Click here to Skip to main content
15,887,420 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
I am working on the Akaunting project which has modules inside the project. My main aim was to try to fetch the crud outside of the modules and calls APIs in the routes/api.php in my Laravel project.

Chart of accounts controller inside modules:

PHP
<?php

namespace Modules\DoubleEntry\Http\Controllers;

use App\Traits\Uploads;
use App\Abstracts\Http\Controller;
use Modules\DoubleEntry\Models\Type;
use Modules\DoubleEntry\Models\Account;
use Modules\DoubleEntry\Models\DEClass;
use Modules\DoubleEntry\Traits\Accounts;
use Modules\DoubleEntry\Exports\COA as Export;
use Modules\DoubleEntry\Imports\COA as Import;
use Modules\DoubleEntry\Jobs\Account\CreateAccount;
use Modules\DoubleEntry\Jobs\Account\DeleteAccount;
use Modules\DoubleEntry\Jobs\Account\UpdateAccount;
use Modules\DoubleEntry\Jobs\Account\ImportAccount;
use App\Http\Requests\Common\Import as ImportRequest;
use Modules\DoubleEntry\Http\Requests\Account as Request;

class ChartOfAccounts extends Controller
{
    use Accounts, Uploads;

    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        $classes = DEClass::whereHas(
            'accounts',
            function ($query) {
                $query->isNotSubAccount()
                    ->usingSearchString();
            }
        )->with([
            'accounts' => function ($query) {
                $query->isNotSubAccount()
                    ->usingSearchString()
                    ->with(['type', 'declass', 'sub_accounts']);
            },
        ])->collect('id');

