diff --git a/app/Console/Commands/TestOFX.php b/app/Console/Commands/TestOFX.php new file mode 100644 index 000000000000..637451fbba68 --- /dev/null +++ b/app/Console/Commands/TestOFX.php @@ -0,0 +1,30 @@ +bankAccountService = $bankAccountService; + } + + public function fire() + { + $this->info(date('Y-m-d').' Running TestOFX...'); + + $bankId = env('TEST_BANK_ID'); + $username = env('TEST_BANK_USERNAME'); + $password = env('TEST_BANK_PASSWORD'); + + $data = $this->bankAccountService->loadBankAccounts($bankId, $username, $password, false); + + print "
".print_r($data, 1).""; + } +} \ No newline at end of file diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 03b6ce776484..e281afb926d4 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -17,6 +17,7 @@ class Kernel extends ConsoleKernel 'App\Console\Commands\CheckData', 'App\Console\Commands\SendRenewalInvoices', 'App\Console\Commands\SendReminders', + 'App\Console\Commands\TestOFX', ]; /** diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index e77bdf0b23ce..ddf43bb33050 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -144,6 +144,8 @@ class AccountController extends BaseController return self::showLocalization(); } elseif ($section == ACCOUNT_PAYMENTS) { return self::showOnlinePayments(); + } elseif ($section == ACCOUNT_BANKS) { + return self::showBankAccounts(); } elseif ($section == ACCOUNT_INVOICE_SETTINGS) { return self::showInvoiceSettings(); } elseif ($section == ACCOUNT_IMPORT_EXPORT) { @@ -263,6 +265,21 @@ class AccountController extends BaseController return View::make('accounts.localization', $data); } + private function showBankAccounts() + { + $account = Auth::user()->account; + $account->load('bank_accounts'); + $count = count($account->bank_accounts); + + if ($count == 0) { + return Redirect::to('bank_accounts/create'); + } else { + return View::make('accounts.banks', [ + 'title' => trans('texts.bank_accounts') + ]); + } + } + private function showOnlinePayments() { $account = Auth::user()->account; diff --git a/app/Http/Controllers/BankAccountController.php b/app/Http/Controllers/BankAccountController.php new file mode 100644 index 000000000000..3b0f190ef1ec --- /dev/null +++ b/app/Http/Controllers/BankAccountController.php @@ -0,0 +1,152 @@ +bankAccountService = $bankAccountService; + } + + public function index() + { + return Redirect::to('settings/' . ACCOUNT_BANKS); + } + + public function getDatatable() + { + return $this->bankAccountService->getDatatable(Auth::user()->account_id); + } + + public function edit($publicId) + { + $bankAccount = BankAccount::scope($publicId)->firstOrFail(); + $bankAccount->username = str_repeat('*', 16); + + $data = [ + 'url' => 'bank_accounts/' . $publicId, + 'method' => 'PUT', + 'title' => trans('texts.edit_bank_account'), + 'banks' => Cache::get('banks'), + 'bankAccount' => $bankAccount, + ]; + + return View::make('accounts.bank_account', $data); + } + + public function update($publicId) + { + return $this->save($publicId); + } + + public function store() + { + return $this->save(); + } + + /** + * Displays the form for account creation + * + */ + public function create() + { + $data = [ + 'url' => 'bank_accounts', + 'method' => 'POST', + 'title' => trans('texts.add_bank_account'), + 'banks' => Cache::get('banks'), + 'bankAccount' => null, + ]; + + return View::make('accounts.bank_account', $data); + } + + public function bulk() + { + $action = Input::get('bulk_action'); + $ids = Input::get('bulk_public_id'); + $count = $this->bankAccountService->bulk($ids, $action); + + Session::flash('message', trans('texts.archived_bank_account')); + + return Redirect::to('settings/' . ACCOUNT_BANKS); + } + + /** + * Stores new account + * + */ + public function save($bankAccountPublicId = false) + { + $account = Auth::user()->account; + $bankId = Input::get('bank_id'); + $username = Input::get('bank_username'); + + $rules = [ + 'bank_id' => $bankAccountPublicId ? '' : 'required', + 'bank_username' => 'required', + ]; + + $validator = Validator::make(Input::all(), $rules); + + if ($validator->fails()) { + return Redirect::to('bank_accounts/create') + ->withErrors($validator) + ->withInput(); + } else { + if ($bankAccountPublicId) { + $bankAccount = BankAccount::scope($bankAccountPublicId)->firstOrFail(); + } else { + $bankAccount = BankAccount::createNew(); + $bankAccount->bank_id = $bankId; + } + + if ($username != str_repeat('*', strlen($username))) { + $bankAccount->username = Crypt::encrypt(trim($username)); + } + + if ($bankAccountPublicId) { + $bankAccount->save(); + $message = trans('texts.updated_bank_account'); + } else { + $account->bank_accounts()->save($bankAccount); + $message = trans('texts.created_bank_account'); + } + + Session::flash('message', $message); + return Redirect::to("bank_accounts/{$bankAccount->public_id}/edit"); + } + } + + public function test() + { + $bankId = Input::get('bank_id'); + $username = Input::get('bank_username'); + $password = Input::get('bank_password'); + + return json_encode($this->bankAccountService->loadBankAccounts($bankId, $username, $password, false)); + } + +} diff --git a/app/Http/Middleware/StartupCheck.php b/app/Http/Middleware/StartupCheck.php index e3ad3a6ba5fa..bfda7bcb4916 100644 --- a/app/Http/Middleware/StartupCheck.php +++ b/app/Http/Middleware/StartupCheck.php @@ -163,7 +163,7 @@ class StartupCheck $orderBy = 'num_days'; } elseif ($name == 'fonts') { $orderBy = 'sort_order'; - } elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries'])) { + } elseif (in_array($name, ['currencies', 'industries', 'languages', 'countries', 'banks'])) { $orderBy = 'name'; } else { $orderBy = 'id'; diff --git a/app/Http/routes.php b/app/Http/routes.php index 4381c4177dee..a5e903eb3cf8 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -132,6 +132,11 @@ Route::group(['middleware' => 'auth'], function() { Route::get('api/gateways', array('as'=>'api.gateways', 'uses'=>'AccountGatewayController@getDatatable')); Route::post('account_gateways/bulk', 'AccountGatewayController@bulk'); + Route::resource('bank_accounts', 'BankAccountController'); + Route::get('api/bank_accounts', array('as'=>'api.bank_accounts', 'uses'=>'BankAccountController@getDatatable')); + Route::post('bank_accounts/bulk', 'BankAccountController@bulk'); + Route::post('bank_accounts/test', 'BankAccountController@test'); + Route::resource('clients', 'ClientController'); Route::get('api/clients', array('as'=>'api.clients', 'uses'=>'ClientController@getDatatable')); Route::get('api/activities/{client_id?}', array('as'=>'api.activities', 'uses'=>'ActivityController@getDatatable')); @@ -253,6 +258,7 @@ if (!defined('CONTACT_EMAIL')) { define('ENTITY_QUOTE', 'quote'); define('ENTITY_TASK', 'task'); define('ENTITY_ACCOUNT_GATEWAY', 'account_gateway'); + define('ENTITY_BANK_ACCOUNT', 'bank_account'); define('ENTITY_USER', 'user'); define('ENTITY_TOKEN', 'token'); define('ENTITY_TAX_RATE', 'tax_rate'); @@ -271,6 +277,7 @@ if (!defined('CONTACT_EMAIL')) { define('ACCOUNT_NOTIFICATIONS', 'notifications'); define('ACCOUNT_IMPORT_EXPORT', 'import_export'); define('ACCOUNT_PAYMENTS', 'online_payments'); + define('ACCOUNT_BANKS', 'bank_accounts'); define('ACCOUNT_MAP', 'import_map'); define('ACCOUNT_EXPORT', 'export'); define('ACCOUNT_TAX_RATES', 'tax_rates'); @@ -518,6 +525,8 @@ if (!defined('CONTACT_EMAIL')) { define('EMAIL_DESIGN_LIGHT', 2); define('EMAIL_DESIGN_DARK', 3); + define('BANK_LIBRARY_OFX', 1); + $creditCards = [ 1 => ['card' => 'images/credit_cards/Test-Visa-Icon.png', 'text' => 'Visa'], 2 => ['card' => 'images/credit_cards/Test-MasterCard-Icon.png', 'text' => 'Master Card'], @@ -543,6 +552,7 @@ if (!defined('CONTACT_EMAIL')) { 'frequencies' => 'App\Models\Frequency', 'gateways' => 'App\Models\Gateway', 'fonts' => 'App\Models\Font', + 'banks' => 'App\Models\Bank', ]; define('CACHED_TABLES', serialize($cachedTables)); @@ -596,3 +606,4 @@ if (Auth::check() && Auth::user()->id === 1) Auth::loginUsingId(1); } */ + diff --git a/app/Libraries/OFX.php b/app/Libraries/OFX.php new file mode 100644 index 000000000000..734a27be30b5 --- /dev/null +++ b/app/Libraries/OFX.php @@ -0,0 +1,225 @@ +bank = $bank; + $this->request = $request; + } + public function go() + { + $c = curl_init(); + curl_setopt($c, CURLOPT_URL, $this->bank->url); + curl_setopt($c, CURLOPT_POST, 1); + curl_setopt($c, CURLOPT_HTTPHEADER, array('Content-Type: application/x-ofx')); + curl_setopt($c, CURLOPT_POSTFIELDS, $this->request); + curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); + //curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false); + $this->response = curl_exec($c); + curl_close($c); + $tmp = explode('