b1sl-python 0.3.0__tar.gz → 0.4.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.
- b1sl_python-0.4.0/CLAUDE.md +114 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/PKG-INFO +1 -1
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/pyproject.toml +1 -1
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/__init__.py +19 -1
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/async_client.py +55 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/async_rest_adapter.py +9 -7
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/base_adapter.py +44 -1
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/batch/_recording_adapter.py +15 -12
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/batch/serializer.py +14 -3
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/client.py +56 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/exceptions/__init__.py +6 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/exceptions/exceptions.py +95 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/pagination.py +12 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/async_base.py +67 -39
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/base.py +71 -41
- b1sl_python-0.4.0/src/b1sl/b1sl/resources/crossjoin.py +542 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/odata.py +40 -2
- b1sl_python-0.4.0/src/b1sl/b1sl/resources/sql_queries.py +571 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/rest_adapter.py +9 -6
- b1sl_python-0.4.0/src/b1sl/contrib/mcp/__init__.py +108 -0
- b1sl_python-0.4.0/src/b1sl/contrib/mcp/discovery.py +410 -0
- b1sl_python-0.4.0/src/b1sl/contrib/mcp/formatters.py +182 -0
- b1sl_python-0.4.0/src/b1sl/contrib/mcp/grammar.py +255 -0
- b1sl_python-0.4.0/src/b1sl/contrib/mcp/odata_formatters.py +308 -0
- b1sl_python-0.4.0/src/b1sl/contrib/mcp/odata_grammar.py +316 -0
- b1sl_python-0.4.0/src/b1sl/contrib/mcp/odata_schemas.py +640 -0
- b1sl_python-0.4.0/src/b1sl/contrib/mcp/schemas.py +151 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/fakes/fake_rest_adapter.py +102 -0
- b1sl_python-0.4.0/tests/unit/test_crossjoin.py +572 -0
- b1sl_python-0.4.0/tests/unit/test_mcp_discovery.py +228 -0
- b1sl_python-0.4.0/tests/unit/test_mcp_helpers.py +461 -0
- b1sl_python-0.4.0/tests/unit/test_mcp_odata.py +400 -0
- b1sl_python-0.4.0/tests/unit/test_mcp_odata_formatters.py +282 -0
- b1sl_python-0.4.0/tests/unit/test_mcp_odata_schemas.py +282 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/test_odata_builder.py +65 -0
- b1sl_python-0.4.0/tests/unit/test_sql_queries.py +702 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/.env.example +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/.github/workflows/ci.yml +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/.github/workflows/publish.yml +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/.gitignore +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/LICENSE +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/Makefile +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/README.md +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/ROADMAP.md +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/configs/dev.json +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/configs/qa.json.example +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/adapter.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/adapter_protocol.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/batch/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/batch/changeset.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/batch/client.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/batch/parser.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/batch/results.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/config.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/config_manager.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/contrib/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/contrib/django/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/contrib/django/middleware/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/contrib/django/middleware/base.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/contrib/django/middleware/odata_decode_middleware.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/contrib/django/middleware/odata_transform_url_middleware.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/entities/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/environment.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/fields/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/fields/_generated/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/fields/_generated/complex_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/fields/_generated/entities/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/fields/_generated/entities/businesspartners.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/fields/_generated/entities/finance.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/fields/_generated/entities/general.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/fields/_generated/entities/inventory.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/fields/_generated/entities/production.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/fields/_generated/entities/purchasing.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/fields/_generated/entities/sales.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/fields/base.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/logging_utils.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/_generated/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/_generated/_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/_generated/complex_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/_generated/entities/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/_generated/entities/businesspartners.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/_generated/entities/finance.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/_generated/entities/general.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/_generated/entities/inventory.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/_generated/entities/production.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/_generated/entities/purchasing.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/_generated/entities/sales.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/_generated/enums.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/_generated/resources/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/_overrides/inventory.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/base.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/odata_query_model.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/paginated_result.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/models/result.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/account_category.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/account_category_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/account_segmentation_categories.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/account_segmentations.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/accounts_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/accrual_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/accrual_types_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/activities.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/activities_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/activity_locations.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/activity_recipient_lists.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/activity_recipient_lists_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/activity_statuses.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/activity_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/additional_expenses.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/address_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/alert_managements.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/alternate_cat_num.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/alternative_items_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/approval_requests.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/approval_requests_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/approval_stages.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/approval_stages_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/approval_templates.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/approval_templates_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_capitalization.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_capitalization_credit_memo.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_capitalization_credit_memo_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_capitalization_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_classes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_classes_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_depreciation_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_depreciation_groups_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_groups_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_manual_depreciation.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_manual_depreciation_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_retirement.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_retirement_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_transfer.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/asset_transfer_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/attachments2.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/attribute_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/attribute_groups_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bank_charges_allocation_codes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bank_charges_allocation_codes_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bank_pages.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bank_statements.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bank_statements_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/banks.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bar_codes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bar_codes_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/batch_number_details.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bill_of_exchange_transactions.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bin_location_attributes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bin_location_attributes_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bin_location_fields.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bin_location_fields_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bin_locations.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bin_locations_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/blanket_agreements.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/blanket_agreements_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/boe_document_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/boe_document_types_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/boe_instructions.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/boe_instructions_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/boe_lines_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/boe_portfolios.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/boe_portfolios_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bp_fiscal_registry_id.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bp_opening_balance_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/bp_priorities.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/branches.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/branches_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/brazil_beverage_indexers.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/brazil_beverage_indexers_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/brazil_fuel_indexers.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/brazil_fuel_indexers_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/brazil_multi_indexers.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/brazil_numeric_indexers.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/brazil_string_indexers.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/budget_distributions.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/budget_scenarios.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/budgets.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/business_partner_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/business_partner_properties.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/business_partner_properties_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/business_partners.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/business_partners_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/business_places.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/campaign_response_type.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/campaign_response_type_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/campaigns.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/campaigns_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/cash_discounts.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/cash_discounts_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/cash_flow_line_items.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/cash_flow_line_items_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/certificate_series.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/certificate_series_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/change_logs_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/chart_of_accounts.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/check_lines_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/checksfor_payment.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/choose_from_list.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/closing_date_procedure.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/cockpits.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/cockpits_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/commission_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/company_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/contacts.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/contract_templates.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/correction_invoice.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/correction_invoice_reversal.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/correction_invoice_reversal_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/correction_invoice_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/correction_purchase_invoice.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/correction_purchase_invoice_reversal.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/correction_purchase_invoice_reversal_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/correction_purchase_invoice_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/cost_center_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/cost_center_types_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/cost_element_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/cost_elements.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/counties.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/counties_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/countries.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/countries_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/credit_card_payments.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/credit_cards.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/credit_lines_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/credit_notes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/credit_notes_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/credit_payment_methods.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/currencies.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/customer_equipment_cards.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/customs_declaration.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/customs_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/cycle_count_determinations.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/cycle_count_determinations_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/dashboard_packages_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/deductible_tax_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/deductible_taxes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/deduction_tax_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/deduction_tax_hierarchies.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/deduction_tax_sub_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/deduction_tax_sub_groups_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/delivery_notes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/delivery_notes_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/departments.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/departments_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/deposits.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/deposits_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/depreciation_areas.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/depreciation_areas_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/depreciation_type_pools.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/depreciation_type_pools_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/depreciation_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/depreciation_types_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/determination_criterias.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/determination_criterias_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/dimensions.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/dimensions_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/distribution_rules.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/distribution_rules_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/dnf_code_setup.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/dnf_code_setup_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/down_payments.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/down_payments_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/drafts.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/drafts_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/dunning_letters.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/dunning_terms.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/dunning_terms_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/dynamic_system_strings.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/electronic_communication_action_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/electronic_communication_actions_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/electronic_file_formats.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/electronic_file_formats_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/email_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/email_groups_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/employee_id_type.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/employee_id_type_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/employee_position.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/employee_position_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/employee_roles_setup.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/employee_roles_setup_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/employee_status.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/employee_status_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/employee_transfers.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/employee_transfers_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/employees_info.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/employment_category_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/employment_categorys.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/enhanced_discount_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/enhanced_discount_groups_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/exceptional_event_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/exceptional_events.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/extended_translations.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/extended_translations_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/external_calls_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/external_reconciliations_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/fa_account_determinations.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/fa_account_determinations_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/factoring_indicators.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/financial_years.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/financial_years_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/fiscal_printer.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/fiscal_printer_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/fixed_asset_items_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/form_preferences.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/formatted_searches.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/forms1099.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/gl_account_advanced_rules.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/gl_account_advanced_rules_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/goods_return_request.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/goods_return_request_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/gov_pay_codes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/gov_pay_codes_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/gt_is_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/holidays.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/house_bank_accounts.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/incoming_payments.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/india_hsn.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/india_hsn_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/industries.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/integration_packages_configure.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/integration_packages_configure_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/internal_reconciliations.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/internal_reconciliations_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/intrastat_configuration.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/intrastat_configuration_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/inventory_countings.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/inventory_countings_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/inventory_cycles.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/inventory_gen_entries.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/inventory_gen_entry_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/inventory_gen_exit_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/inventory_gen_exits.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/inventory_opening_balances.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/inventory_opening_balances_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/inventory_postings.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/inventory_postings_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/inventory_transfer_requests.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/inventory_transfer_requests_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/invoices.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/invoices_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/item_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/item_properties.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/items.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/journal_entries.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/journal_entry_document_type_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/journal_entry_document_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/journal_vouchers_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/knowledge_base_solutions.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/kp_is.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/kp_is_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/landed_costs.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/landed_costs_codes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/landed_costs_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/legal_data.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/length_measures.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/license_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/local_era.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/manufacturers.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/material_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/material_groups_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/material_revaluation.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/material_revaluation_fifo_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/material_revaluation_snb_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/messages.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/messages_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/mobile_add_on_setting.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/mobile_add_on_setting_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/mobile_app_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/multi_language_translations.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/nature_of_assessees.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/nature_of_assessees_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/ncm_codes_setup.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/ncm_codes_setup_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/nf_models.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/nf_models_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/nf_tax_categories.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/nf_tax_categories_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/nota_fiscal_cfop.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/nota_fiscal_cst.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/nota_fiscal_usage.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/occurrence_codes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/occurrence_codes_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/orders.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/orders_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/packages_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/partners_setups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/partners_setups_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/payment_blocks.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/payment_blocks_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/payment_calculation_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/payment_drafts.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/payment_reason_code_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/payment_reason_codes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/payment_run_export.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/payment_terms_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/payment_terms_types_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/pick_lists.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/pick_lists_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/pos_daily_summary.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/predefined_texts.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/predefined_texts_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/price_lists.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/product_trees.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/production_orders.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/profit_centers.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/profit_centers_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/project_management_configuration_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/project_management_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/project_management_time_sheet.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/project_managements.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/projects.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/projects_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_credit_notes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_credit_notes_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_delivery_notes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_delivery_notes_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_down_payments.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_down_payments_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_invoices.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_invoices_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_orders.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_orders_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_quotations.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_quotations_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_request_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_requests.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_returns.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_returns_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/purchase_tax_invoices.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/qr_code_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/query_auth_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/query_categories.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/query_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/queue.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/quotations.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/quotations_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/recurring_transaction_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/relationships.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/report_filter.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/report_filter_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/report_layouts_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/report_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/report_types_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/resource_capacities.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/resource_capacities_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/resource_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/resource_groups_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/resource_properties.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/resource_properties_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/resources.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/resources_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/retorno_codes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/retorno_codes_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/return_request.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/return_request_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/returns.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/returns_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/route_stages.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/route_stages_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_forecast.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_opportunities.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_opportunity_competitors_setup.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_opportunity_competitors_setup_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_opportunity_interests_setup.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_opportunity_interests_setup_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_opportunity_reasons_setup.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_opportunity_reasons_setup_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_opportunity_sources_setup.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_opportunity_sources_setup_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_persons.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_stages.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_tax_authorities.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_tax_authorities_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_tax_codes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sales_tax_invoices.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sbo_bob_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sections.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/sections_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/self_credit_memo_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/self_credit_memos.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/self_invoice_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/self_invoices.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/serial_number_details.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/series_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_call_origins.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_call_origins_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_call_problem_sub_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_call_problem_sub_types_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_call_problem_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_call_problem_types_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_call_solution_status.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_call_solution_status_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_call_status.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_call_status_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_call_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_call_types_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_calls.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_contracts.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_groups_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/service_tax_posting_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/shipping_types.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/short_link_mappings_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/special_prices.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/states.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/states_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/stock_takings.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/stock_transfer_draft_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/stock_transfer_drafts.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/stock_transfer_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/stock_transfers.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/target_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/target_groups_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/tax_code_determinations.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/tax_code_determinations_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/tax_code_determinations_tcd.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/tax_code_determinations_tcd_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/tax_invoice_report.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/tax_web_sites.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/tax_web_sites_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/teams.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/termination_reason.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/termination_reason_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/territories.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/tracking_notes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/tracking_notes_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/transaction_codes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/transaction_codes_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/transportation_document.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/tsr_exceptional_event_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/tsr_exceptional_events.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/unit_of_measurement_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/unit_of_measurement_groups_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/unit_of_measurements.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/unit_of_measurements_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/user_default_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/user_fields_md.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/user_keys_md.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/user_languages.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/user_menu_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/user_objects_md.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/user_permission_tree.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/user_queries.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/user_tables_md.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/users.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/users_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/value_mapping.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/value_mapping_communication.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/value_mapping_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/vat_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/vendor_payments.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/w_tax_type_code_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/w_tax_type_codes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/warehouse_locations.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/warehouse_sublevel_codes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/warehouse_sublevel_codes_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/warehouses.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_bookmark_tile_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_bookmark_tiles.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_dashboard_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_dashboards.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_form_setting_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_form_settings.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_launchpad_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_launchpads.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_listview_filter_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_listview_filters.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_notification_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_notifications.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_preference_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_preferences.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_recent_activities.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_recent_activity_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_variant_group_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_variant_groups.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_variant_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/web_client_variants.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/weight_measures.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/withholding_tax_codes.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/witholding_tax_definition.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/wizard_payment_methods.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/_generated/workflow_task_service.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/resources/udo.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/schemas/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/schemas/udf.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/testing.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/tests/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/tests/test_01_settings.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/tests/test_02_rest_adapter.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/tests/test_03_items_endpoint.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/tests/test_04_serialnumberdetails_endpoint.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/tests/test_observability.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/b1sl/tests/test_utils.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/contrib/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/contrib/django/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/contrib/django/base.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/contrib/django/odata_decode_middleware.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/contrib/django/odata_transform_url_middleware.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/py.typed +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/saphdb/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/saphdb/adapter.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/saphdb/client.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/saphdb/config.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/saphdb/endpoints/serialnumberdetailodbc.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/saphdb/exceptions/exceptions.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/saphdb/main.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/saphdb/models/result.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/saphdb/models/serial.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/saphdb/odbc_adapter.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/saphdb/tests/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/saphdb/tests/test_01_settings.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/saphdb/tests/test_02_odbc_adapter.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/src/b1sl/saphdb/tests/test_04_serialnumberdetails_endpoint.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/conftest.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/fakes/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/fixtures/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/fixtures/mock_responses/items_list.json +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/fixtures/mock_responses/items_single.json +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/fixtures/test_data.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/integration/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/integration/cassettes/test_items_real/test_get_item_real.yaml +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/integration/cassettes/test_items_real/test_list_items_real.yaml +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/integration/conftest.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/integration/test_items_real.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/test_async_adapter.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/test_b1sl_adapter.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/test_middleware.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/test_saphdb_adapter.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/__init__.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/mocks/items_list.json +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/mocks/items_single.json +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/test_advanced_features.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/test_batch.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/test_bool_serialisation.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/test_dry_run.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/test_items_mock.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/test_model_resolution.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/test_pagination.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/test_rest_adapter.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/test_schema_header.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/test_service_calls.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/test_stream_execution.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/tests/unit/test_udfs.py +0 -0
- {b1sl_python-0.3.0 → b1sl_python-0.4.0}/uv.lock +0 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project
|
|
6
|
+
|
|
7
|
+
`b1sl-python` — an async-first, metadata-driven Python SDK for the SAP Business One Service Layer (OData v4). Published to PyPI. Optional `saphdb` subpackage wraps SAP HANA via `hdbcli`.
|
|
8
|
+
|
|
9
|
+
## Tooling and commands
|
|
10
|
+
|
|
11
|
+
- **Package manager: `uv` exclusively.** `uv sync` (or `uv sync --all-extras --dev`) for installs. The venv lives at `.venv/`.
|
|
12
|
+
- **Python: 3.11–3.12** (`requires-python = ">=3.11,<3.13"`).
|
|
13
|
+
- Common targets (see `Makefile`):
|
|
14
|
+
- `make test` — unit tests only, no network (`pytest -m "not (integration or vcr)"`).
|
|
15
|
+
- `make test-vcr` — replay recorded cassettes offline (`--record-mode=none`). Requires the `vcr` marker.
|
|
16
|
+
- `make test-record` — re-record cassettes against a real SAP server. Requires `.env`.
|
|
17
|
+
- `make test-demo` — live integration tests, `APP_ENV=demo`, requires `.env`.
|
|
18
|
+
- `make test-ci` — full CI suite with coverage XML.
|
|
19
|
+
- `make lint` — `ruff check .` + `mypy .` (CI parity).
|
|
20
|
+
- **Single test**: `PYTHONPATH=src:. .venv/bin/pytest tests/unit/test_odata_builder.py::test_name -xvs`. The `PYTHONPATH=src:.` prefix matters — the package lives at `src/b1sl/` and tests import via `b1sl.b1sl.…`.
|
|
21
|
+
- CI (`.github/workflows/ci.yml`) runs only `uv run ruff check .` + `uv run pytest tests/unit/`. `mypy` is enforced locally via `make lint`, not in CI.
|
|
22
|
+
- Release: `make release v=X.Y.Z` commits, tags, pushes; `publish.yml` then publishes to PyPI on tag.
|
|
23
|
+
|
|
24
|
+
## Architecture
|
|
25
|
+
|
|
26
|
+
### Three-layer model code: generated / overrides / entities
|
|
27
|
+
|
|
28
|
+
The SDK is **metadata-driven**. Most of `src/b1sl/b1sl/models/` and `src/b1sl/b1sl/resources/` is autogenerated from SAP's OData `$metadata` XML, service document JSON, and API reference HTML (sources versioned under `metadata/<version>/`).
|
|
29
|
+
|
|
30
|
+
- `models/_generated/`, `resources/_generated/` — **NEVER edit**. Wiped on every regeneration. Any structural fix belongs in the generator at `scripts/b1sl_metadata_generator/` (run via `./scripts/generate_models.sh <version>`).
|
|
31
|
+
- `models/_overrides/` — hand-written extensions, calculated properties, `model_rebuild()` calls, metadata quirk fixes.
|
|
32
|
+
- `entities/__init__.py` — the public facade. Blends generated + overridden models. **All public consumption goes through `from b1sl.b1sl import entities as en`**, never from `_generated/` directly.
|
|
33
|
+
|
|
34
|
+
Production metadata should not be committed: place it as `metadata/<version>/metadata_document.real.xml` / `service_document.real.json`. The generator prioritizes `.real.*` over the public files; `.real.*` is gitignored.
|
|
35
|
+
|
|
36
|
+
### `B1Model` base class
|
|
37
|
+
|
|
38
|
+
Every entity inherits from `B1Model` (`models/base.py`), which provides:
|
|
39
|
+
- Boolean coercion (SAP `"tYES"`/`"tNO"` ↔ Python `bool`).
|
|
40
|
+
- Date handling (`/Date(ms)/` ↔ `date`).
|
|
41
|
+
- `.to_api_payload()` uses `exclude_unset=True` — this is the foundation of the **Surgical Delta** pattern. PATCH payloads must contain only the fields the caller explicitly set; never `GET` an entity and resend it.
|
|
42
|
+
- `.udfs` proxy: mapping-like accessor for User-Defined Fields. **Enforces the `U_` prefix** to prevent overwriting SAP core fields.
|
|
43
|
+
|
|
44
|
+
### Elite vs Generic resource access
|
|
45
|
+
|
|
46
|
+
The client exposes ~16 "Elite" aliases as direct properties (`client.items`, `client.business_partners`, `client.orders`, …) — these are the entities with verified ETag concurrency support. Everything else (~1000 endpoints) requires explicit binding:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
res = client.get_resource(en.User, "Users")
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The explicit `get_resource` call is a deliberate safety signal: ETag protection is **not guaranteed** for these endpoints. When adding a new alias, only promote to Elite if SAP supports ETag for that endpoint.
|
|
53
|
+
|
|
54
|
+
### Async/Sync symmetry
|
|
55
|
+
|
|
56
|
+
`B1Client` / `AsyncB1Client`, `RestAdapter` / `AsyncRestAdapter`, `GenericResource` / `AsyncGenericResource`, `QueryBuilder` / `AsyncQueryBuilder` — every sync class has an async counterpart. Both surfaces must support the same parameters and methods. When changing one, change the other.
|
|
57
|
+
|
|
58
|
+
### ETag concurrency — proactive invalidation
|
|
59
|
+
|
|
60
|
+
SAP returns `204 No Content` on PATCH/DELETE without a fresh `ETag` header. The adapter's contract is:
|
|
61
|
+
|
|
62
|
+
1. GET caches `ETag`.
|
|
63
|
+
2. PATCH/DELETE sends it as `If-Match`.
|
|
64
|
+
3. **On success, the adapter immediately clears the cached ETag** (proactive invalidation). Skipping this step makes a subsequent DELETE-after-UPDATE use a stale ETag and silently break under load.
|
|
65
|
+
4. 412 → `SAPConcurrencyError`.
|
|
66
|
+
|
|
67
|
+
Adapters map HTTP status to semantic exceptions via a standardized dict: 400 → `B1ValidationError`, 401 → `B1AuthError`, 404 → `B1NotFoundError`, 412 → `SAPConcurrencyError`, else `B1Exception`.
|
|
68
|
+
|
|
69
|
+
### Batch / changesets
|
|
70
|
+
|
|
71
|
+
`src/b1sl/b1sl/batch/` implements `$batch` via a `RecordingAdapter` proxy pattern: `batch.items.create(...)` reuses the exact same resource API but enqueues into `_pending` instead of executing.
|
|
72
|
+
|
|
73
|
+
- `changeset()` blocks → atomic (all-or-nothing).
|
|
74
|
+
- Top-level batch ops → independent (partial success allowed).
|
|
75
|
+
- **`batch.execute()` must NOT raise on individual op failures.** Callers inspect `results.all_ok` / `results.failed`. Each result preserves `r.index` for traceability.
|
|
76
|
+
|
|
77
|
+
### Pagination
|
|
78
|
+
|
|
79
|
+
`.execute()` returns one page. `.stream()` follows `odata.nextLink` via generators (async generators for the async client). `.top(N)` is a global hard cap; `page_size` and `max_pages` are independent safety knobs. Filters survive page boundaries.
|
|
80
|
+
|
|
81
|
+
### Configuration
|
|
82
|
+
|
|
83
|
+
`B1Environment.load()` loads with precedence: env vars > `.env` > `configs/<env>.json`. JSON profiles hold non-sensitive test data only — credentials must come from env/`.env`. `B1SL_ENV` controls `dev` (human logs) vs `test` vs `prod` (structured JSON logs). `B1SL_DRY_RUN=1` (or `with b1.dry_run():` — `ContextVar`-scoped, task-safe) intercepts all writes and returns a fake 204.
|
|
84
|
+
|
|
85
|
+
## Rules and gotchas
|
|
86
|
+
|
|
87
|
+
- **English only** in code, comments, commits, docs.
|
|
88
|
+
- **Never `pip install`** — use `uv add` / `uv sync`.
|
|
89
|
+
- **Never edit `_generated/`**. Fix the generator or add a `_overrides/` file.
|
|
90
|
+
- **Run `make lint` before proposing changes** — it covers the whole repo (CI only runs ruff, so mypy regressions slip past unless you run it locally).
|
|
91
|
+
- **Surgical deltas only**: write `client.items.update("A001", en.Item(item_name="New"))`, never round-trip a fetched object.
|
|
92
|
+
- **Don't promote endpoints to Elite without verifying ETag support** — Elite aliases imply concurrency safety.
|
|
93
|
+
- **VCR cassette hygiene**: `tests/conftest.py` redacts hosts, sessions, credentials, and OData context URLs. Before pushing recorded cassettes, sanity-check with `grep -r "B1SESSION" tests/integration/cassettes/`.
|
|
94
|
+
- **`hdbcli` is mocked at top-level in `tests/conftest.py`** so HANA tests don't require the SAP driver. Don't import `hdbcli` outside the `saphdb` subpackage.
|
|
95
|
+
- Pytest markers: `integration` (live SAP), `vcr` (cassette playback). Default `make test` excludes both.
|
|
96
|
+
|
|
97
|
+
## Where things live
|
|
98
|
+
|
|
99
|
+
- `src/b1sl/b1sl/` — Service Layer SDK (the main product).
|
|
100
|
+
- `src/b1sl/saphdb/` — optional HANA direct-SQL adapter (gated by `hana` extra).
|
|
101
|
+
- `src/b1sl/contrib/` — framework integrations (Django, etc.).
|
|
102
|
+
- `src/b1sl/contrib/mcp/` — MCP helper toolkit (framework-agnostic, no MCP SDK import).
|
|
103
|
+
Seven modules: `discovery.py` (Elite resource catalog + field introspection),
|
|
104
|
+
`grammar.py` / `odata_grammar.py` (SQL and OData grammar constraints + system prompts),
|
|
105
|
+
`schemas.py` / `odata_schemas.py` (tool-definition builders for SQL and OData CRUD),
|
|
106
|
+
`formatters.py` / `odata_formatters.py` (result/error formatters).
|
|
107
|
+
Guide: `docs/16-mcp-helpers.md`. Example: `examples/23_mcp_odata_server.py`.
|
|
108
|
+
- `scripts/b1sl_metadata_generator/` — the generator engine.
|
|
109
|
+
- `scripts/generate_models.sh <version>` — regen entry point.
|
|
110
|
+
- `docs/` — long-form architecture/API guides (excluded from the wheel).
|
|
111
|
+
- `docs/reference/sl/` — verbatim SAP Service Layer reference extracts (e.g. `sql-queries.md`). Read these before guessing endpoint semantics.
|
|
112
|
+
- `examples/`, `skills/`, `agents.md`, `metadata/` — also excluded from the wheel (see `pyproject.toml [tool.hatch.build]`).
|
|
113
|
+
- `src/b1sl/b1sl/resources/sql_queries.py` — specialized resource with bounded function (`/List`) support; the reference implementation for resources that go beyond generic CRUD.
|
|
114
|
+
- `src/b1sl/b1sl/pagination.py` — contains `extract_next_link()` which handles both OData v3 (`odata.nextLink`) and v4 (`@odata.nextLink`) response formats.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: b1sl-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: A framework-agnostic Python SDK for SAP Business One Service Layer and SAP HANA. (Unofficial)
|
|
5
5
|
Project-URL: Homepage, https://github.com/operator-ita/b1sl-python
|
|
6
6
|
Project-URL: Repository, https://github.com/operator-ita/b1sl-python
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "b1sl-python"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.4.0"
|
|
8
8
|
description = "A framework-agnostic Python SDK for SAP Business One Service Layer and SAP HANA. (Unofficial)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11,<3.13"
|
|
@@ -13,9 +13,20 @@ from b1sl.b1sl.client import B1Client
|
|
|
13
13
|
from b1sl.b1sl.config import B1Config
|
|
14
14
|
from b1sl.b1sl.config_manager import B1Environment
|
|
15
15
|
from b1sl.b1sl.environment import B1Env
|
|
16
|
-
from b1sl.b1sl.exceptions.exceptions import
|
|
16
|
+
from b1sl.b1sl.exceptions.exceptions import (
|
|
17
|
+
B1SqlNotAllowedError,
|
|
18
|
+
B1SqlParamError,
|
|
19
|
+
B1SqlSyntaxError,
|
|
20
|
+
SAPConcurrencyError,
|
|
21
|
+
)
|
|
17
22
|
from b1sl.b1sl.resources.async_base import AsyncGenericResource
|
|
18
23
|
from b1sl.b1sl.resources.base import GenericResource, ODataQuery
|
|
24
|
+
from b1sl.b1sl.resources.sql_queries import (
|
|
25
|
+
DEFAULT_ACCESSIBLE_TABLES,
|
|
26
|
+
KNOWN_INACCESSIBLE_PATTERNS,
|
|
27
|
+
SQLQueryInfo,
|
|
28
|
+
SQLRunResult,
|
|
29
|
+
)
|
|
19
30
|
from b1sl.b1sl.rest_adapter import RestAdapter
|
|
20
31
|
|
|
21
32
|
try:
|
|
@@ -42,9 +53,16 @@ __all__ = [
|
|
|
42
53
|
"RestAdapter",
|
|
43
54
|
"B1Env",
|
|
44
55
|
"SAPConcurrencyError",
|
|
56
|
+
"B1SqlSyntaxError",
|
|
57
|
+
"B1SqlNotAllowedError",
|
|
58
|
+
"B1SqlParamError",
|
|
45
59
|
"AsyncGenericResource",
|
|
46
60
|
"GenericResource",
|
|
47
61
|
"ODataQuery",
|
|
62
|
+
"DEFAULT_ACCESSIBLE_TABLES",
|
|
63
|
+
"KNOWN_INACCESSIBLE_PATTERNS",
|
|
64
|
+
"SQLQueryInfo",
|
|
65
|
+
"SQLRunResult",
|
|
48
66
|
"entities",
|
|
49
67
|
"fields",
|
|
50
68
|
"HookContext",
|
|
@@ -17,6 +17,11 @@ if TYPE_CHECKING:
|
|
|
17
17
|
from b1sl.b1sl.models._generated.entities.inventory import Item
|
|
18
18
|
from b1sl.b1sl.models.base import B1Model
|
|
19
19
|
from b1sl.b1sl.resources.async_base import AsyncGenericResource
|
|
20
|
+
from b1sl.b1sl.resources.crossjoin import (
|
|
21
|
+
AsyncCrossJoinQueryBuilder,
|
|
22
|
+
AsyncQueryServiceBuilder,
|
|
23
|
+
)
|
|
24
|
+
from b1sl.b1sl.resources.sql_queries import AsyncSQLQueriesResource
|
|
20
25
|
from b1sl.b1sl.resources.udo import AsyncUDOResource
|
|
21
26
|
|
|
22
27
|
|
|
@@ -351,6 +356,15 @@ class AsyncB1Client:
|
|
|
351
356
|
from b1sl.b1sl.models._generated.entities.general import Document
|
|
352
357
|
return self.get_resource(Document, "CorrectionPurchaseInvoiceReversal")
|
|
353
358
|
|
|
359
|
+
# --- SQL Queries ---
|
|
360
|
+
|
|
361
|
+
@property
|
|
362
|
+
def sql_queries(self) -> "AsyncSQLQueriesResource":
|
|
363
|
+
"""Access the 'SQLQueries' endpoint (supports ETags, run() / run_stream())."""
|
|
364
|
+
from b1sl.b1sl.resources.sql_queries import AsyncSQLQueriesResource
|
|
365
|
+
resource = AsyncSQLQueriesResource(self._adapter)
|
|
366
|
+
return resource
|
|
367
|
+
|
|
354
368
|
def udo(self, table_name: str) -> "AsyncUDOResource":
|
|
355
369
|
"""
|
|
356
370
|
Asynchronously access a User Defined Object (UDO) or User Table.
|
|
@@ -360,4 +374,45 @@ class AsyncB1Client:
|
|
|
360
374
|
from b1sl.b1sl.resources.udo import AsyncUDOResource
|
|
361
375
|
return AsyncUDOResource(adapter=self._adapter, table_name=table_name)
|
|
362
376
|
|
|
377
|
+
def crossjoin(self, *entities: str) -> "AsyncCrossJoinQueryBuilder":
|
|
378
|
+
"""Build an async ``$crossjoin`` query (SAP HANA only, B1 9.2 patch 07+).
|
|
379
|
+
|
|
380
|
+
At least 2 entity names are required. A bare crossjoin without
|
|
381
|
+
``$expand`` or ``$apply`` will raise ``ValueError`` before the request.
|
|
382
|
+
|
|
383
|
+
Example::
|
|
384
|
+
|
|
385
|
+
rows = await (
|
|
386
|
+
client.crossjoin("Orders", "BusinessPartners")
|
|
387
|
+
.expand({"Orders": ["DocEntry", "DocNum"], "BusinessPartners": ["CardCode"]})
|
|
388
|
+
.filter("Orders/CardCode eq BusinessPartners/CardCode")
|
|
389
|
+
.execute()
|
|
390
|
+
)
|
|
391
|
+
"""
|
|
392
|
+
from b1sl.b1sl.resources.crossjoin import AsyncCrossJoinQueryBuilder
|
|
393
|
+
|
|
394
|
+
return AsyncCrossJoinQueryBuilder(self._adapter, *entities)
|
|
395
|
+
|
|
396
|
+
def query_service(self, query_path: str) -> "AsyncQueryServiceBuilder":
|
|
397
|
+
"""Async ``QueryService_PostQuery`` row-level filter (SAP HANA only, B1 9.2 PL11+).
|
|
398
|
+
|
|
399
|
+
Example::
|
|
400
|
+
|
|
401
|
+
rows = await (
|
|
402
|
+
client.query_service("$crossjoin(Orders,Orders/DocumentLines)")
|
|
403
|
+
.expand({
|
|
404
|
+
"Orders": ["DocEntry", "DocNum"],
|
|
405
|
+
"Orders/DocumentLines": ["ItemCode", "LineNum"],
|
|
406
|
+
})
|
|
407
|
+
.filter(
|
|
408
|
+
"Orders/DocEntry eq Orders/DocumentLines/DocEntry"
|
|
409
|
+
" and Orders/DocumentLines/ItemCode eq 'WIDGET'"
|
|
410
|
+
)
|
|
411
|
+
.execute()
|
|
412
|
+
)
|
|
413
|
+
"""
|
|
414
|
+
from b1sl.b1sl.resources.crossjoin import AsyncQueryServiceBuilder
|
|
415
|
+
|
|
416
|
+
return AsyncQueryServiceBuilder(self._adapter, query_path)
|
|
417
|
+
|
|
363
418
|
|
|
@@ -16,6 +16,7 @@ from b1sl.b1sl.exceptions.exceptions import (
|
|
|
16
16
|
B1ValidationError,
|
|
17
17
|
)
|
|
18
18
|
from b1sl.b1sl.models.result import Result
|
|
19
|
+
from b1sl.b1sl.pagination import extract_next_link
|
|
19
20
|
|
|
20
21
|
_HTTP_STATUS_TO_EXC: dict[int, type] = {
|
|
21
22
|
400: B1ValidationError,
|
|
@@ -278,7 +279,10 @@ class AsyncRestAdapter(BaseRestAdapter):
|
|
|
278
279
|
self._raise_if_concurrency_error(
|
|
279
280
|
e.response.status_code, sap_code, sap_msg, endpoint_path, body
|
|
280
281
|
)
|
|
281
|
-
|
|
282
|
+
self._raise_if_sql_error(
|
|
283
|
+
e.response.status_code, sap_code, sap_msg, body
|
|
284
|
+
)
|
|
285
|
+
|
|
282
286
|
# Use specialized exception based on status code if available
|
|
283
287
|
exc_cls = _HTTP_STATUS_TO_EXC.get(e.response.status_code, B1Exception)
|
|
284
288
|
raise exc_cls(f"SAP Error {sap_code}: {sap_msg}", details=body) from e
|
|
@@ -335,13 +339,11 @@ class AsyncRestAdapter(BaseRestAdapter):
|
|
|
335
339
|
status_code=response.status_code,
|
|
336
340
|
message=response.reason_phrase,
|
|
337
341
|
data=data_out,
|
|
338
|
-
next_link=data_out
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
next_params=self._get_ep_params(data_out.get("odata.nextLink"))
|
|
342
|
-
if isinstance(data_out, dict) and data_out.get("odata.nextLink")
|
|
342
|
+
next_link=extract_next_link(data_out) if isinstance(data_out, dict) else None,
|
|
343
|
+
next_params=self._get_ep_params(extract_next_link(data_out))
|
|
344
|
+
if isinstance(data_out, dict) and extract_next_link(data_out)
|
|
343
345
|
else None,
|
|
344
|
-
metadata=data_out.get("odata.metadata")
|
|
346
|
+
metadata=(data_out.get("@odata.context") or data_out.get("odata.metadata"))
|
|
345
347
|
if isinstance(data_out, dict)
|
|
346
348
|
else None,
|
|
347
349
|
)
|
|
@@ -16,7 +16,12 @@ from datetime import datetime
|
|
|
16
16
|
from typing import Any, Callable, Dict, List, Optional
|
|
17
17
|
from urllib.parse import parse_qs, urlencode, urlparse
|
|
18
18
|
|
|
19
|
-
from b1sl.b1sl.exceptions.exceptions import
|
|
19
|
+
from b1sl.b1sl.exceptions.exceptions import (
|
|
20
|
+
B1SqlNotAllowedError,
|
|
21
|
+
B1SqlParamError,
|
|
22
|
+
B1SqlSyntaxError,
|
|
23
|
+
SAPConcurrencyError,
|
|
24
|
+
)
|
|
20
25
|
|
|
21
26
|
|
|
22
27
|
@dataclass
|
|
@@ -403,6 +408,44 @@ class BaseRestAdapter:
|
|
|
403
408
|
details=response_body,
|
|
404
409
|
)
|
|
405
410
|
|
|
411
|
+
@staticmethod
|
|
412
|
+
def _raise_if_sql_error(
|
|
413
|
+
status_code: int,
|
|
414
|
+
sap_code: str,
|
|
415
|
+
sap_message: str,
|
|
416
|
+
response_body: dict | None,
|
|
417
|
+
) -> None:
|
|
418
|
+
"""Convert SAP 400 responses with SQL-specific codes into typed exceptions.
|
|
419
|
+
|
|
420
|
+
SAP error codes handled:
|
|
421
|
+
- ``"702"`` / ``"703"`` → ``B1SqlNotAllowedError`` (table or column blocked)
|
|
422
|
+
- ``"704"`` → ``B1SqlParamError`` (missing, extra, or mis-typed parameter)
|
|
423
|
+
|
|
424
|
+
Called from ``_do`` in both sync and async adapters, right before the
|
|
425
|
+
generic ``B1ValidationError`` fallback, so callers can catch the
|
|
426
|
+
granular subclass or the broader ``B1ValidationError``.
|
|
427
|
+
|
|
428
|
+
Note: SAP returns ``code`` as a JSON string (e.g. ``"702"``), not an int.
|
|
429
|
+
"""
|
|
430
|
+
if status_code != 400:
|
|
431
|
+
return
|
|
432
|
+
if sap_code == B1SqlSyntaxError.SAP_ERROR_CODE:
|
|
433
|
+
raise B1SqlSyntaxError(
|
|
434
|
+
f"SAP SQL syntax error: {sap_message}",
|
|
435
|
+
details=response_body,
|
|
436
|
+
)
|
|
437
|
+
if sap_code in ("702", "703"):
|
|
438
|
+
raise B1SqlNotAllowedError(
|
|
439
|
+
f"SAP SQL allowlist violation [{sap_code}]: {sap_message}",
|
|
440
|
+
sap_code=sap_code,
|
|
441
|
+
details=response_body,
|
|
442
|
+
)
|
|
443
|
+
if sap_code == B1SqlParamError.SAP_ERROR_CODE:
|
|
444
|
+
raise B1SqlParamError(
|
|
445
|
+
f"SAP SQL parameter error: {sap_message}",
|
|
446
|
+
details=response_body,
|
|
447
|
+
)
|
|
448
|
+
|
|
406
449
|
def _redact_data(self, data: dict | None) -> dict:
|
|
407
450
|
"""Mask sensitive information in data dictionaries before logging."""
|
|
408
451
|
return {k: "***" if k == "Password" else v for k, v in (data or {}).items()}
|
|
@@ -18,6 +18,7 @@ class PendingRequest:
|
|
|
18
18
|
endpoint: str
|
|
19
19
|
data: dict | None = None
|
|
20
20
|
ep_params: dict | None = None
|
|
21
|
+
headers: dict | None = None
|
|
21
22
|
model_type: Type[B1Model] | None = None
|
|
22
23
|
changeset_id: str | None = None
|
|
23
24
|
content_id: str = field(default_factory=lambda: str(uuid.uuid4()))
|
|
@@ -31,7 +32,8 @@ class _RecordingAdapter:
|
|
|
31
32
|
self._batch = batch_client
|
|
32
33
|
self._current_model: Type[B1Model] | None = None
|
|
33
34
|
|
|
34
|
-
def _record(self, method: str, endpoint: str, ep_params: dict | None = None,
|
|
35
|
+
def _record(self, method: str, endpoint: str, ep_params: dict | None = None,
|
|
36
|
+
data: dict | None = None, headers: dict | None = None):
|
|
35
37
|
"""Captures the request and adds it to the client's queue."""
|
|
36
38
|
if method == "GET" and self._batch.active_changeset_id:
|
|
37
39
|
raise ValueError("OData Batch Error: GET operations are not allowed within a ChangeSet.")
|
|
@@ -41,27 +43,28 @@ class _RecordingAdapter:
|
|
|
41
43
|
endpoint=endpoint,
|
|
42
44
|
ep_params=ep_params,
|
|
43
45
|
data=data,
|
|
46
|
+
headers=headers,
|
|
44
47
|
model_type=self._current_model,
|
|
45
48
|
changeset_id=self._batch.active_changeset_id
|
|
46
49
|
)
|
|
47
50
|
self._batch._pending.append(req)
|
|
48
|
-
|
|
51
|
+
|
|
49
52
|
# Return a simulated Result so Pydantic doesn't crash
|
|
50
53
|
return Result(status_code=202, data={})
|
|
51
54
|
|
|
52
55
|
# Asynchronous implementation for AsyncGenericResource
|
|
53
|
-
async def get(self, endpoint, ep_params=None, data=None):
|
|
54
|
-
return self._record("GET", endpoint, ep_params, data)
|
|
56
|
+
async def get(self, endpoint, ep_params=None, data=None, headers=None):
|
|
57
|
+
return self._record("GET", endpoint, ep_params, data, headers)
|
|
55
58
|
|
|
56
|
-
async def post(self, endpoint, ep_params=None, data=None):
|
|
57
|
-
return self._record("POST", endpoint, ep_params, data)
|
|
59
|
+
async def post(self, endpoint, ep_params=None, data=None, headers=None):
|
|
60
|
+
return self._record("POST", endpoint, ep_params, data, headers)
|
|
58
61
|
|
|
59
|
-
async def patch(self, endpoint, ep_params=None, data=None):
|
|
60
|
-
return self._record("PATCH", endpoint, ep_params, data)
|
|
62
|
+
async def patch(self, endpoint, ep_params=None, data=None, headers=None):
|
|
63
|
+
return self._record("PATCH", endpoint, ep_params, data, headers)
|
|
61
64
|
|
|
62
|
-
async def delete(self, endpoint, ep_params=None, data=None):
|
|
63
|
-
return self._record("DELETE", endpoint, ep_params, data)
|
|
65
|
+
async def delete(self, endpoint, ep_params=None, data=None, headers=None):
|
|
66
|
+
return self._record("DELETE", endpoint, ep_params, data, headers)
|
|
64
67
|
|
|
65
68
|
# Synchronous implementation for GenericResource (compatibility)
|
|
66
|
-
def get_sync(self, endpoint, ep_params=None, data=None):
|
|
67
|
-
return self._record("GET", endpoint, ep_params, data)
|
|
69
|
+
def get_sync(self, endpoint, ep_params=None, data=None, headers=None):
|
|
70
|
+
return self._record("GET", endpoint, ep_params, data, headers)
|
|
@@ -49,14 +49,25 @@ class BatchSerializer:
|
|
|
49
49
|
lines.append(f"{req.method} /b1s/v2/{clean_endpoint} HTTP/1.1")
|
|
50
50
|
|
|
51
51
|
# 5. Internal Headers
|
|
52
|
-
|
|
52
|
+
# Any caller-supplied per-part headers (e.g. Prefer:
|
|
53
|
+
# odata.maxpagesize, If-Match) — skip Content-Type, we set our own
|
|
54
|
+
# below whenever a body is present.
|
|
55
|
+
if req.headers:
|
|
56
|
+
for hk, hv in req.headers.items():
|
|
57
|
+
if hk.lower() == "content-type":
|
|
58
|
+
continue
|
|
59
|
+
lines.append(f"{hk}: {hv}")
|
|
60
|
+
# A body is present whenever data is not None — note an empty dict
|
|
61
|
+
# ({}) is a valid, required body for some bounded functions (e.g.
|
|
62
|
+
# the SQLQueries /List POST), so we must not skip it on falsiness.
|
|
63
|
+
if req.data is not None:
|
|
53
64
|
lines.append("Content-Type: application/json")
|
|
54
65
|
lines.append("") # End of internal headers
|
|
55
66
|
|
|
56
67
|
# 6. Body
|
|
57
|
-
if req.data:
|
|
68
|
+
if req.data is not None:
|
|
58
69
|
lines.append(json.dumps(req.data))
|
|
59
|
-
|
|
70
|
+
|
|
60
71
|
lines.append("") # Blank line after body (OData multipart spec)
|
|
61
72
|
|
|
62
73
|
# Close the last changeset if it remained open
|
|
@@ -18,6 +18,8 @@ if TYPE_CHECKING:
|
|
|
18
18
|
from b1sl.b1sl.models._generated.entities.inventory import Item
|
|
19
19
|
from b1sl.b1sl.models.base import B1Model
|
|
20
20
|
from b1sl.b1sl.resources.base import GenericResource
|
|
21
|
+
from b1sl.b1sl.resources.crossjoin import CrossJoinQueryBuilder, QueryServiceBuilder
|
|
22
|
+
from b1sl.b1sl.resources.sql_queries import SQLQueriesResource
|
|
21
23
|
from b1sl.b1sl.resources.udo import UDOResource
|
|
22
24
|
|
|
23
25
|
|
|
@@ -348,6 +350,15 @@ class B1Client:
|
|
|
348
350
|
from b1sl.b1sl.models._generated.entities.general import Document
|
|
349
351
|
return self.get_resource(Document, "CorrectionPurchaseInvoiceReversal")
|
|
350
352
|
|
|
353
|
+
# --- SQL Queries ---
|
|
354
|
+
|
|
355
|
+
@property
|
|
356
|
+
def sql_queries(self) -> "SQLQueriesResource":
|
|
357
|
+
"""Access the 'SQLQueries' endpoint (supports ETags, run() / run_stream())."""
|
|
358
|
+
from b1sl.b1sl.resources.sql_queries import SQLQueriesResource
|
|
359
|
+
resource = SQLQueriesResource(self._adapter)
|
|
360
|
+
return resource
|
|
361
|
+
|
|
351
362
|
def udo(self, table_name: str) -> "UDOResource":
|
|
352
363
|
"""
|
|
353
364
|
Access a User Defined Object (UDO) or User Table dynamically.
|
|
@@ -362,3 +373,48 @@ class B1Client:
|
|
|
362
373
|
from b1sl.b1sl.resources.udo import UDOResource
|
|
363
374
|
|
|
364
375
|
return UDOResource(adapter=self._adapter, table_name=table_name)
|
|
376
|
+
|
|
377
|
+
def crossjoin(self, *entities: str) -> "CrossJoinQueryBuilder":
|
|
378
|
+
"""Build a ``$crossjoin`` query across entity sets (SAP HANA only, B1 9.2 patch 07+).
|
|
379
|
+
|
|
380
|
+
At least 2 entity names are required. A bare crossjoin without
|
|
381
|
+
``$expand`` or ``$apply`` will raise ``ValueError`` before the request.
|
|
382
|
+
|
|
383
|
+
Example::
|
|
384
|
+
|
|
385
|
+
rows = (
|
|
386
|
+
client.crossjoin("Orders", "BusinessPartners")
|
|
387
|
+
.expand({"Orders": ["DocEntry", "DocNum"], "BusinessPartners": ["CardCode"]})
|
|
388
|
+
.filter("Orders/CardCode eq BusinessPartners/CardCode")
|
|
389
|
+
.execute()
|
|
390
|
+
)
|
|
391
|
+
"""
|
|
392
|
+
from b1sl.b1sl.resources.crossjoin import CrossJoinQueryBuilder
|
|
393
|
+
|
|
394
|
+
return CrossJoinQueryBuilder(self._adapter, *entities)
|
|
395
|
+
|
|
396
|
+
def query_service(self, query_path: str) -> "QueryServiceBuilder":
|
|
397
|
+
"""Build a ``QueryService_PostQuery`` row-level filter (SAP HANA only, B1 9.2 PL11+).
|
|
398
|
+
|
|
399
|
+
Joins a document header with its navigation lines via POST. Use this
|
|
400
|
+
when you need to filter by line-level fields (ItemCode, LineNum, etc.)
|
|
401
|
+
combined with header fields — which regular ``$filter`` cannot do.
|
|
402
|
+
|
|
403
|
+
Example::
|
|
404
|
+
|
|
405
|
+
rows = (
|
|
406
|
+
client.query_service("$crossjoin(Orders,Orders/DocumentLines)")
|
|
407
|
+
.expand({
|
|
408
|
+
"Orders": ["DocEntry", "DocNum"],
|
|
409
|
+
"Orders/DocumentLines": ["ItemCode", "LineNum"],
|
|
410
|
+
})
|
|
411
|
+
.filter(
|
|
412
|
+
"Orders/DocEntry eq Orders/DocumentLines/DocEntry"
|
|
413
|
+
" and Orders/DocumentLines/ItemCode eq 'WIDGET'"
|
|
414
|
+
)
|
|
415
|
+
.execute()
|
|
416
|
+
)
|
|
417
|
+
"""
|
|
418
|
+
from b1sl.b1sl.resources.crossjoin import QueryServiceBuilder
|
|
419
|
+
|
|
420
|
+
return QueryServiceBuilder(self._adapter, query_path)
|
|
@@ -4,6 +4,9 @@ from b1sl.b1sl.exceptions.exceptions import (
|
|
|
4
4
|
B1Exception,
|
|
5
5
|
B1NotFoundError,
|
|
6
6
|
B1ResponseError,
|
|
7
|
+
B1SqlNotAllowedError,
|
|
8
|
+
B1SqlParamError,
|
|
9
|
+
B1SqlSyntaxError,
|
|
7
10
|
B1ValidationError,
|
|
8
11
|
SAPConcurrencyError,
|
|
9
12
|
)
|
|
@@ -14,6 +17,9 @@ __all__ = [
|
|
|
14
17
|
"B1ConnectionError",
|
|
15
18
|
"B1NotFoundError",
|
|
16
19
|
"B1ValidationError",
|
|
20
|
+
"B1SqlSyntaxError",
|
|
21
|
+
"B1SqlNotAllowedError",
|
|
22
|
+
"B1SqlParamError",
|
|
17
23
|
"B1ResponseError",
|
|
18
24
|
"SAPConcurrencyError",
|
|
19
25
|
]
|
|
@@ -88,6 +88,101 @@ class B1ValidationError(B1Exception):
|
|
|
88
88
|
"""
|
|
89
89
|
|
|
90
90
|
|
|
91
|
+
class B1SqlNotAllowedError(B1ValidationError):
|
|
92
|
+
"""Raised when SAP rejects a SQLQuery because a table or column is blocked.
|
|
93
|
+
|
|
94
|
+
SAP error codes:
|
|
95
|
+
- ``"702"`` — table not in the server allowlist (``b1s_sqltable.conf``).
|
|
96
|
+
- ``"703"`` — column excluded via ``ColumnExcludeList`` in the same config.
|
|
97
|
+
|
|
98
|
+
Neither condition can be fixed at runtime; the SQL text or the server
|
|
99
|
+
configuration must change. The ``sap_code`` attribute lets callers
|
|
100
|
+
distinguish table-level from column-level blocks::
|
|
101
|
+
|
|
102
|
+
try:
|
|
103
|
+
result = client.sql_queries.run("sql04")
|
|
104
|
+
except B1SqlNotAllowedError as e:
|
|
105
|
+
if e.sap_code == "702":
|
|
106
|
+
print(f"Table blocked: {e}")
|
|
107
|
+
else:
|
|
108
|
+
print(f"Column blocked: {e}")
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
def __init__(
|
|
112
|
+
self,
|
|
113
|
+
message: str,
|
|
114
|
+
*,
|
|
115
|
+
sap_code: str = "702",
|
|
116
|
+
details: dict | None = None,
|
|
117
|
+
) -> None:
|
|
118
|
+
super().__init__(message, details=details)
|
|
119
|
+
self.sap_code = sap_code
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class B1SqlSyntaxError(B1ValidationError):
|
|
123
|
+
"""Raised when SAP rejects a SQL definition or execution due to invalid syntax.
|
|
124
|
+
|
|
125
|
+
SAP error code ``"701"`` — covers multiple sub-cases, all requiring a fix
|
|
126
|
+
to the SQL text itself (no runtime adjustment can resolve a 701 error):
|
|
127
|
+
|
|
128
|
+
- **Grammar error**: typos like ``ORDER BY x dsc`` instead of ``DESC``.
|
|
129
|
+
- **Unsupported function**: e.g. ``length()``, ``CASE WHEN``, ``COALESCE``.
|
|
130
|
+
- **``SELECT *`` in the top-level query**: only allowed inside subqueries.
|
|
131
|
+
- **Computed column without alias**: ``SUM(col)`` must be aliased as
|
|
132
|
+
``SUM(col) AS total``.
|
|
133
|
+
- **Duplicate alias**: two columns sharing the same alias are rejected.
|
|
134
|
+
- **DML statement**: ``UPDATE``, ``INSERT``, ``DELETE``, ``ALTER``, etc. —
|
|
135
|
+
the ``SQLQueries`` endpoint accepts only ``SELECT`` queries.
|
|
136
|
+
|
|
137
|
+
The SAP error message includes the character position and a description::
|
|
138
|
+
|
|
139
|
+
try:
|
|
140
|
+
client.sql_queries.create(en.SQLQuery(sql_code="q1",
|
|
141
|
+
sql_text="select * from ORDR"))
|
|
142
|
+
except B1SqlSyntaxError as e:
|
|
143
|
+
print(e) # "Invalid SQL syntax: ..., Cannot support asterisk(*)..."
|
|
144
|
+
"""
|
|
145
|
+
|
|
146
|
+
SAP_ERROR_CODE = "701"
|
|
147
|
+
|
|
148
|
+
def __init__(self, message: str, *, details: dict | None = None) -> None:
|
|
149
|
+
super().__init__(message, details=details)
|
|
150
|
+
self.sap_code = self.SAP_ERROR_CODE
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class B1SqlParamError(B1ValidationError):
|
|
154
|
+
"""Raised when SAP rejects a ``/List`` invocation due to parameter problems.
|
|
155
|
+
|
|
156
|
+
SAP error code ``"704"`` — covers missing parameters, extra parameters, or
|
|
157
|
+
type mismatches. Unlike ``B1SqlNotAllowedError``, this is fixable by the
|
|
158
|
+
caller: check that the kwargs passed to ``run()`` / ``run_stream()`` match
|
|
159
|
+
the ``ParamList`` declared in the stored ``SqlText``::
|
|
160
|
+
|
|
161
|
+
try:
|
|
162
|
+
rows = client.sql_queries.run("sql01", doc_total=100)
|
|
163
|
+
except B1SqlParamError:
|
|
164
|
+
# Wrong param name — SAP expects :docTotal, not :doc_total
|
|
165
|
+
rows = client.sql_queries.run("sql01", docTotal=100)
|
|
166
|
+
|
|
167
|
+
Note: SAP returns a generic ``"Parameter error."`` message without naming
|
|
168
|
+
the offending parameter. Inspect the stored query's ``ParamList`` field
|
|
169
|
+
to cross-reference.
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
SAP_ERROR_CODE = "704"
|
|
173
|
+
|
|
174
|
+
def __init__(
|
|
175
|
+
self,
|
|
176
|
+
message: str,
|
|
177
|
+
*,
|
|
178
|
+
details: dict | None = None,
|
|
179
|
+
expected_params: list[str] | None = None,
|
|
180
|
+
) -> None:
|
|
181
|
+
super().__init__(message, details=details)
|
|
182
|
+
self.sap_code = self.SAP_ERROR_CODE
|
|
183
|
+
self.expected_params: list[str] | None = expected_params
|
|
184
|
+
|
|
185
|
+
|
|
91
186
|
class B1ResponseError(B1Exception):
|
|
92
187
|
"""Raised for unexpected non-2xx responses not covered by other subclasses."""
|
|
93
188
|
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
from urllib.parse import parse_qs, urlparse
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
def extract_next_link(data: dict) -> str | None:
|
|
5
|
+
"""Return the OData nextLink from a response body, tolerating v3 and v4 formats.
|
|
6
|
+
|
|
7
|
+
SAP Service Layer uses different key names depending on the OData version:
|
|
8
|
+
- OData v3 (``b1s/v1``): ``"odata.nextLink"``
|
|
9
|
+
- OData v4 (``b1s/v2``): ``"@odata.nextLink"``
|
|
10
|
+
|
|
11
|
+
Returns the first non-empty value found, or ``None``.
|
|
12
|
+
"""
|
|
13
|
+
return data.get("@odata.nextLink") or data.get("odata.nextLink") or None
|
|
14
|
+
|
|
15
|
+
|
|
4
16
|
def extract_skip(next_link: str) -> int | None:
|
|
5
17
|
"""
|
|
6
18
|
Extracts the $skip value from an odata.nextLink string.
|