Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Exact Online Bundle Laravel Package

aibianchi/exact-online-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle

    composer require aibianchi/exact-online-bundle
    
  2. Configure Exact Online Accounts Add your Exact Online credentials to config/packages/exact_online.yaml:

    exact_online:
      Belgium:
        baseUrl:      https://start.exactonline.be/
        apiUrl:       api/v1
        authUrl:      api/oauth2/auth
        tokenUrl:     api/oauth2/token
        redirectUrl:  https://yourdomain.com/exact-request
        clientId:     YOUR_CLIENT_ID
        clientSecret: YOUR_CLIENT_SECRET
    
  3. Update Database Schema

    php bin/console doctrine:schema:update --force
    
  4. First Authentication Redirect users to Exact Online’s OAuth flow:

    // In a controller (e.g., ExactRequestController)
    public function authenticate(Request $request, ExactManager $exactManager) {
        $code = $request->query->get('code');
        $exactManager->init($code, "Belgium"); // First-time auth
    }
    

    Visit https://yourdomain.com/exact-request to trigger the OAuth flow.


First Use Case: Fetching Accounts

use aibianchi\ExactOnlineBundle\Manager\ExactManager;

public function listAccounts(ExactManager $exactManager) {
    $accounts = $exactManager->getModel("Account")->getList(1, 10); // Page 1, 10 items
    foreach ($accounts as $account) {
        dump($account->getName());
    }
}

Implementation Patterns

Dependency Injection & Service Integration

  • Inject ExactManager into controllers/services:
    public function __construct(private ExactManager $exactManager) {}
    
  • Multi-Account Handling: Use the country key (e.g., "Belgium") to switch contexts:
    $exactManager->refreshToken("France"); // Switch to France account
    

Common Workflows

  1. CRUD Operations

    // Create
    $item = new Item();
    $item->setCode('TEST123')->setDescription('Test Item');
    $exactManager->persist($item);
    
    // Read
    $account = $exactManager->getModel("Account")->find("GUID_HERE");
    
    // Update
    $account->setWebsite("https://example.com");
    $exactManager->update($account);
    
    // Delete
    $exactManager->remove($account);
    
  2. Querying with Filters

    $criteria = ['BusinessType' => 'Customer'];
    $accounts = $exactManager->getModel("Account")->findBy($criteria, ['Name', 'Email']);
    
  3. Pagination

    $page = 2;
    $perPage = 20;
    $accounts = $exactManager->getModel("Account")->getList($page, $perPage);
    
  4. Token Refresh Schedule a job to refresh tokens before expiration (e.g., via Symfony Messenger or cron):

    $exactManager->refreshToken("Belgium");
    

Integration Tips

  • Event Listeners: Extend the bundle by listening to exact.online.token.refreshed events.
  • Custom Models: Override model behavior by extending the bundle’s Model class.
  • Error Handling: Wrap API calls in try-catch blocks to handle ExactOnlineException:
    try {
        $exactManager->getModel("Account")->find("INVALID_GUID");
    } catch (\Exception $e) {
        // Log or notify
    }
    

Gotchas and Tips

Pitfalls

  1. Token Expiry

    • The initial OAuth code expires after 10 minutes. Use refreshToken() for subsequent calls.
    • Fix: Store the refresh token securely (e.g., in the database) and automate refreshes.
  2. Country-Specific Config

    • Forgetting to specify the country key (e.g., "Belgium") will default to the first configured account.
    • Fix: Always pass the country to refreshToken() or init().
  3. Guzzle Version Mismatch

    • The bundle requires Guzzle 6. Using Guzzle 7+ may break compatibility.
    • Fix: Pin Guzzle to ^6.2 in composer.json.
  4. Database Schema Updates

    • Running doctrine:schema:update without backing up may overwrite existing data.
    • Fix: Use migrations (doctrine:migrations:diff) instead of --force.
  5. Redirect URL Mismatch

    • The redirectUrl in config must match the Exact Online app registration.
    • Fix: Verify the URL in the Exact Online developer portal.

Debugging

  • Enable API Debugging Configure Guzzle middleware to log requests/responses:

    $exactManager->getClient()->getEmitter()->attach(
        new \GuzzleHttp\Middleware::tap(function ($request, $options) {
            error_log($request->getUri());
        })
    );
    
  • Check Token Validity Manually verify tokens via Exact Online’s OAuth playground.


Extension Points

  1. Custom Endpoints Extend the ExactManager to support non-CRUD endpoints:

    $response = $exactManager->getClient()->request('GET', '/api/v1/Reports');
    
  2. Model Overrides Create a custom model class (e.g., CustomAccount) extending the bundle’s Account model to add fields/methods.

  3. Authentication Flow Override the OAuth redirect logic by extending the ExactAuthenticator service.

  4. Rate Limiting Implement a decorator around ExactManager to handle API rate limits:

    $manager->setRateLimiter(new CustomRateLimiter());
    

Performance Tips

  • Batch Operations: Use Exact Online’s bulk endpoints (if supported) to reduce API calls.

  • Caching: Cache frequent queries (e.g., getList()) with Symfony’s cache component:

    $cacheKey = "accounts_page_1";
    $accounts = $this->cache->get($cacheKey, function() use ($exactManager) {
        return $exactManager->getModel("Account")->getList(1, 10);
    });
    
  • Async Processing: Offload long-running operations (e.g., bulk updates) to Symfony Messenger or a queue worker.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours