Working on the API

This commit is contained in:
Hillel Coren 2015-11-03 21:03:24 +02:00
parent ebd63f1805
commit 029e740a6c
12 changed files with 335 additions and 102 deletions

View File

@ -11,65 +11,63 @@ use App\Ninja\Repositories\AccountRepository;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use League\Fractal; use League\Fractal;
use League\Fractal\Resource\Item; use League\Fractal\Resource\Item;
use League\Fractal\Resource\Collection;
use League\Fractal\Manager; use League\Fractal\Manager;
use App\Ninja\Serializers\ArraySerializer; use App\Ninja\Serializers\ArraySerializer;
use App\Ninja\Transformers\AccountTransformer; use App\Ninja\Transformers\AccountTransformer;
use App\Ninja\Transformers\UserAccountTransformer;
use App\Http\Controllers\BaseAPIController;
class AccountApiController extends Controller class AccountApiController extends BaseAPIController
{ {
protected $accountRepo; protected $accountRepo;
public function __construct(AccountRepository $accountRepo) public function __construct(AccountRepository $accountRepo)
{ {
parent::__construct();
$this->accountRepo = $accountRepo; $this->accountRepo = $accountRepo;
} }
public function login(Request $request) public function login(Request $request)
{ {
if ( ! env(API_SECRET) || $request->api_secret !== env(API_SECRET)) { if ( ! env(API_SECRET) || $request->api_secret !== env(API_SECRET)) {
sleep(ERROR_DELAY);
return 'Invalid secret'; return 'Invalid secret';
} }
if (Auth::attempt(['email' => $request->email, 'password' => $request->password])) { if (Auth::attempt(['email' => $request->email, 'password' => $request->password])) {
return $this->processLogin($request); return $this->processLogin($request);
} else { } else {
sleep(ERROR_DELAY);
return 'Invalid credentials'; return 'Invalid credentials';
} }
} }
public function index()
{
$manager = new Manager();
$manager->setSerializer(new ArraySerializer());
$account = Auth::user()->account->load('users');
$resource = new Item($account, new AccountTransformer, 'account');
$response = $manager->createData($resource)->toArray();
$response = json_encode($response, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders();
return Response::make($response, 200, $headers);
}
private function processLogin(Request $request) private function processLogin(Request $request)
{ {
// Create a new token only if one does not already exist
$this->accountRepo->createTokens(Auth::user(), $request->token_name);
//Create a new token only if one does not already exist return $this->index();
$this->accountRepo->createToken('ios_api_token');
$manager = new Manager();
$manager->setSerializer(new ArraySerializer());
$account = Auth::user()->account->load('users','tokens');
$resource = new Item($account, new AccountTransformer, 'account');
$response = $manager->createData($resource)->toArray();
$response = json_encode($response, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders();
return Response::make($response, 200, $headers);
} }
public function index()
{
$users = $this->accountRepo->findUsers(Auth::user(), 'account.account_tokens');
$resource = new Collection($users, new UserAccountTransformer);
return $this->returnData($resource);
}
public function show($accountKey)
{
$account = $this->accountRepo->findByKey($accountKey);
$resource = new Item($account, new AccountTransformer);
return $this->returnData($resource);
}
} }

View File

@ -0,0 +1,28 @@
<?php namespace App\Http\Controllers;
use Utils;
use Response;
use League\Fractal;
use League\Fractal\Manager;
use App\Ninja\Serializers\ArraySerializer;
class BaseAPIController extends Controller
{
protected $manager;
public function __construct()
{
$this->manager = new Manager();
$this->manager->setSerializer(new ArraySerializer());
}
protected function returnData($resource)
{
$response = $this->manager->createData($resource)->toArray();
$response = json_encode($response, JSON_PRETTY_PRINT);
$headers = Utils::getApiHeaders();
return Response::make($response, 200, $headers);
}
}

View File

@ -192,6 +192,7 @@ Route::group(['middleware' => 'api', 'prefix' => 'api/v1'], function()
Route::resource('ping', 'ClientApiController@ping'); Route::resource('ping', 'ClientApiController@ping');
Route::post('login', 'AccountApiController@login'); Route::post('login', 'AccountApiController@login');
Route::get('accounts', 'AccountApiController@index'); Route::get('accounts', 'AccountApiController@index');
Route::get('accounts/{account_key}', 'AccountApiController@show');
Route::resource('clients', 'ClientApiController'); Route::resource('clients', 'ClientApiController');
Route::get('quotes/{client_id?}', 'QuoteApiController@index'); Route::get('quotes/{client_id?}', 'QuoteApiController@index');
Route::resource('quotes', 'QuoteApiController'); Route::resource('quotes', 'QuoteApiController');
@ -331,6 +332,7 @@ if (!defined('CONTACT_EMAIL')) {
define('MAX_NUM_CLIENTS_PRO', 20000); define('MAX_NUM_CLIENTS_PRO', 20000);
define('MAX_NUM_CLIENTS_LEGACY', 500); define('MAX_NUM_CLIENTS_LEGACY', 500);
define('LEGACY_CUTOFF', 57800); define('LEGACY_CUTOFF', 57800);
define('ERROR_DELAY', 3);
define('INVOICE_STATUS_DRAFT', 1); define('INVOICE_STATUS_DRAFT', 1);
define('INVOICE_STATUS_SENT', 2); define('INVOICE_STATUS_SENT', 2);

View File

@ -41,7 +41,7 @@ class Account extends Eloquent
'invoice_settings' => 'object', 'invoice_settings' => 'object',
]; ];
*/ */
public function tokens() public function account_tokens()
{ {
return $this->hasMany('App\Models\AccountToken'); return $this->hasMany('App\Models\AccountToken');
} }

View File

@ -236,6 +236,15 @@ class AccountRepository
return $client; return $client;
} }
public function findByKey($key)
{
$account = Account::whereAccountKey($key)
->with('clients.invoices.invoice_items', 'clients.contacts')
->firstOrFail();
return $account;
}
public function unlinkUserFromOauth($user) public function unlinkUserFromOauth($user)
{ {
$user->oauth_provider_id = null; $user->oauth_provider_id = null;
@ -301,6 +310,17 @@ class AccountRepository
->first(); ->first();
} }
public function findUsers($user, $with = null)
{
$accounts = $this->findUserAccounts($user->id);
if ($accounts) {
return $this->getUserAccounts($accounts, $with);
} else {
return [$user];
}
}
public function findUserAccounts($userId1, $userId2 = false) public function findUserAccounts($userId1, $userId2 = false)
{ {
if (!Schema::hasTable('user_accounts')) { if (!Schema::hasTable('user_accounts')) {
@ -324,7 +344,8 @@ class AccountRepository
return $query->first(['id', 'user_id1', 'user_id2', 'user_id3', 'user_id4', 'user_id5']); return $query->first(['id', 'user_id1', 'user_id2', 'user_id3', 'user_id4', 'user_id5']);
} }
public function prepareUsersData($record) { public function getUserAccounts($record, $with = null)
{
if (!$record) { if (!$record) {
return false; return false;
} }
@ -338,8 +359,18 @@ class AccountRepository
} }
$users = User::with('account') $users = User::with('account')
->whereIn('id', $userIds) ->whereIn('id', $userIds);
->get();
if ($with) {
$users->with($with);
}
return $users->get();
}
public function prepareUsersData($record)
{
$users = $this->getUserAccounts($record);
$data = []; $data = [];
foreach ($users as $user) { foreach ($users as $user) {
@ -457,19 +488,20 @@ class AccountRepository
return $code; return $code;
} }
public function createToken($name) public function createTokens($user, $name)
{ {
$name = trim($name) ?: 'TOKEN'; $name = trim($name) ?: 'TOKEN';
$users = $this->findUsers($user);
if ($token = AccountToken::scope()->whereName($name)->first()) { foreach ($users as $user) {
return $token; if ($token = AccountToken::whereUserId($user->id)->whereName($name)->first()) {
continue;
}
$token = AccountToken::createNew($user);
$token->name = $name;
$token->token = str_random(RANDOM_KEY_LENGTH);
$token->save();
} }
$token = AccountToken::createNew();
$token->name = $name;
$token->token = str_random(RANDOM_KEY_LENGTH);
$token->save();
return $token;
} }
} }

