### Generic HTTP Methods Source: https://github.com/josh48202/current-rms-php/blob/master/README.md Provides examples for making common HTTP requests (GET, POST, PUT, PATCH, DELETE) using the client. ```APIDOC ## Generic HTTP Methods ### Description Allows for making direct HTTP requests to specified endpoints. ### Methods - **GET request** ```php $data = $client->get('/endpoint', ['param' => 'value']); ``` - **POST request** ```php $data = $client->post('/endpoint', ['key' => 'value']); ``` - **PUT request** ```php $data = $client->put('/endpoint', ['key' => 'value']); ``` - **PATCH request** ```php $data = $client->patch('/endpoint', ['key' => 'value']); ``` - **DELETE request** ```php $client->delete('/endpoint'); ``` ### Parameters #### Common Parameters for all methods - **`endpoint`** (string) - Required - The API endpoint path. - **`data`** (array) - Optional (for POST, PUT, PATCH) - The data to send in the request body. - **`query`** (array) - Optional (for GET) - Query parameters to append to the URL. ### Response #### Success Response (200) - **`data`** (mixed) - The response data from the API, typically in JSON format. #### Response Example (for GET request) ```json { "key": "value", "another_key": "another_value" } ``` ``` -------------------------------- ### Install Current RMS PHP Client using Composer Source: https://github.com/josh48202/current-rms-php/blob/master/README.md Installs the Current RMS PHP Client library using Composer, the dependency manager for PHP. This command adds the library to your project's dependencies. ```bash composer require wjbecker/current-rms-php ``` -------------------------------- ### Opportunities API Reference Source: https://github.com/josh48202/current-rms-php/blob/master/README.md Provides detailed examples for interacting with the Opportunities API endpoint, including listing, finding, creating, updating, deleting, checking out, cloning, and finalizing check-ins. ```APIDOC ## API Reference ### Opportunities Endpoint ```php // List all opportunities $opportunities = $client->opportunities()->list(); // List with filters (legacy array syntax) $opportunities = $client->opportunities()->list([ 'q[state_eq]' => 1 ]); // Find specific opportunity $opportunity = $client->opportunities()->find(123); // Find with includes $opportunity = $client->opportunities()->find(123, ['owner', 'member']); // Create opportunity $opportunity = $client->opportunities()->create([ 'subject' => 'New Project', 'member_id' => 456, 'starts_at' => '2025-01-15T08:00:00.000Z', 'ends_at' => '2025-01-16T18:00:00.000Z', ]); // Update opportunity $opportunity = $client->opportunities()->update(123, [ 'subject' => 'Updated Project Name' ]); // Delete opportunity $client->opportunities()->destroy(123); // Checkout (convert to order) $opportunity = $client->opportunities()->checkout([ 'opportunity_id' => 123 ]); // Clone opportunity $newOpportunity = $client->opportunities()->clone(123); // Finalize check-in $opportunity = $client->opportunities()->finalizeCheckIn(123, [ 'return' => [ 'return_at' => '2025-01-15T18:00:00.000Z' ], 'move_outstanding' => false, 'complete_sales_items' => false, ]); ``` ``` -------------------------------- ### Basic Opportunity Filtering with PHP Query Builder Source: https://context7.com/josh48202/current-rms-php/llms.txt Illustrates basic filtering capabilities of the PHP query builder for opportunities. Examples include filtering by state, member ID, creation dates, and string content. It demonstrates chaining methods for creating specific queries. ```php // Simple equality filters $confirmed = $client->opportunities() ->query() ->whereState(3) // Confirmed orders ->forMember(456) ->get(); // Date range queries $recentOrders = $client->opportunities() ->query() ->createdAfter('2025-01-01') ->createdBefore('2025-01-31') ->whereState(3) ->get(); // String searching $weddings = $client->opportunities() ->query() ->whereContains('subject', 'Wedding') ->whereNotEquals('state', 1) // Exclude drafts ->get(); // Multiple conditions $filtered = $client->opportunities() ->query() ->whereGreaterThanOrEqual('charge_total', 1000) ->whereLessThan('charge_total', 5000) ->whereIn('state', [2, 3]) // Provisional or Confirmed ->whereNotNull('venue_id') ->get(); echo "Found {$filtered->count()} opportunities "; ``` -------------------------------- ### PHP List Opportunity Items Source: https://context7.com/josh48202/current-rms-php/llms.txt Provides examples for retrieving lists of opportunity items. It covers listing all items, including unscoped lists and lists with eager loading of related data like 'item' and 'item_assets'. It also demonstrates how to list items for a specific opportunity and check their transaction types (Rental, Sale, Service). ```php // List all opportunity items (unscoped) $allItems = $client->opportunityItems()->list(); foreach ($allItems as $item) { echo "Item: {$item->getItemName()}\n"; echo "Opportunity ID: {$item->opportunity_id}\n"; echo "Quantity: {$item->quantity}\n"; echo "Charge: {$item->charge}\n"; } // List with eager loading $items = $client->opportunityItems()->list([], ['item', 'item_assets']); foreach ($items as $item) { // Access loaded item data if ($item->item) { echo "Item Name: {$item->item->name}\n"; echo "Barcode: {$item->item->barcode}\n"; echo "Description: {$item->item->description}\n"; } } // List items for specific opportunity (scoped) $items = $client->opportunities()->items(123)->list(); foreach ($items as $item) { echo "{$item->getItemName()} x{$item->quantity} = {$item->charge}\n"; // Check transaction type if ($item->isRental()) { echo " Type: Rental\n"; } elseif ($item->isSale()) { echo " Type: Sale\n"; } elseif ($item->isService()) { echo " Type: Service\n"; } } ``` -------------------------------- ### Query Execution Methods Source: https://github.com/josh48202/current-rms-php/blob/master/README.md Details the various methods available to execute a query and retrieve results, including getting collections, single items, paginated data, and checking existence or counts. ```APIDOC ## Query Execution Methods ### Description These methods are used to execute the configured query and retrieve the results in different formats, such as a collection, a single item, or paginated data. ### Method - **get()**: Executes the query and returns a Collection of results. - **first()**: Executes the query and returns the first matching item, or null if no results are found. - **paginate(int $perPage)**: Executes the query and returns a paginated result object. - **cursor()**: Returns an iterator that fetches results page by page, suitable for large datasets. - **exists()**: Executes a query to determine if any records match the criteria, returning a boolean. - **count()**: Executes a query to get the total number of matching records. ### Endpoint N/A (These are methods applied to a query builder object before execution) ### Parameters - **perPage**: (For `paginate`) The number of items to include per page. ### Request Example ```php // Get a Collection of results $results = $query->get(); // Get just the first result $item = $query->first(); // Get paginated results with metadata $page = $query->paginate(10); // Iterate through all pages (memory-efficient) foreach ($query->cursor() as $item) { // Process one item at a time } // Check existence $exists = $query->exists(); // Get count $count = $query->count(); ``` ### Response #### Success Response (200) - **get()**: Returns a Collection of matching objects. - **first()**: Returns a single object or null. - **paginate()**: Returns a PaginatedResult object containing items and metadata. - **cursor()**: Returns an iterator. - **exists()**: Returns a boolean (true or false). - **count()**: Returns an integer representing the total count. #### Response Example ```json // Example for get() { "data": [ { "id": 1, "name": "Item 1" }, { "id": 2, "name": "Item 2" } ] } // Example for paginate() { "data": [ { "id": 1, "name": "Item 1" } ], "current_page": 1, "last_page": 5, "total": 50 } ``` ``` -------------------------------- ### Memory-Efficient Iteration (Generators) Source: https://github.com/josh48202/current-rms-php/blob/master/README.md Demonstrates how to use the `cursor()` method for memory-efficient iteration over large datasets, processing items one at a time without loading the entire dataset into memory. Includes examples with and without filters. ```APIDOC ## Memory-Efficient Iteration (Generators) For large datasets, use the `cursor()` method which yields items one at a time: ```php // Process thousands of items without loading all into memory foreach ($client->opportunityItems()->cursor() as $item) { echo "{$item->getItemName()} - Qty: {$item->quantity}\n"; // Each item is fetched as needed, pages are loaded lazily } // With filters via query builder foreach ($client->opportunityItems()->query()->forOpportunity(123)->cursor() as $item) { processItem($item); } ``` ### Pagination Limits - **Opportunities**: Max 25 items per page - **Other Endpoints**: Max 100 items per page (default) ``` -------------------------------- ### Execute Queries and Process Results in PHP Source: https://context7.com/josh48202/current-rms-php/llms.txt Different methods are available to execute queries and retrieve results, from getting all records to fetching single items, paginated data, or iterating efficiently. You can also check for existence or get a count. ```php // Get collection of all results $results = $client->opportunities() ->query() ->whereState(3) ->get(); echo "Total: {$results->count()}\n"; // Get just the first result $first = $client->opportunities() ->query() ->whereState(3) ->orderBy('created_at', 'desc') ->first(); // Get paginated results with metadata $page = $client->opportunities() ->query() ->whereState(3) ->paginate(page: 1); echo "Page {$page->currentPage()} of {$page->lastPage()}\n"; echo "Total: {$page->total()} items\n"; echo "Showing {$page->count()} on this page\n"; // Memory-efficient iteration through all pages foreach ($client->opportunities()->query()->whereState(3)->cursor() as $opportunity) { // Process one at a time without loading all into memory processOpportunity($opportunity); } // Check existence without loading data $exists = $client->opportunities() ->query() ->forMember(456) ->whereState(1) ->exists(); // Get count (makes API call) $count = $client->opportunities() ->query() ->createdAfter('2025-01-01') ->count(); echo "Found {$count} opportunities created this year\n"; ``` -------------------------------- ### Query Builder: Execution Methods Source: https://github.com/josh48202/current-rms-php/blob/master/README.md Methods to execute queries and retrieve results in various formats. This includes getting collections, single items, paginated data, iterating with cursors, checking for existence, and counting records. ```php // Get a Collection of results $results = $query->get(); // Get just the first result $item = $query->first(); // Get paginated results with metadata $page = $query->paginate(1); // Iterate through all pages (memory-efficient) foreach ($query->cursor() as $item) { // Process one item at a time } // Check existence $exists = $query->exists(); // Get count (requires API call) $count = $query->count(); ``` -------------------------------- ### Generic HTTP Methods with Current RMS PHP Client Source: https://context7.com/josh48202/current-rms-php/llms.txt This snippet demonstrates how to make various HTTP requests (GET, POST, PUT, PATCH, DELETE) using the Current RMS PHP client. It also shows how to access the underlying Guzzle client for advanced usage and how to handle potential API exceptions like AuthenticationException, ValidationException, RateLimitException, and ApiException. ```php // GET request with query parameters $data = $client->get('/custom-endpoint', [ 'param1' => 'value1', 'param2' => 'value2' ]); // POST request with data $result = $client->post('/custom-endpoint', [ 'name' => 'Test', 'value' => 123 ]); // PUT request for updates $updated = $client->put('/custom-endpoint/123', [ 'status' => 'active' ]); // PATCH request for partial updates $patched = $client->patch('/custom-endpoint/123', [ 'field' => 'new value' ]); // DELETE request $client->delete('/custom-endpoint/123'); // Access raw Guzzle client for advanced usage $guzzle = $client->getHttpClient(); // Make custom request with full control $response = $client->request('GET', '/custom-endpoint', [ 'headers' => [ 'Custom-Header' => 'value' ], 'query' => [ 'filter' => 'active' ] ]); // Handle errors try { $data = $client->get('/endpoint'); } catch (WjbeckerCurrentRmsClientExceptionsAuthenticationException $e) { echo "Auth failed: {$e->getMessage()}\n"; } catch (WjbeckerCurrentRmsClientExceptionsValidationException $e) { echo "Validation errors:\n"; print_r($e->getErrors()); } catch (WjbeckerCurrentRmsClientExceptionsRateLimitException $e) { echo "Rate limit exceeded\n"; } catch (WjbeckerCurrentRmsClientExceptionsApiException $e) { echo "API error {$e->getStatusCode()}: {$e->getMessage()}\n"; } ``` -------------------------------- ### Advanced Opportunity Filtering with PHP Query Builder Source: https://context7.com/josh48202/current-rms-php/llms.txt Explores advanced filtering techniques using the PHP query builder, including date range comparisons, string pattern matching (starts with, ends with, contains), array containment checks, and boolean/null value evaluations. It also shows how to use raw predicates for complex queries. ```php // Date ranges with whereBetween $summerEvents = $client->opportunities() ->query() ->whereBetween('starts_at', '2025-06-01', '2025-08-31') ->whereState(3) ->with('member', 'venue') ->get(); // String pattern matching $results = $client->opportunities() ->query() ->whereStartsWith('number', 'ORD-2025') ->whereEndsWith('subject', 'Gala') ->whereNotContains('description', 'cancelled') ->get(); // Array contains checks $tagged = $client->opportunities() ->query() ->whereContainsAll('subject', ['Corporate', 'Annual']) // Must contain ALL ->get(); $anyMatch = $client->opportunities() ->query() ->whereContainsAny('subject', ['Wedding', 'Birthday', 'Anniversary']) // ANY match ->get(); // Boolean and null checks $openWithVenue = $client->opportunities() ->query() ->whereTrue('open_ended_rental') ->whereFalse('invoiced') ->wherePresent('venue_id') // Not null and not blank ->whereBlank('reference') // Null or empty ->get(); // Complex queries with raw predicates $complex = $client->opportunities() ->query() ->where('charge_total', 'gteq', 5000) ->where('item_returned', 'false') ->where('state', 'in', [2, 3, 4]) ->whereNotNull('member_id') ->get(); ``` -------------------------------- ### PHP Query Opportunity Items Source: https://context7.com/josh48202/current-rms-php/llms.txt Details how to filter opportunity items using a query builder. Examples include filtering by transaction type, applying complex criteria like quantity ranges and item IDs, finding high-value items, and searching by item properties. It also shows how to retrieve items for multiple opportunities using the cursor. ```php // Filter by transaction type $rentals = $client->opportunityItems() ->query() ->whereEquals('transaction_type', 1) // Rentals ->forOpportunity(123) ->with('item') ->get(); // Complex item queries $filtered = $client->opportunityItems() ->query() ->where('quantity', 'gteq', 5) // Quantity >= 5 ->where('item_id', 'in', [1, 2, 3]) ->whereNotNull('charge_total') ->with('item', 'rate_definition') ->get(); // Find high-value items $expensive = $client->opportunityItems() ->query() ->whereGreaterThan('charge', 500) ->whereEquals('transaction_type', 1) ->get(); foreach ($expensive as $item) { echo "{$item->getItemName()}: ${$item->charge}\n"; } // Search by item properties $searched = $client->opportunityItems() ->query() ->whereContains('name', 'Projector') ->whereNotEquals('transaction_type', 3) // Exclude services ->get(); // Get items for multiple opportunities $multipleOpps = $client->opportunityItems() ->query() ->where('opportunity_id', 'in', [123, 456, 789]) ->with('item') ->cursor(); ``` -------------------------------- ### Client Initialization Source: https://context7.com/josh48202/current-rms-php/llms.txt Initialize the Current RMS client with API credentials and make your first request. ```APIDOC ## Client Initialization ### Description Initialize the Current RMS client with API credentials. ### Method Various (Initialization and Request) ### Endpoint N/A (Client-side initialization) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```php use Wjbecker\CurrentRms\Client\Auth\ApiKeyAuth; use Wjbecker\CurrentRms\Client\CurrentRmsClient; // Create authentication manager $auth = new ApiKeyAuth( subdomain: 'yourcompany', apiToken: 'your-api-token-here' ); // Initialize client with configuration $client = new CurrentRmsClient( baseUrl: 'https://api.current-rms.com/api/v1', auth: $auth, timeout: 30, connectTimeout: 10, verifySsl: true ); // Make your first request try { $opportunities = $client->opportunities()->list(); echo "Found ". $opportunities->count() . " opportunities\n"; } catch (\Wjbecker\CurrentRms\Client\Exceptions\AuthenticationException $e) { echo "Authentication failed: ". $e->getMessage() . "\n"; } catch (\Wjbecker\CurrentRms\Client\Exceptions\ApiException $e) { echo "API error: ". $e->getMessage() . "\n"; } ``` ### Response #### Success Response (200) - **opportunities** (Collection) - A collection of opportunity objects. #### Response Example ```json // Example output after processing opportunities Found 10 opportunities ``` ``` -------------------------------- ### Testing Source: https://github.com/josh48202/current-rms-php/blob/master/README.md Instructions on how to run automated tests for the package. ```APIDOC ## Testing ### Description Run automated tests using the Pest testing framework. ### Command ```bash ./vendor/bin/pest ``` ``` -------------------------------- ### Initialize Current RMS PHP Client Source: https://context7.com/josh48202/current-rms-php/llms.txt Demonstrates how to initialize the Current RMS PHP client using API credentials and making a basic request. It includes error handling for authentication and API-related exceptions. ```php use Wjbecker\CurrentRms\Client\Auth\ApiKeyAuth; use Wjbecker\CurrentRms\Client\CurrentRmsClient; // Create authentication manager $auth = new ApiKeyAuth( subdomain: 'yourcompany', apiToken: 'your-api-token-here' ); // Initialize client with configuration $client = new CurrentRmsClient( baseUrl: 'https://api.current-rms.com/api/v1', auth: $auth, timeout: 30, connectTimeout: 10, verifySsl: true ); // Make your first request try { $opportunities = $client->opportunities()->list(); echo "Found {$opportunities->count()} opportunities\n"; } catch (\Wjbecker\CurrentRms\Client\Exceptions\AuthenticationException $e) { echo "Authentication failed: {$e->getMessage()}\n"; } catch (\Wjbecker\CurrentRms\Client\Exceptions\ApiException $e) { echo "API error: {$e->getMessage()}\n"; } ``` -------------------------------- ### Client Configuration Source: https://github.com/josh48202/current-rms-php/blob/master/README.md Details on how to configure and instantiate the Current RMS client, including setting the base URL and other options. ```APIDOC ## Configuration Options ### Description Configure and create a new instance of the `CurrentRmsClient`. ### Usage ```php $client = new CurrentRmsClient( baseUrl: 'https://api.current-rms.com/api/v1', // required auth: $auth, // optional timeout: 30, // optional, default: 30 connectTimeout: 10, // optional, default: 10 verifySsl: true // optional, default: true ); ``` ### Parameters - **`baseUrl`** (string) - Required - The base URL for the Current RMS API. - **`auth`** (object) - Optional - Authentication credentials or object. - **`timeout`** (integer) - Optional - The timeout in seconds for requests. Defaults to 30. - **`connectTimeout`** (integer) - Optional - The connection timeout in seconds. Defaults to 10. - **`verifySsl`** (boolean) - Optional - Whether to verify SSL certificates. Defaults to true. ``` -------------------------------- ### Standalone Usage of Current RMS PHP Client Source: https://github.com/josh48202/current-rms-php/blob/master/README.md Demonstrates how to use the Current RMS PHP Client without a framework. It shows the creation of an API authentication object and the client instance, followed by basic operations like listing and finding opportunities. ```php use Wjbecker\CurrentRms\Client\Auth\ApiKeyAuth; use Wjbecker\CurrentRms\Client\CurrentRmsClient; // Create authentication $auth = new ApiKeyAuth( subdomain: 'yourcompany', apiToken: 'your-api-token-here' ); // Create client $client = new CurrentRmsClient( baseUrl: 'https://api.current-rms.com/api/v1', auth: $auth ); // Use the client $opportunities = $client->opportunities()->list(); $opportunity = $client->opportunities()->find(123); ``` -------------------------------- ### PHP Pagination with Navigation Source: https://context7.com/josh48202/current-rms-php/llms.txt Demonstrates how to paginate through results, access items, check pagination state, and navigate between pages. It covers fetching the first page, iterating through items, checking the current page, total items, and more pages, as well as moving to the next, previous, or a specific page. Metadata about the pagination is also accessible. ```php // Get first page $page = $client->opportunities()->paginate(page: 1, perPage: 25); // Access items foreach ($page->items() as $opportunity) { echo "{$opportunity->subject}\n"; } // Check pagination state echo "On page {$page->currentPage()} of {$page->lastPage()}\n"; echo "Total items: {$page->total()}\n"; echo "Items on this page: {$page->count()}\n"; if ($page->hasMorePages()) { echo "More pages available\n"; } if ($page->onFirstPage()) { echo "This is the first page\n"; } // Navigate to next page $nextPage = $page->nextPage(); if ($nextPage) { echo "Next page has {$nextPage->count()} items\n"; } // Navigate to previous page $prevPage = $page->previousPage(); // Go to specific page $page5 = $page->goToPage(5); // Iterate through all pages automatically foreach ($page->cursor() as $opportunity) { echo "{$opportunity->subject}\n"; } // Get metadata $meta = $page->meta(); /* Array ( 'current_page' => 1, 'per_page' => 25, 'total' => 150, 'last_page' => 6, 'has_more_pages' => true, 'count' => 25 ) */ ``` -------------------------------- ### Perform Generic HTTP Requests with PHP Source: https://github.com/josh48202/current-rms-php/blob/master/README.md Execute common HTTP methods (GET, POST, PUT, PATCH, DELETE) against the CurrentRMS API using the provided client. Each method accepts an endpoint path and optional payload or parameters. ```php // GET request $data = $client->get('/endpoint', ['param' => 'value']); // POST request $data = $client->post('/endpoint', ['key' => 'value']); // PUT request $data = $client->put('/endpoint', ['key' => 'value']); // PATCH request $data = $client->patch('/endpoint', ['key' => 'value']); // DELETE request $client->delete('/endpoint'); ``` -------------------------------- ### Delete an Opportunity using PHP Source: https://context7.com/josh48202/current-rms-php/llms.txt Removes an opportunity from the system. This can be done by providing the opportunity's ID. The code demonstrates how to handle potential API errors, such as when an opportunity is not found (404). It also includes an example of deleting multiple opportunities in a loop. ```php // Delete by ID try { $deleted = $client->opportunities()->destroy(123); if ($deleted) { echo "Opportunity deleted successfully "; } } catch (\Wjbecker\CurrentRms\Client\Exceptions\ApiException $e) { if ($e->getStatusCode() === 404) { echo "Opportunity not found "; } else { echo "Failed to delete: {$e->getMessage()} "; } } // Delete multiple opportunities $opportunityIds = [123, 456, 789]; foreach ($opportunityIds as $id) { try { $client->opportunities()->destroy($id); echo "Deleted opportunity #{$id} "; } catch (\Exception $e) { echo "Failed to delete #{$id}: {$e->getMessage()} "; } } ``` -------------------------------- ### List and Filter Opportunities in Current RMS PHP Source: https://context7.com/josh48202/current-rms-php/llms.txt Demonstrates how to retrieve a list of opportunities using the Current RMS PHP client, including basic listing, advanced filtering with Ransack syntax, and accessing related data. It also shows how to use pagination and custom fields. ```php // Basic listing - gets first page with default pagination $opportunities = $client->opportunities()->list(); foreach ($opportunities as $opportunity) { echo "{$opportunity->number} - {$opportunity->subject}\n"; echo "State: {$opportunity->state_name}, Total: {$opportunity->charge_total}\n"; } // Legacy array-based filtering (supports Ransack syntax) $filtered = $client->opportunities()->list([ 'q[state_eq]' => 3, // State equals 3 (Confirmed) 'q[member_id_eq]' => 456, 'q[starts_at_gteq]' => '2025-01-01', 'q[subject_cont]' => 'Wedding' ], ['member', 'venue', 'owner']); // Iterate and access related data foreach ($filtered as $opportunity) { echo "{$opportunity->subject}\n"; echo "Customer: {$opportunity->getMemberName()}\n"; echo "Owner: {$opportunity->getOwnerName()}\n"; // Access custom fields $projectCode = $opportunity->getCustomField('project_code'); if ($projectCode) { echo "Project Code: {$projectCode}\n"; } } ``` -------------------------------- ### Update an Existing Opportunity using PHP Source: https://context7.com/josh48202/current-rms-php/llms.txt Modifies an existing opportunity's details. You can update specific fields like subject, dates, delivery instructions, and state. It also allows for updating custom fields. The code includes examples of handling validation errors if invalid data is provided. ```php // Update specific fields $updated = $client->opportunities()->update(123, [ 'subject' => 'Updated Event Title', 'starts_at' => '2025-06-16T18:00:00.000Z', 'delivery_instructions' => 'Updated delivery notes', 'state' => 3 // Change to Confirmed ] ); echo "Updated opportunity #{$updated->id} "; echo "New subject: {$updated->subject} "; echo "State changed to: {$updated->state_name} "; // Update custom fields $updated = $client->opportunities()->update(123, [ 'custom_fields' => [ 'project_code' => 'NEWCODE2025', 'notes' => 'Additional project notes' ] ] ); // Handle update errors try { $client->opportunities()->update(123, [ 'member_id' => 999999 // Invalid member ID ] ); } catch (ValidationException $e) { echo "Validation errors: "; print_r($e->getErrors()); } ``` -------------------------------- ### Build Fluent Queries with Current RMS PHP Client Source: https://github.com/josh48202/current-rms-php/blob/master/README.md Illustrates the use of the fluent query builder provided by the Current RMS PHP Client. This allows for constructing complex API queries using chainable methods for better readability and maintainability. ```php // Find confirmed opportunities for a specific member $orders = $client->opportunities()->query() ->whereState(3) // Confirmed ->forMember(456) ->createdAfter('2025-01-01') ->with('member', 'venue') ->get(); // Search by subject $results = $client->opportunities()->query() ->whereContains('subject', 'Wedding') ->whereBetween('starts_at', '2025-06-01', '2025-08-31') ->get(); // Filter opportunity items $rentalItems = $client->opportunityItems()->query() ->whereEquals('transaction_type', 1) // Rentals ->forOpportunity(123) ->with('item') ->get(); // Complex queries with Ransack predicates $items = $client->opportunityItems()->query() ->where('quantity', 'gteq', 5) // quantity >= 5 ->where('item_id', 'in', [1, 2, 3]) // item_id in array ->whereNotNull('charge_total') ->get(); ``` -------------------------------- ### Create Opportunity Source: https://context7.com/josh48202/current-rms-php/llms.txt Create a new opportunity, providing essential details and optional custom fields. Handles validation errors gracefully. ```APIDOC ## POST /opportunities ### Description Creates a new opportunity record in the system. Requires core details and allows for custom field population. ### Method POST ### Endpoint `/opportunities` ### Parameters #### Request Body - **subject** (string) - Required - The subject or title of the opportunity. - **member_id** (integer) - Required - The ID of the member associated with the opportunity. - **venue_id** (integer) - Required - The ID of the venue associated with the opportunity. - **starts_at** (datetime) - Required - The start date and time of the opportunity. - **ends_at** (datetime) - Required - The end date and time of the opportunity. - **charge_starts_at** (datetime) - Optional - The start date and time for charging. - **charge_ends_at** (datetime) - Optional - The end date and time for charging. - **description** (string) - Optional - A detailed description of the opportunity. - **delivery_instructions** (string) - Optional - Specific instructions for delivery. - **state** (integer) - Optional - The initial state of the opportunity (e.g., 1 for Draft). - **status** (integer) - Optional - The initial status of the opportunity (e.g., 0 for Open). - **custom_fields** (object) - Optional - A key-value map for custom fields. ### Request Example ```json { "subject": "Corporate Event - Annual Gala", "member_id": 456, "venue_id": 789, "starts_at": "2025-06-15T18:00:00.000Z", "ends_at": "2025-06-15T23:00:00.000Z", "charge_starts_at": "2025-06-15T18:00:00.000Z", "charge_ends_at": "2025-06-15T23:00:00.000Z", "description": "Annual company gala event with full AV setup", "delivery_instructions": "Loading dock access from 14:00", "state": 1, // Draft "status": 0, // Open "custom_fields": { "project_code": "GALA2025", "department": "Marketing" } } ``` ### Response #### Success Response (201 Created) - **id** (integer) - The unique identifier of the newly created opportunity. - **number** (string) - The reference number of the new opportunity. - **state_name** (string) - The name of the opportunity's initial state. #### Response Example ```json { "id": 12345, "number": "OPP-0012345", "state_name": "Draft" } ``` #### Error Response (422 Unprocessable Entity) Returned if validation fails. Includes a map of errors. ```json { "message": "The given data was invalid.", "errors": { "field_name": [ "Error message 1", "Error message 2" ] } } ``` ``` -------------------------------- ### Pagination API Source: https://github.com/josh48202/current-rms-php/blob/master/README.md Documentation for basic pagination and page navigation methods, allowing retrieval and manipulation of paginated query results. ```APIDOC ## Pagination API ### Description Provides functionality for retrieving data in pages and navigating through them. This is essential for handling large datasets efficiently. ### Method - **paginate(int $page, int $perPage)**: Retrieves a specific page of results. - **items()**: Returns the collection of items for the current page. - **currentPage()**: Returns the current page number. - **lastPage()**: Returns the last page number. - **total()**: Returns the total number of items across all pages. - **hasMorePages()**: Returns a boolean indicating if there are more pages available. - **nextPage()**: Returns a new PaginatedResult object for the next page, or null. - **previousPage()**: Returns a new PaginatedResult object for the previous page, or null. - **goToPage(int $pageNumber)**: Returns a new PaginatedResult object for the specified page number, or null. ### Endpoint N/A (These are methods applied to a query builder object or a paginated result object) ### Parameters - **page**: The desired page number (for `paginate`). - **perPage**: The number of items per page (for `paginate`). - **pageNumber**: The target page number (for `goToPage`). ### Request Example ```php // Get the first page with 25 items per page $page = $client->opportunities()->paginate(page: 1, perPage: 25); // Access items on the current page foreach ($page->items() as $opportunity) { echo $opportunity->subject; } // Check pagination metadata echo "Page {$page->currentPage()} of {$page->lastPage()}"; echo "Total items: {$page->total()}"; echo "Has more pages: " . ($page->hasMorePages() ? 'yes' : 'no'); // Navigate between pages $nextPage = $page->nextPage(); $prevPage = $page->previousPage(); $specificPage = $page->goToPage(5); ``` ### Response #### Success Response (200) - **PaginatedResult Object**: Contains the items for the requested page and pagination metadata. #### Response Example ```json { "data": [ { "id": 1, "subject": "Opportunity Alpha", "created_at": "2024-01-10T09:30:00Z" } // ... other items for the page ], "current_page": 1, "last_page": 10, "total": 250, "per_page": 25, "has_more_pages": true } ``` ``` -------------------------------- ### PHP Memory-Efficient Cursor Iteration Source: https://context7.com/josh48202/current-rms-php/llms.txt This section illustrates how to process large datasets without consuming excessive memory by using cursors. It shows iterating through thousands of items one at a time, with pages being loaded lazily and memory usage remaining constant. Examples include processing opportunity items with query filters and calculating total revenue from all opportunities efficiently. ```php // Process thousands of items one at a time foreach ($client->opportunityItems()->cursor() as $item) { echo "{$item->getItemName()} - Qty: {$item->quantity}\n"; // Each item is fetched as needed // Pages are loaded lazily // Memory usage stays constant } // With query filters foreach ($client->opportunityItems() ->query() ->forOpportunity(123) ->whereEquals('transaction_type', 1) // Rentals only ->cursor() as $item) { if ($item->quantity > 10) { processLargeOrder($item); } } // Process all opportunities efficiently $totalRevenue = 0; foreach ($client->opportunities()->cursor() as $opportunity) { $totalRevenue += (float) $opportunity->charge_total; } echo "Total revenue: ${$totalRevenue}\n"; // Cursor vs get() comparison // BAD - Loads everything into memory $all = $client->opportunities()->list(); // Could be thousands of records // GOOD - Processes one at a time foreach ($client->opportunities()->cursor() as $opportunity) { // Constant memory usage } ``` -------------------------------- ### Configure CurrentRMS PHP Client Source: https://github.com/josh48202/current-rms-php/blob/master/README.md Manually instantiate the CurrentRMS client by providing necessary configuration options. Key parameters include the base URL, authentication details, and network timeouts. ```php $client = new CurrentRmsClient( baseUrl: 'https://api.current-rms.com/api/v1', // required auth: $auth, // optional timeout: 30, // optional, default: 30 connectTimeout: 10, // optional, default: 10 verifySsl: true // optional, default: true ); ``` -------------------------------- ### Create a New Opportunity using PHP Source: https://context7.com/josh48202/current-rms-php/llms.txt Creates a new opportunity in the system. This function requires essential fields like subject, member ID, venue ID, and start/end times. Optional fields such as description, delivery instructions, state, status, and custom fields can also be provided. Includes error handling for validation and API issues. ```php use Wjbecker\CurrentRms\Client\Exceptions\ValidationException; try { $opportunity = $client->opportunities()->create([ 'subject' => 'Corporate Event - Annual Gala', 'member_id' => 456, 'venue_id' => 789, 'starts_at' => '2025-06-15T18:00:00.000Z', 'ends_at' => '2025-06-15T23:00:00.000Z', 'charge_starts_at' => '2025-06-15T18:00:00.000Z', 'charge_ends_at' => '2025-06-15T23:00:00.000Z', 'description' => 'Annual company gala event with full AV setup', 'delivery_instructions' => 'Loading dock access from 14:00', 'state' => 1, // Draft 'status' => 0, // Open 'custom_fields' => [ 'project_code' => 'GALA2025', 'department' => 'Marketing' ] ]); echo "Created opportunity #{$opportunity->id} "; echo "Number: {$opportunity->number} "; echo "State: {$opportunity->state_name} "; } catch (ValidationException $e) { echo "Validation failed: "; foreach ($e->getErrors() as $field => $errors) { echo " {$field}: " . implode(', ', $errors) . " "; } } catch (\Wjbecker\CurrentRms\Client\Exceptions\ApiException $e) { echo "API error: {$e->getMessage()} "; } ``` -------------------------------- ### POST /opportunities Source: https://context7.com/josh48202/current-rms-php/llms.txt Retrieve a list of opportunities with options for filtering, sorting, and including related data. ```APIDOC ## POST /opportunities ### Description Retrieve a list of opportunities with filtering and pagination. ### Method GET ### Endpoint `/opportunities` ### Parameters #### Path Parameters None #### Query Parameters - **q[state_eq]** (integer) - Optional - Filter opportunities by state ID. - **q[member_id_eq]** (integer) - Optional - Filter opportunities by member ID. - **q[starts_at_gteq]** (string) - Optional - Filter opportunities starting on or after a specific date (YYYY-MM-DD). - **q[subject_cont]** (string) - Optional - Filter opportunities where the subject contains the specified string. - **include** (array) - Optional - Include related data such as 'member', 'venue', 'owner'. #### Request Body None ### Request Example ```php // Basic listing - gets first page with default pagination $opportunities = $client->opportunities()->list(); foreach ($opportunities as $opportunity) { echo "".$opportunity->number." - ".$opportunity->subject."\n"; echo "State: ".$opportunity->state_name.", Total: ".$opportunity->charge_total."\n"; } // Legacy array-based filtering (supports Ransack syntax) $filtered = $client->opportunities()->list([ 'q[state_eq]' => 3, // State equals 3 (Confirmed) 'q[member_id_eq]' => 456, 'q[starts_at_gteq]' => '2025-01-01', 'q[subject_cont]' => 'Wedding' ], ['member', 'venue', 'owner']); // Iterate and access related data foreach ($filtered as $opportunity) { echo "".$opportunity->subject."\n"; echo "Customer: ".$opportunity->getMemberName()."\n"; echo "Owner: ".$opportunity->getOwnerName()."\n"; // Access custom fields $projectCode = $opportunity->getCustomField('project_code'); if ($projectCode) { echo "Project Code: ".$projectCode."\n"; } } ``` ### Response #### Success Response (200) - **opportunities** (Collection) - A collection of opportunity objects, potentially filtered and including related data. #### Response Example ```json [ { "id": 123, "number": "OPP-001", "subject": "Wedding Rental", "state_name": "Confirmed", "charge_total": "1500.00", "member": { "id": 456, "name": "John Doe" }, "venue": { "id": 789, "name": "Downtown Hall" }, "owner": { "id": 101, "name": "Jane Smith" }, "custom_fields": { "project_code": "WED2025" } } // ... more opportunity objects ] ``` ```