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
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;
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'));
}
public function show()
{
return redirect()->route('double-entry.chart-of-accounts.index');
}
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'));
}
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);
}
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);
}
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);
}
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'));
}
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);
}
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);
}
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);
}
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);
}
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
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
use Illuminate\Support\Facades\Route;
Route::group(['as' => 'api.'], function () {
Route::get('ping', 'Common\Ping@pong')->name('ping');
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');
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']]);
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');
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']]);
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');
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']]);
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']]);
Route::apiResource('reconciliations',
'Banking\Reconciliations', ['middleware' =>
['date.format', 'money', 'dropzone']]);
Route::apiResource('transactions', 'Banking\Transactions',
['middleware' => ['date.format', 'money', 'dropzone']]);
Route::apiResource('transfers', 'Banking\Transfers',
['middleware' => ['date.format', 'money', 'dropzone']]);
Route::resource('reports', 'Common\Reports');
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');
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');
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');
Route::apiResource('settings', 'Settings\Settings');
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