View File

@ -10,6 +10,7 @@ class ClientTransformer extends TransformerAbstract
protected $defaultIncludes = [ protected $defaultIncludes = [
'contacts', 'contacts',
'invoices', 'invoices',
'quotes',
]; ];
public function includeContacts($client) public function includeContacts($client)
@ -19,7 +20,20 @@ class ClientTransformer extends TransformerAbstract
public function includeInvoices($client) public function includeInvoices($client)
{ {
return $this->collection($client->invoices, new InvoiceTransformer); $invoices = $client->invoices->filter(function($invoice) {
return !$invoice->is_quote && !$invoice->is_recurring;
});
return $this->collection($invoices, new InvoiceTransformer);
}
public function includeQuotes($client)
{
$invoices = $client->invoices->filter(function($invoice) {
return $invoice->is_quote && !$invoice->is_recurring;
});
return $this->collection($invoices, new QuoteTransformer);
} }
public function transform(Client $client) public function transform(Client $client)

View File

@ -0,0 +1,26 @@
<?php namespace App\Ninja\Transformers;
use App\Models\Invoice;
use League\Fractal;
use League\Fractal\TransformerAbstract;
class QuoteTransformer extends TransformerAbstract
{
protected $defaultIncludes = [
'invoice_items',
];
public function includeInvoiceItems($invoice)
{
return $this->collection($invoice->invoice_items, new InvoiceItemTransformer);
}
public function transform(Invoice $invoice)
{
return [
'id' => (int) $invoice->public_id,
'quote_number' => $invoice->invoice_number,
'amount' => (float) $invoice->amount,
];
}
}