        return view('double-entry::chart_of_accounts.index', compact('classes'));
    }

    /**
     * Show the form for viewing the specified resource.
     *
     * @return Response
     */
    public function show()
    {
        return redirect()->route('double-entry.chart-of-accounts.index');
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return Response
     */
    public function create()
    {
        $types = [];

        $classes = DEClass::pluck('name', 'id')->map(function ($name) {
            return trans($name);
        })->toArray();

        $all_types = Type::all()->reject(function ($t) {
            return ($t->id == setting('double-entry.types_tax', 17));
        });

        foreach ($all_types as $type) {
            if (!isset($classes[$type->class_id])) {
                continue;
            }

            $types[$classes[$type->class_id]][$type->id] = trans($type->name);
        }

        ksort($types);

        $accounts = [];

        Account::with('type')
            ->collect(['type.class_id'])
            ->each(function ($account) use (&$accounts) {
                $accounts[$account->type->id][trans($account->type->name)][$account->id] = $account->code . ' - ' . $account->trans_name;
            });

        return view('double-entry::chart_of_accounts.create', compact('types', 'accounts'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  Request  $request
     *
     * @return Response
     */
    public function store(Request $request)
    {
        $response = $this->ajaxDispatch(new CreateAccount($request));

        if ($response['success']) {
            $response['redirect'] = route('double-entry.chart-of-accounts.index');

            $message = trans('messages.success.added', ['type' => trans_choice('general.accounts', 1)]);

            flash($message)->success();
        }

        if ($response['error']) {
            $response['redirect'] = route('double-entry.chart-of-accounts.create');

            $message = $response['message'];

            flash($message)->error()->important();
        }

        return response()->json($response);
    }

    /**
     * Duplicate the specified resource.
     *
     * @param  Account  $chart_of_account
     *
     * @return Response
     */
    public function duplicate(Account $chart_of_account)
    {
        $clone = $chart_of_account->duplicate();

        $message = trans('messages.success.duplicated', ['type' => trans_choice('general.accounts', 1)]);

        flash($message)->success();

        return redirect()->route('double-entry.chart-of-accounts.edit', $clone->id);
    }

    /**
     * Import the specified resource.
     *
     * @param  ImportRequest  $request
     *
     * @return Response
     */
    public function import(ImportRequest $request)
    {
        $response = $this->ajaxDispatch(new ImportAccount(new Import, $request));

        if ($response['data']['success']) {
            $response['redirect'] = route('double-entry.chart-of-accounts.index');

            flash($response['data']['message'])->success();
        } else {
            $response['redirect'] = route('import.create', ['double-entry', 'chart-of-accounts']);

            flash($response['data']['message'])->error()->important();
        }

        return response()->json($response);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  Account  $chart_of_account
     *
     * @return Response
     */
    public function edit(Account $chart_of_account)
    {
        $account = $chart_of_account;

        $account->name = trans($account->name);

        $types = [];

        $classes = DEClass::pluck('name', 'id')->map(function ($name) {
            return trans($name);
        })->toArray();

        if ($chart_of_account->type_id == setting('double-entry.types_tax', 17)) {
            $all_types = Type::all();
        } else {
            $all_types = Type::all()->reject(function ($t) {
                return ($t->id == setting('double-entry.types_tax', 17));
            });
        }

        foreach ($all_types as $type) {
            if (!isset($classes[$type->class_id])) {
                continue;
            }

            $types[$classes[$type->class_id]][$type->id] = trans($type->name);
        }

        ksort($types);

        $accounts[$account->type_id] = [];

        $sub_accounts_ids = $account->child_nodes
            ->flatten()
            ->pluck('id')
            ->toArray();

        Account::with('type')
            ->whereKeyNot($chart_of_account->id)
            ->whereNotIn('double_entry_accounts.id', $sub_accounts_ids)
            ->collect(['type.class_id'])
            ->each(function ($account) use (&$accounts) {
                $accounts[$account->type->id][trans($account->type->name)][$account->id] = $account->code . ' - ' . $account->trans_name;
            });

        return view('double-entry::chart_of_accounts.edit', compact('account', 'types', 'accounts'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  Account  $chart_of_account
     * @param  Request  $request
     *
     * @return Response
     */
    public function update(Account $chart_of_account, Request $request)
    {
        $response = $this->ajaxDispatch(new UpdateAccount($chart_of_account, $request));

        if ($response['success']) {
            $response['redirect'] = route('double-entry.chart-of-accounts.index');

            $message = trans('messages.success.updated', ['type' => trans_choice('general.accounts', 1)]);

            flash($message)->success();
        }

        if ($response['error']) {
            $response['redirect'] = route('double-entry.chart-of-accounts.edit', $chart_of_account->id);

            flash($response['message'])->error()->important();
        }

        return response()->json($response);
    }

    /**
     * Enable the specified resource.
     *
     * @param  Account  $chart_of_account
     *
     * @return Response
     */
    public function enable(Account $chart_of_account)
    {
        $response = $this->ajaxDispatch(new UpdateAccount($chart_of_account, request()->merge(['enabled' => 1])));

        if ($response['success']) {
            $response['message'] = trans('messages.success.enabled', ['type' => trans($chart_of_account->name)]);
        }

        return response()->json($response);
    }

    /**
     * Disable the specified resource.
     *
     * @param  Account  $chart_of_account
     *
     * @return Response
     */
    public function disable(Account $chart_of_account)
    {
        $response = $this->ajaxDispatch(new UpdateAccount($chart_of_account, request()->merge(['enabled' => 0])));

        if ($response['success']) {
            $response['message'] = trans('messages.success.disabled', ['type' => trans($chart_of_account->name)]);
        }

        return response()->json($response);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  Account  $chart_of_account
     *
     * @return Response
     */
    public function destroy(Account $chart_of_account)
    {
        $response = $this->ajaxDispatch(new DeleteAccount($chart_of_account));

        $response['redirect'] = route('double-entry.chart-of-accounts.index');

        if ($response['success']) {
            $message = trans('messages.success.deleted', ['type' => trans($chart_of_account->name)]);

            flash($message)->success();
        }

        if ($response['error']) {
            $message = $response['message'];

            flash($message)->error()->important();
        }

        return response()->json($response);
    }

    /**
     * Export the specified resource.
     *
     * @return Response
     */
    public function export()
    {
        return $this->exportExcel(new Export, trans_choice('double-entry::general.chart_of_accounts', 2));
    }
}

route. admin.php handles the controller routes:

PHP
<?php

Route::admin('double-entry', function () {
    Route::get('chart-of-accounts/{chart_of_account}/enable', 
    'ChartOfAccounts@enable')->name('chart-of-accounts.enable');
    Route::get('chart-of-accounts/{chart_of_account}/disable', 
    'ChartOfAccounts@disable')->name('chart-of-accounts.disable');
    Route::get('chart-of-accounts/{chart_of_account}/duplicate', 
    'ChartOfAccounts@duplicate')->name('chart-of-accounts.duplicate');
    Route::post('chart-of-accounts/import', 'ChartOfAccounts@import')- 
    >name('chart-of-accounts.import');
    Route::get('chart-of-accounts/export', 'ChartOfAccounts@export')- 
    >name('chart-of-accounts.export');
    Route::resource('chart-of-accounts', 'ChartOfAccounts');

    Route::get('journal-entry/{journal_entry}/duplicate', 
    'JournalEntry@duplicate')->name('journal-entry.duplicate');
    Route::post('journal-entry/import', 'JournalEntry@import')- 
    >name('journal-entry.import');
    Route::get('journal-entry/export', 'JournalEntry@export')- 
    >name('journal-entry.export');
    Route::get('journal-entry/{journal_entry}/print', 
    'JournalEntry@printJournalEntry')->name('journal-entry.print');
    Route::get('journal-entry/{journal_entry}/pdf', 
    'JournalEntry@pdfJournalEntry')->name('journal-entry.pdf');
    Route::resource('journal-entry', 'JournalEntry', ['middleware' => 
    ['double-entry-money']]);

    Route::get('settings', 'Settings@edit')->name('settings.edit');
    Route::post('settings', 'Settings@update')->name('settings.update');
});

I want to modify the above code to handle the APIs in my main api.php routes:

PHP
<?php

use Illuminate\Support\Facades\Route;

/**
 * 'api' middleware and prefix applied to all routes
 *
 * @see \App\Providers\Route::mapApiRoutes
 * @see \modules\DoubleEntry\Routes\admin.php
 */

Route::group(['as' => 'api.'], function () {
    // Ping
    Route::get('ping', 'Common\Ping@pong')->name('ping');

    // Users
    Route::get('users/{user}/enable', 
    'Auth\Users@enable')->name('users.enable');
    Route::get('users/{user}/disable', 
    'Auth\Users@disable')->name('users.disable');
    Route::apiResource('users', 'Auth\Users');

    // Companies
    Route::get('companies/{company}/owner', 
    'Common\Companies@canAccess')->name('companies.owner');
    Route::get('companies/{company}/enable', 
    'Common\Companies@enable')->name('companies.enable');
    Route::get('companies/{company}/disable', 
    'Common\Companies@disable')->name('companies.disable');
    Route::apiResource('companies', 'Common\Companies', 
           ['middleware' => ['dropzone']]);

    // Dashboards
    Route::get('dashboards/
    {dashboard}/enable', 'Common\Dashboards@enable')- 
    >name('dashboards.enable');
    Route::get('dashboards/{dashboard}/disable', 
    'Common\Dashboards@disable')->name('dashboards.disable');
    Route::apiResource('dashboards', 'Common\Dashboards');

    // Items
    Route::get('items/{item}/enable', 
    'Common\Items@enable')->name('items.enable');
    Route::get('items/{item}/disable', 
    'Common\Items@disable')->name('items.disable');
    Route::apiResource('items', 'Common\Items', 
    ['middleware' => ['dropzone']]);

    // Contacts
    Route::get('contacts/{contact}/enable', 
    'Common\Contacts@enable')->name('contacts.enable');
    Route::get('contacts/{contact}/disable', 
    'Common\Contacts@disable')->name('contacts.disable');
    Route::apiResource('contacts', 'Common\Contacts');

    // Documents
    Route::get('documents/{document}/received', 'Document\Documents@received')->name('documents.received');
    Route::apiResource('documents', 'Document\Documents', 
    ['middleware' => ['date.format', 'money', 'dropzone']]);
    Route::apiResource('documents.transactions', 
    'Document\DocumentTransactions', ['middleware' => 
    ['date.format', 'money', 'dropzone']]);

    // Accounts
    Route::get('accounts/{account}/enable', 
    'Banking\Accounts@enable')->name('accounts.enable');
    Route::get('accounts/{account}/disable', 
    'Banking\Accounts@disable')->name('accounts.disable');
    Route::apiResource('accounts', 'Banking\Accounts', 
    ['middleware' => ['date.format', 'money', 'dropzone']]);

    // Reconciliations
    Route::apiResource('reconciliations', 
    'Banking\Reconciliations', ['middleware' => 
    ['date.format', 'money', 'dropzone']]);

    // Transactions
    Route::apiResource('transactions', 'Banking\Transactions', 
    ['middleware' => ['date.format', 'money', 'dropzone']]);

    // Transfers
    Route::apiResource('transfers', 'Banking\Transfers', 
    ['middleware' => ['date.format', 'money', 'dropzone']]);

    // Reports
    Route::resource('reports', 'Common\Reports');

    // Categories
    Route::get('categories/{category}/enable', 
    'Settings\Categories@enable')->name('categories.enable');
    Route::get('categories/{category}/disable', 
    'Settings\Categories@disable')->name('categories.disable');
    Route::apiResource('categories', 'Settings\Categories');

    // Currencies
    Route::get('currencies/{currency}/enable', 
    'Settings\Currencies@enable')->name('currencies.enable');
    Route::get('currencies/{currency}/disable', 
    'Settings\Currencies@disable')->name('currencies.disable');
    Route::apiResource('currencies', 'Settings\Currencies');

    // Taxes
    Route::get('taxes/{tax}/enable', 
    'Settings\Taxes@enable')->name('taxes.enable');
    Route::get('taxes/{tax}/disable', 
    'Settings\Taxes@disable')->name('taxes.disable');
    Route::apiResource('taxes', 'Settings\Taxes');

    // Settings
    Route::apiResource('settings', 'Settings\Settings');

    // Translations
    Route::get('translations/{locale}/all', 
    'Common\Translations@all')->name('translations.all');
    Route::get('translations/{locale}/{file}', 
    'Common\Translations@file')->name('translations.file');
});


What I have tried:

Creating routes in the api.php file, but I get an error where the page displays 500 error
Posted
Updated 15-Aug-23 7:53am
v4
Comments
Richard Deeming 15-Aug-23 8:24am    
There's a secret error somewhere in your secret code. You should fix that.

Seriously, nobody can help you fix an error you can't describe in code we can't see running on a system we can't access.

Click the green "Improve question" link and update your question to include the relevant parts of your code, and the full details of the error.

NB: A "500" error just means "something went wrong". You need to check the logs on the server to find out what the actual error is.

1 solution

In your 'routes/api.php' file, you can change your existing code to handle the API's -
PHP
//Import the classes needed, I only used 2 as an example...
use Illuminate\Support\Facades\Route;
use Modules\DoubleEntry\Http\Controllers\ChartOfAccounts;

//Update the existing admin.php route definitions to match your new API structure...
Route::group(['prefix' => 'double-entry', 'as' => 'api.'], function () {
    Route::get('chart-of-accounts/{chart_of_account}/enable', [ChartOfAccounts::class, 'enable'])->name('chart-of-accounts.enable');
    Route::get('chart-of-accounts/{chart_of_account}/disable', [ChartOfAccounts::class, 'disable'])->name('chart-of-accounts.disable');
    //Add more routes as needed, only an example to help you going...
});


All your controller methods are already defined in your 'ChartOfAccounts' class, you don't need to rewrite them, you are just specifying which controller method should handle the respective API endpoint.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900