All notable changes to laravel-sapb1 will be documented in this file.
- 10 New Documentation Files: Comprehensive guides for SDK features
- Quick Start Guide (
docs/quick-start.md) - Making Requests (
docs/requests.md) - OData Query Builder (
docs/odata-query-builder.md) - Working with Responses (
docs/responses.md) - Multiple Connections (
docs/multiple-connections.md) - Health Checks (
docs/health-checks.md) - Artisan Commands (
docs/artisan-commands.md) - Events Lifecycle (
docs/events.md) - Error Handling (
docs/error-handling.md) - Testing Factories (
docs/testing-factories.md)
- Quick Start Guide (
- 63 New Unit Tests: Expanded test coverage from 164 to 227 tests
MiddlewarePipelineTest: 12 tests for middleware pipeline operationsEntityWatcherTest: 17 tests for change detection watcherChangeSetTest: 10 tests for change set operationsEntitySchemaTest: 12 tests for schema inspectionFieldInfoTest: 13 tests for field info and type checking
- Expanded from ~50 to ~100+ error codes with categories:
- Production/Manufacturing errors
- Pricing and Tax calculation errors
- Payment processing errors
- Inventory transfer errors
- Project management errors
- Banking errors
- Configuration errors
- Added HTTP status codes: 405, 406, 408, 412, 413, 415, 422, 429, 502, 503, 504
- Expanded entity mapping from 7 to 40+ entities:
- Master Data: BusinessPartners, Items, Warehouses, PriceLists, SalesPersons, Employees, ChartOfAccounts, Projects, Users, ItemGroups, BusinessPartnerGroups
- Sales Documents: Orders, Invoices, DeliveryNotes, Returns, CreditNotes, Quotations, DownPayments
- Purchasing Documents: PurchaseOrders, PurchaseDeliveryNotes, PurchaseInvoices, PurchaseReturns, PurchaseCreditNotes, PurchaseQuotations
- Inventory Documents: InventoryGenEntries, InventoryGenExits, StockTransfers, InventoryTransferRequests, InventoryCountings
- Financial Documents: JournalEntries, Payments, IncomingPayments
- Production: ProductionOrders, BillOfMaterials
- Service: ServiceCalls, ServiceContracts
- Banking: BankStatements, Checks
- Draft Documents: Drafts
- Added
getSupportedEntities()static method for entity listing - Added
isEntitySupported()static method for entity validation
- Middleware System: Extensible request/response pipeline
MiddlewareInterfacecontract for custom middlewareMiddlewarePipelinefor chaining middlewareSapB1Client::pushMiddleware()/prependMiddleware()/removeMiddleware()- Built-in middleware:
LoggingMiddleware: Request/response logging with sensitive data maskingRetryMiddleware: Configurable retries with exponential backoffTenantMiddleware: Multi-tenant header injection
- MetadataManager: SAP B1 schema introspection
entities(): List all available entity namesentity('Name'): Get EntitySchema with fields, UDFs, navigation propertieshasEntity()/hasField(): Quick existence checksudos(): List User Defined Objectsudts(): List User Defined Tablesudfs('TableName'): Get User Defined Fields for entity- Automatic caching with configurable TTL
- OData v3 (XML) and v4 (JSON) metadata parsing
- ErrorCodeDatabase: Human-readable SAP error messages
- 50+ common SAP B1 error codes with descriptions
- Actionable suggestions for each error
- Error categories (authentication, validation, business_logic, etc.)
isRetryable()flag for automatic retry decisions
- Enhanced ServiceLayerException:
getHumanMessage(): User-friendly error messagegetSuggestion(): How to fix the errorgetCategory(): Error classificationisRetryable(): Whether retry might succeed
- ChangeDetector: Polling-based entity change tracking (webhook alternative)
watch('Entity'): Start watching entity for changespoll(): Detect created/updated/deleted records- Callback system:
onCreated(),onUpdated(),onDeleted() - Configurable track fields and filters
- State caching for efficient change detection
- EntityWatcher: Configure what to watch
keyField(): Set primary key fieldtrack(): Specify fields to monitorwhere(): Filter watched recordslimit(): Max records to track
- ChangeSet: Detected changes container
- AuditService: Access SAP B1 change/access logs
entity('BusinessPartners')->key('C001')->get(): Query change historyaccessLog()->user('manager')->getAccessLog(): Query access log- Date filters:
since(),until(),between() - Maps to SAP history tables (ACRD, AITM, etc.)
- AlertService: SAP B1 internal messaging
send()/sendMessage(): Send internal messagesconfigurations(): List alert rulescreateRule()/updateRule()/deleteRule(): Manage alertspending(): Get unread alertsmarkRead(): Mark alert as read
- CompanyService: Company and system information
info(): Full company informationname()/localCurrency()/country()/version()adminInfo(): Administrative settingsserviceLayerInfo(): Service Layer configurationisHana()/isMultiBranch(): System capabilities
- ConnectionDiagnostics: Comprehensive connection health
run(): Full diagnostic reporttestConnectivity(): DNS, TCP, HTTP, Auth testsmeasureLatency(): Latency sampling with P95getHealthStatus(): Quick health checkgetSessionStatus(): Session informationgetPerformanceMetrics(): Profiler integration
- TenantManager: Multi-tenant SAP B1 support
setTenant()/getTenant(): Tenant contextsetResolver(): Custom tenant resolutiongetConfig(): Tenant-specific configurationforTenant(): Execute in tenant context
- TenantResolverInterface: Implement custom resolution
- DatabaseTenantResolver: Example database-based resolver
- TenantMiddleware: Automatic tenant header injection
- TelemetryService: Distributed tracing support (optional)
enable()/disable(): Toggle telemetryrecordMetric(): Custom metricsrecordRequest()/recordDuration()/recordError()- Auto-enables via config when available
- OpenTelemetryMiddleware: Automatic span creation
- Request/response attributes
- Error recording with stack traces
- Requires:
open-telemetry/sdk,open-telemetry/api
metadata(): Access MetadataManageraudit(): Access AuditServicealerts(): Access AlertServicecompany(): Access CompanyServicechanges(): Access ChangeDetectordiagnostics(): Access ConnectionDiagnostics
- ServiceProvider registers TenantManager and TelemetryService
- PendingRequest integrates middleware pipeline
- ServiceLayerException enhanced with ErrorCodeDatabase integration
- Version bumped to 1.8.0
-
Session Pool: High-concurrency session management for heavy load scenarios
SessionPoolclass implementingSessionPoolInterface- Acquire/release pattern for session usage
PooledSessionvalue object wrapping SessionData with pool metadataPoolConfigurationvalue object with validation
-
Pool Storage Drivers:
DatabasePoolStore: Database-based pool storage with atomic operationsRedisPoolStore: Redis-based pool storage using Hash and Sets- Migration:
create_sapb1_session_pool_tablefor database driver
-
Distribution Algorithms:
round_robin: Evenly distributes across sessions (oldest released first)least_connections: Selects least used sessionlifo: Last-In-First-Out for cache locality
-
Pool Configuration:
min_size/max_size: Pool size boundariesidle_timeout/wait_timeout: Timeout settingswarmup_on_boot: Auto pre-create sessions on app bootvalidation_on_acquire: Validate session before returning
-
New Events:
SessionAcquired: Fired when session acquired from poolSessionReleased: Fired when session released to poolPoolWarmedUp: Fired when pool warmup completesPoolSessionExpired: Fired when pooled session expires
-
New Exceptions:
PoolExhaustedException: No session available within timeoutPoolConfigurationException: Invalid pool configuration
-
New Artisan Command:
sap-b1:poolstatus: Show pool statistics and healthwarmup: Pre-create sessions (--count=Nto specify)drain: Close and remove all sessionscleanup: Remove expired sessionssessions: List session summary by status
-
SapB1Client Pool Integration:
releaseSession(): Release acquired session back to poolisUsingPool(): Check if pool is activegetPoolStats(): Get pool statistics
SapB1Clientnow accepts optionalSessionPoolInterfacefor pool usageSessionManagerexposescreateNewSession()for pool session creation- ServiceProvider version updated to 1.7.0
- Added 43 new unit tests for pool components
- Total tests: 164 (297 assertions)
- Circuit Breaker: Prevent cascading failures with automatic circuit breaking
CircuitBreakerclass with CLOSED, OPEN, HALF_OPEN statesCircuitBreakerInterfacecontract for custom implementationsCircuitBreakerOpenExceptionfor circuit open scenariosCircuitBreakerStateChangedevent for monitoring state transitions- Configurable:
failure_threshold,open_duration,half_open_max_attempts - Per-endpoint or global tracking via
scopeconfig withCircuitBreaker()/withoutCircuitBreaker()methods on PendingRequest- Laravel Cache-based state storage
- Only real errors count as failures: Connection timeouts and 5xx status codes
- Slow but successful responses are SUCCESS, not failures
- Auto Request ID in createRequest(): Request IDs now properly applied
withRequestId()chained inSapB1Client::createRequest()when auto is enabled- Ensures request ID propagates through all request methods
- Fixed auto request ID not being applied via
SapB1Client.createRequest()
- Added comprehensive unit tests for CircuitBreaker (14 tests)
- Added CircuitBreakerOpenException tests
- Dual OData Version Support: Both v1 (OData v3) and v2 (OData v4)
odata_versionconfig option per connection (default: 'v1')useODataV4()/useODataV3()/withODataVersion()fluent methods- Backward compatible - v1 remains default
- SAP deprecated OData v3 in FP 2405
- 429 Rate Limit Handling: Automatic retry with Retry-After header
RateLimitExceptionfor rate limit errorsparseRetryAfter()for intelligent delay based on header- Added 429 to default retry status codes
- 502 Proxy Error Recovery: Enhanced handling for proxy errors
ProxyExceptionfor proxy-related errors- Configurable longer delays for proxy errors (
proxy_error_delay) - Separate max retry count for 502 errors (
proxy_error_max_attempts)
- Preemptive Session Renewal: Proactive session refresh
getRemainingTtl()method on SessionData- Automatic refresh before timeout based on threshold
- Reduces latency caused by expired sessions
- Request Compression: Gzip compression for large payloads
withCompression()/withoutCompression()methods- Configurable minimum size threshold
- Automatic Content-Encoding header
- Request ID Tracking: X-Request-ID header support
withRequestId()method for manual IDautoconfig for automatic ID generation- Included in logs for correlation
getRequestId()on Response class
- Updated retry status codes to include 429 (rate limit)
- Enhanced
sleepWithResponse()for status-aware delays - Added
shouldRetry()special handling for 502 errors
- Session Auto-Refresh: Automatic session refresh on 401 errors
invalidateAndRefresh()method in SessionManagerisSessionError()for detecting session-related errorswithAutoRefresh()/withoutAutoRefresh()on SapB1Client- Configurable via
session.auto_refreshconfig option
- Session Pool Foundation: Interface and config for high-concurrency session pooling
SessionPoolInterfacewith acquire/release/stats methods- Pool configuration: min_size, max_size, idle_timeout, wait_timeout
- Distribution algorithms: round_robin, least_connections, lifo
- JsonDecodeException: Dedicated exception for JSON parsing errors
fromLastError()static factory method- Includes body preview and error context
- Used in Response::decodeBody() and SessionData::fromJson()
- OData Filter Sanitization: Protection against OData injection
- Field name validation (alphanumeric, underscore, dot, slash)
- Operator whitelist (eq, ne, gt, ge, lt, le)
strictMode()/withoutStrictMode()for control
- Pagination nextLink Parsing: Correct URL parsing for OData pagination
- Fixed regex to properly extract endpoint from /b1s/v1/ paths
- Added fallback for unusual URL formats
- Race Condition in File Lock: Replaced TOCTOU-vulnerable code with flock()
- Atomic lock acquisition using LOCK_EX | LOCK_NB
- Proper file handle management for lock release
- Updated SapB1Client CRUD methods to use auto-refresh wrapper
- Enhanced FileSessionDriver with proper file locking mechanism
- Batch Operations: Execute multiple requests in a single HTTP call with changeset support
BatchRequestandBatchResponseclasses- Atomic changeset transactions with
beginChangeset()/endChangeset() - Support for GET, POST, PATCH, PUT, DELETE in batches
- Exponential Backoff: Smart retry logic with jitter to prevent thundering herd
- Connection Pooling: Shared Guzzle client with keep-alive for better performance
- Request/Response Logging: Debug logging with sensitive data masking (passwords, tokens)
- Timeout Configuration: Configurable request and connection timeouts
- Attachments API: File upload/download support via
AttachmentsManagerupload(),download(),list(),delete(),metadata()- File validation (size limits, allowed extensions)
- Query Caching: Cache GET request results with
QueryCache- Pattern-based include/exclude rules
- Configurable TTL
- Cache Invalidation: Smart cache invalidation with
CacheInvalidator- Relation-based invalidation (e.g., Order change invalidates BusinessPartners cache)
- SQL Queries: Execute stored SQL queries via
SqlQueryBuildersql('QueryName')->param('key', 'value')->execute()- Pagination with
top()andskip()
- Semantic Layer: Query semantic layer views via
SemanticLayerClientsemantic('ViewName')->dimensions(...)->measures(...)->execute()
- Cross-Company Queries: Query across company databases
query()->crossCompany('*')orcrossCompany('CompanyDB')
- Query Profiling: Performance monitoring with
QueryProfiler- Track slow queries, get statistics, analyze by endpoint
- Updated
SapB1ServiceProviderto register new services (QueryCache, CacheInvalidator, QueryProfiler) - Version bumped to 1.3.0 in about command
- Core Client: Full SAP B1 Service Layer API client with CRUD operations
- Session Management: Automatic session handling with multiple drivers (file, redis, database)
- OData Query Builder: Fluent query builder for complex OData queries
select(),filter(),where(),whereIn(),whereContains()whereStartsWith(),whereNull(),whereBetween()orderBy(),orderByDesc(),top(),skip(),page()expand(),inlineCount()
- Multiple Connections: Support for multiple SAP B1 server connections
- Response Handling: Rich response object with OData metadata support
- Health Checks: Connection health monitoring with
SapB1HealthCheckservice - Artisan Commands:
sap-b1:status- Check connection statussap-b1:session- Manage sessions (login, logout, refresh, clear)sap-b1:health- Health check for connections
- Testing Utilities:
SapB1Faketrait for mocking HTTP requestsFakeResponseclass for building mock responses- Entity factories (BusinessPartner, Item, Order)
- Events: Request lifecycle events for monitoring and logging
SessionCreated,SessionExpiredRequestSending,RequestSent,RequestFailed
- Exceptions: Typed exceptions for different error scenarios
AuthenticationException,ConnectionExceptionServiceLayerException,SessionExpiredException
- Facade & Helper:
SapB1facade andsap_b1()helper function - Laravel Integration: Full integration with Laravel 11.x and 12.x