57
composer.lock generated
View File

@ -1,11 +1,10 @@
{ {
"_readme": [ "_readme": [
"This file locks the dependencies of your project to a known state", "This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"hash": "70ef9e09bca60a19c396c138d8a01d50", "hash": "d0f3825f6d361f655c7393dd024b676e",
"content-hash": "399b36f7735987d2daf3d182603354b3",
"packages": [ "packages": [
{ {
"name": "alfaproject/omnipay-neteller", "name": "alfaproject/omnipay-neteller",
@ -340,7 +339,7 @@
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/Chumper/Datatable/zipball/b44834db3d4e560d4368c1a04248b9e6a422ccff", "url": "https://api.github.com/repos/Chumper/Datatable/zipball/7fa47cb5469f07c620fb69dee94b8e1a96943ee2",
"reference": "7fa47cb", "reference": "7fa47cb",
"shasum": "" "shasum": ""
}, },
@ -352,7 +351,7 @@
}, },
"require-dev": { "require-dev": {
"mockery/mockery": "dev-master", "mockery/mockery": "dev-master",
"orchestra/testbench": "3.1.*", "orchestra/testbench": "2.1.*",
"phpunit/phpunit": "3.7.*" "phpunit/phpunit": "3.7.*"
}, },
"type": "library", "type": "library",
@ -381,7 +380,7 @@
"jquery", "jquery",
"laravel" "laravel"
], ],
"time": "2015-10-26 01:21:31" "time": "2015-04-20 09:21:21"
}, },
{ {
"name": "classpreloader/classpreloader", "name": "classpreloader/classpreloader",
@ -771,16 +770,16 @@
}, },
{ {
"name": "doctrine/cache", "name": "doctrine/cache",
"version": "v1.5.0", "version": "v1.5.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/cache.git", "url": "https://github.com/doctrine/cache.git",
"reference": "eb8a73619af4f1c8711e2ce482f5de3643258a1f" "reference": "2b9cec5a5e722010cbebc91713d4c11eaa064d5e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/eb8a73619af4f1c8711e2ce482f5de3643258a1f", "url": "https://api.github.com/repos/doctrine/cache/zipball/2b9cec5a5e722010cbebc91713d4c11eaa064d5e",
"reference": "eb8a73619af4f1c8711e2ce482f5de3643258a1f", "reference": "2b9cec5a5e722010cbebc91713d4c11eaa064d5e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -837,7 +836,7 @@
"cache", "cache",
"caching" "caching"
], ],
"time": "2015-10-28 11:27:45" "time": "2015-11-02 18:35:48"
}, },
{ {
"name": "doctrine/collections", "name": "doctrine/collections",
@ -1438,16 +1437,16 @@
}, },
{ {
"name": "guzzlehttp/psr7", "name": "guzzlehttp/psr7",
"version": "1.2.0", "version": "1.2.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/psr7.git", "url": "https://github.com/guzzle/psr7.git",
"reference": "4ef919b0cf3b1989523138b60163bbcb7ba1ff7e" "reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/4ef919b0cf3b1989523138b60163bbcb7ba1ff7e", "url": "https://api.github.com/repos/guzzle/psr7/zipball/4d0bdbe1206df7440219ce14c972aa57cc5e4982",
"reference": "4ef919b0cf3b1989523138b60163bbcb7ba1ff7e", "reference": "4d0bdbe1206df7440219ce14c972aa57cc5e4982",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1492,7 +1491,7 @@
"stream", "stream",
"uri" "uri"
], ],
"time": "2015-08-15 19:32:36" "time": "2015-11-03 01:34:55"
}, },
{ {
"name": "guzzlehttp/ringphp", "name": "guzzlehttp/ringphp",
@ -4944,12 +4943,12 @@
"target-dir": "Symfony/Component/Console", "target-dir": "Symfony/Component/Console",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/Console.git",
"reference": "0e5e18ae09d3f5c06367759be940e9ed3f568359" "reference": "0e5e18ae09d3f5c06367759be940e9ed3f568359"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/0e5e18ae09d3f5c06367759be940e9ed3f568359", "url": "https://api.github.com/repos/symfony/Console/zipball/0e5e18ae09d3f5c06367759be940e9ed3f568359",
"reference": "0e5e18ae09d3f5c06367759be940e9ed3f568359", "reference": "0e5e18ae09d3f5c06367759be940e9ed3f568359",
"shasum": "" "shasum": ""
}, },
@ -5002,12 +5001,12 @@
"target-dir": "Symfony/Component/Debug", "target-dir": "Symfony/Component/Debug",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/debug.git", "url": "https://github.com/symfony/Debug.git",
"reference": "fca5696e0c9787722baa8f2ad6940dfd7a6a6941" "reference": "fca5696e0c9787722baa8f2ad6940dfd7a6a6941"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/fca5696e0c9787722baa8f2ad6940dfd7a6a6941", "url": "https://api.github.com/repos/symfony/Debug/zipball/fca5696e0c9787722baa8f2ad6940dfd7a6a6941",
"reference": "fca5696e0c9787722baa8f2ad6940dfd7a6a6941", "reference": "fca5696e0c9787722baa8f2ad6940dfd7a6a6941",
"shasum": "" "shasum": ""
}, },
@ -5216,12 +5215,12 @@
"target-dir": "Symfony/Component/HttpFoundation", "target-dir": "Symfony/Component/HttpFoundation",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-foundation.git", "url": "https://github.com/symfony/HttpFoundation.git",
"reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c" "reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c", "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c",
"reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c", "reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c",
"shasum": "" "shasum": ""
}, },
@ -5270,12 +5269,12 @@
"target-dir": "Symfony/Component/HttpKernel", "target-dir": "Symfony/Component/HttpKernel",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-kernel.git", "url": "https://github.com/symfony/HttpKernel.git",
"reference": "a3f0ed713255c0400a2db38b3ed01989ef4b7322" "reference": "a3f0ed713255c0400a2db38b3ed01989ef4b7322"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/a3f0ed713255c0400a2db38b3ed01989ef4b7322", "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/a3f0ed713255c0400a2db38b3ed01989ef4b7322",
"reference": "a3f0ed713255c0400a2db38b3ed01989ef4b7322", "reference": "a3f0ed713255c0400a2db38b3ed01989ef4b7322",
"shasum": "" "shasum": ""
}, },
@ -6047,16 +6046,16 @@
}, },
{ {
"name": "facebook/webdriver", "name": "facebook/webdriver",
"version": "1.0.2", "version": "1.0.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/facebook/php-webdriver.git", "url": "https://github.com/facebook/php-webdriver.git",
"reference": "fe1bbbc5dde804d08a8593f1d9d0d3b05f5c84f5" "reference": "d843e33fd19b49db5ac9daaef2610079daab0bad"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/facebook/php-webdriver/zipball/fe1bbbc5dde804d08a8593f1d9d0d3b05f5c84f5", "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/d843e33fd19b49db5ac9daaef2610079daab0bad",
"reference": "fe1bbbc5dde804d08a8593f1d9d0d3b05f5c84f5", "reference": "d843e33fd19b49db5ac9daaef2610079daab0bad",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -6086,7 +6085,7 @@
"selenium", "selenium",
"webdriver" "webdriver"
], ],
"time": "2015-08-12 20:21:31" "time": "2015-11-01 20:09:34"
}, },
{ {
"name": "fzaninotto/faker", "name": "fzaninotto/faker",

View File

@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class ImproveCurrencyLocalization extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('countries', function ($table) {
$table->boolean('swap_currency_symbol')->default(0);
$table->string('thousand_separator')->nullable();
$table->string('decimal_separator')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('countries', function ($table) {
$table->dropColumn('swap_currency_symbol');
$table->dropColumn('thousand_separator');
$table->dropColumn('decimal_separator');
});
}
}

View File

@ -19,7 +19,7 @@ class PaymentLibrariesSeeder extends Seeder
$this->createDateFormats(); $this->createDateFormats();
$this->createDatetimeFormats(); $this->createDatetimeFormats();
$this->createInvoiceDesigns(); $this->createInvoiceDesigns();
$this->updateSwapPostalCode(); $this->updateLocalization();
} }
private function createGateways() { private function createGateways() {
@ -239,36 +239,132 @@ class PaymentLibrariesSeeder extends Seeder
} }
} }
private function updateSwapPostalCode() { private function updateLocalization() {
// Source: http://www.bitboost.com/ref/international-address-formats.html // Source: http://www.bitboost.com/ref/international-address-formats.html
// Source: https://en.wikipedia.org/wiki/Linguistic_issues_concerning_the_euro
$countries = [ $countries = [
'AR', 'AR' => [
'AT', 'swap_postal_code' => true,
'CH', ],
'BE', 'AT' => [
'DE', 'swap_postal_code' => true,
'DK', ],
'ES', 'BE' => [
'FI', 'swap_postal_code' => true,
'FR', ],
'GL', 'BG' => [ // Belgium
'IL', 'swap_currency_symbol' => true,
'IS', ],
'IT', 'CH' => [
'LU', 'swap_postal_code' => true,
'MY', ],
'MX', 'CZ' => [ // Czech Republic
'NL', 'swap_currency_symbol' => true,
'PL', ],
'PT', 'DE' => [ // Germany
'SE', 'swap_postal_code' => true,
'UY', 'swap_currency_symbol' => true,
],
'DK' => [
'swap_postal_code' => true,
],
'EE' => [ // Estonia
'swap_currency_symbol' => true,
],
'ES' => [ // Spain
'swap_postal_code' => true,
'swap_currency_symbol' => true,
],
'FI' => [ // Finland
'swap_postal_code' => true,
'swap_currency_symbol' => true,
],
'FR' => [ // France
'swap_postal_code' => true,
'swap_currency_symbol' => true,
],
'GR' => [ // Greece
'swap_currency_symbol' => true,
],
'HR' => [ // Croatia
'swap_currency_symbol' => true,
],
'HU' => [ // Hungary
'swap_currency_symbol' => true,
],
'GL' => [
'swap_postal_code' => true,
],
'IE' => [ // Ireland
'thousand_separator' => ',',
'decimal_separator' => '.',
],
'IL' => [
'swap_postal_code' => true,
],
'IS' => [ // Iceland
'swap_postal_code' => true,
'swap_currency_symbol' => true,
],
'IT' => [ // Italy
'swap_postal_code' => true,
'swap_currency_symbol' => true,
],
'LT' => [ // Lithuania
'swap_currency_symbol' => true,
],
'LU' => [
'swap_postal_code' => true,
],
'MY' => [
'swap_postal_code' => true,
],
'MX' => [
'swap_postal_code' => true,
],
'NL' => [
'swap_postal_code' => true,
],
'PL' => [ // Poland
'swap_postal_code' => true,
'swap_currency_symbol' => true,
],
'PT' => [ // Portugal
'swap_postal_code' => true,
'swap_currency_symbol' => true,
],
'RO' => [ // Romania
'swap_currency_symbol' => true,
],
'SE' => [ // Sweden
'swap_postal_code' => true,
'swap_currency_symbol' => true,
],
'SI' => [ // Slovenia
'swap_currency_symbol' => true,
],
'SK' => [ // Slovakia
'swap_currency_symbol' => true,
],
'UY' => [
'swap_postal_code' => true,
],
]; ];
for ($i=0; $i<count($countries); $i++) { foreach ($countries as $code => $data) {
$code = $countries[$i];
$country = Country::where('iso_3166_2', '=', $code)->first(); $country = Country::where('iso_3166_2', '=', $code)->first();
$country->swap_postal_code = true; if (isset($data['swap_postal_code'])) {
$country->swap_postal_code = true;
}
if (isset($data['swap_currency_symbol'])) {
$country->swap_currency_symbol = true;
}
if (isset($data['thousand_separator'])) {
$country->thousand_separator = $data['thousand_separator'];
}
if (isset($data['decimal_separator'])) {
$country->decimal_separator = $data['decimal_separator'];
}
$country->save(); $country->save();
} }
} }

View File

@ -15,7 +15,7 @@ class UserTableSeeder extends Seeder
$account = Account::create([ $account = Account::create([
'name' => 'Test Account', 'name' => 'Test Account',
'account_key' => str_random(16), 'account_key' => str_random(RANDOM_KEY_LENGTH),
'timezone_id' => 1, 'timezone_id' => 1,
]); ]);

View File

@ -131,7 +131,9 @@
<div class="bottom"> <div class="bottom">
<div class="wrap"> <div class="wrap">
<div class="copy">Copyright &copy;2015 <a href="{{ NINJA_WEB_URL }}" target="_blank">Invoice Ninja</a>. All rights reserved.</div> @if (!isset($hideLogo) || !$hideLogo)
<div class="copy">Copyright &copy;2015 <a href="{{ NINJA_WEB_URL }}" target="_blank">Invoice Ninja</a>. All rights reserved.</div>
@endif
</div><!-- .wrap --> </div><!-- .wrap -->
</div><!-- .bottom --> </div><!-- .bottom -->
</footer><!-- #footer --> </footer><!-- #footer -->