From 4ea6eb04dd64e843043b51f9230c32b4a30111cc Mon Sep 17 00:00:00 2001 From: David Bomba Date: Fri, 19 Feb 2016 08:30:52 +1100 Subject: [PATCH 001/220] merge --- .travis.yml | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9da900cd753f..94a69dc7696b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,14 +30,6 @@ before_install: install: # install Composer dependencies -<<<<<<< HEAD - - travis_retry composer update --prefer-dist; - -before_script: - # copy configuration files - - cp tests/_bootstrap.php.default tests/_bootstrap.php - - cp tests/.env.circleci .env -======= - rm composer.lock # these providers require referencing git commit's which cause Travis to fail - sed -i '/mollie/d' composer.json @@ -53,11 +45,7 @@ before_script: - php artisan key:generate --no-interaction - sed -i 's/APP_ENV=production/APP_ENV=development/g' .env - sed -i 's/APP_DEBUG=false/APP_DEBUG=true/g' .env -<<<<<<< HEAD ->>>>>>> upstream/develop -======= - sed -i 's/REQUIRE_HTTPS=false/NINJA_DEV=true/g' .env ->>>>>>> upstream/develop # create the database and user - mysql -u root -e "create database IF NOT EXISTS ninja;" - mysql -u root -e "GRANT ALL PRIVILEGES ON ninja.* To 'ninja'@'localhost' IDENTIFIED BY 'ninja'; FLUSH PRIVILEGES;" @@ -76,25 +64,22 @@ before_script: script: #- php ./vendor/codeception/codeception/codecept run --html --debug - #- php ./vendor/codeception/codeception/codecept run --debug acceptance AllPagesCept.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance APICest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance CheckBalanceCest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance ClientCest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance CreditCest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance InvoiceCest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance InvoiceDesignCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance AllPagesCept.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance APICest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance CheckBalanceCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance ClientCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance CreditCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance InvoiceCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance InvoiceDesignCest.php - php ./vendor/codeception/codeception/codecept run acceptance OnlinePaymentCest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance PaymentCest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance TaskCest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance TaxRatesCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance PaymentCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance TaskCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance TaxRatesCest.php #- php ./vendor/codeception/codeception/codecept run--debug acceptance GoProCest.php -<<<<<<< HEAD -======= after_script: - cat storage/logs/laravel.log ->>>>>>> upstream/develop notifications: email: on_success: never From 105321bdbb6ebc550d83a270016293fd35e4d83b Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Mon, 22 Feb 2016 19:47:19 +0200 Subject: [PATCH 002/220] Upgraded to Laravel 5.1 --- .travis.yml | 20 +- app/Http/Controllers/AppController.php | 2 +- app/Http/Controllers/Auth/AuthController.php | 30 +- .../Controllers/Auth/PasswordController.php | 7 +- app/Services/Registrar.php | 39 - bootstrap/autoload.php | 2 +- composer.json | 2 +- composer.lock | 793 +++++++----------- config/app.php | 3 +- 9 files changed, 334 insertions(+), 564 deletions(-) delete mode 100644 app/Services/Registrar.php diff --git a/.travis.yml b/.travis.yml index c7dd08d994c6..e3b0e7301e69 100644 --- a/.travis.yml +++ b/.travis.yml @@ -64,16 +64,16 @@ before_script: script: - php ./vendor/codeception/codeception/codecept run --debug acceptance AllPagesCept.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance APICest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance CheckBalanceCest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance ClientCest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance CreditCest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance InvoiceCest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance InvoiceDesignCest.php - #- php ./vendor/codeception/codeception/codecept run acceptance OnlinePaymentCest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance PaymentCest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance TaskCest.php - #- php ./vendor/codeception/codeception/codecept run --debug acceptance TaxRatesCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance APICest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance CheckBalanceCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance ClientCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance CreditCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance InvoiceCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance InvoiceDesignCest.php + - php ./vendor/codeception/codeception/codecept run acceptance OnlinePaymentCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance PaymentCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance TaskCest.php + - php ./vendor/codeception/codeception/codecept run --debug acceptance TaxRatesCest.php #- sed -i 's/NINJA_DEV=true/NINJA_PROD=true/g' .env #- php ./vendor/codeception/codeception/codecept run acceptance GoProCest.php diff --git a/app/Http/Controllers/AppController.php b/app/Http/Controllers/AppController.php index 606374a0d5de..126e2f395c27 100644 --- a/app/Http/Controllers/AppController.php +++ b/app/Http/Controllers/AppController.php @@ -243,6 +243,7 @@ class AppController extends BaseController if (!Utils::isNinjaProd()) { try { set_time_limit(60 * 5); + Artisan::call('optimize', array('--force' => true)); Cache::flush(); Session::flush(); Artisan::call('migrate', array('--force' => true)); @@ -254,7 +255,6 @@ class AppController extends BaseController ] as $seeder) { Artisan::call('db:seed', array('--force' => true, '--class' => "{$seeder}Seeder")); } - Artisan::call('optimize', array('--force' => true)); Event::fire(new UserSettingsChanged()); Session::flash('message', trans('texts.processed_updates')); } catch (Exception $e) { diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php index 5ed231cedc82..62bae4cbdd8f 100644 --- a/app/Http/Controllers/Auth/AuthController.php +++ b/app/Http/Controllers/Auth/AuthController.php @@ -10,8 +10,6 @@ use App\Events\UserLoggedIn; use App\Http\Controllers\Controller; use App\Ninja\Repositories\AccountRepository; use App\Services\AuthService; -use Illuminate\Contracts\Auth\Guard; -use Illuminate\Contracts\Auth\Registrar; use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers; class AuthController extends Controller { @@ -41,16 +39,38 @@ class AuthController extends Controller { * @param \Illuminate\Contracts\Auth\Registrar $registrar * @return void */ - public function __construct(Guard $auth, Registrar $registrar, AccountRepository $repo, AuthService $authService) + public function __construct(AccountRepository $repo, AuthService $authService) { - $this->auth = $auth; - $this->registrar = $registrar; $this->accountRepo = $repo; $this->authService = $authService; //$this->middleware('guest', ['except' => 'getLogout']); } + public function validator(array $data) + { + return Validator::make($data, [ + 'name' => 'required|max:255', + 'email' => 'required|email|max:255|unique:users', + 'password' => 'required|confirmed|min:6', + ]); + } + + /** + * Create a new user instance after a valid registration. + * + * @param array $data + * @return User + */ + public function create(array $data) + { + return User::create([ + 'name' => $data['name'], + 'email' => $data['email'], + 'password' => bcrypt($data['password']), + ]); + } + public function authLogin($provider, Request $request) { return $this->authService->execute($provider, $request->has('code')); diff --git a/app/Http/Controllers/Auth/PasswordController.php b/app/Http/Controllers/Auth/PasswordController.php index 3741a8157983..bd7d0bb0ef8b 100644 --- a/app/Http/Controllers/Auth/PasswordController.php +++ b/app/Http/Controllers/Auth/PasswordController.php @@ -1,8 +1,6 @@ auth = $auth; - $this->passwords = $passwords; - $this->middleware('guest'); } diff --git a/app/Services/Registrar.php b/app/Services/Registrar.php deleted file mode 100644 index cf19d6f4b70e..000000000000 --- a/app/Services/Registrar.php +++ /dev/null @@ -1,39 +0,0 @@ - 'required|max:255', - 'email' => 'required|email|max:255|unique:users', - 'password' => 'required|confirmed|min:6', - ]); - } - - /** - * Create a new user instance after a valid registration. - * - * @param array $data - * @return User - */ - public function create(array $data) - { - return User::create([ - 'name' => $data['name'], - 'email' => $data['email'], - 'password' => bcrypt($data['password']), - ]); - } - -} diff --git a/bootstrap/autoload.php b/bootstrap/autoload.php index f6387198c299..d1a406d25936 100644 --- a/bootstrap/autoload.php +++ b/bootstrap/autoload.php @@ -30,7 +30,7 @@ require __DIR__.'/../vendor/autoload.php'; | */ -$compiledPath = __DIR__.'/../vendor/compiled.php'; +$compiledPath = __DIR__.'/cache/compiled.php'; if (file_exists($compiledPath)) { diff --git a/composer.json b/composer.json index 68d48cd64803..fc27b248f684 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "omnipay/2checkout": "dev-master#e9c079c2dde0d7ba461903b3b7bd5caf6dee1248", "omnipay/gocardless": "dev-master", "omnipay/stripe": "2.3.0", - "laravel/framework": "5.0.*", + "laravel/framework": "5.1.*", "patricktalmadge/bootstrapper": "5.5.x", "anahkiasen/former": "4.0.*@dev", "barryvdh/laravel-debugbar": "~2.0.2", diff --git a/composer.lock b/composer.lock index 59574931678e..85106bb1336e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "fceb9a043eac244cb01d8e8378e6d66a", - "content-hash": "f717dc8e67caa65002f0f0689d4a5478", + "hash": "1cacd0ee0b218236e50fe5e72c863575", + "content-hash": "9addb5dadcabaeb89d182f1bebcd2137", "packages": [ { "name": "agmscode/omnipay-agms", @@ -637,35 +637,29 @@ }, { "name": "classpreloader/classpreloader", - "version": "1.4.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/ClassPreloader/ClassPreloader.git", - "reference": "b76f3f4f603ebbe7e64351a7ef973431ddaf7b27" + "reference": "9b10b913c2bdf90c3d2e0d726b454fb7f77c552a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/b76f3f4f603ebbe7e64351a7ef973431ddaf7b27", - "reference": "b76f3f4f603ebbe7e64351a7ef973431ddaf7b27", + "url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/9b10b913c2bdf90c3d2e0d726b454fb7f77c552a", + "reference": "9b10b913c2bdf90c3d2e0d726b454fb7f77c552a", "shasum": "" }, "require": { - "nikic/php-parser": "~1.3", - "php": ">=5.3.3", - "symfony/console": "~2.1", - "symfony/filesystem": "~2.1", - "symfony/finder": "~2.1" + "nikic/php-parser": "^1.0|^2.0", + "php": ">=5.5.9" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^4.8|^5.0" }, - "bin": [ - "classpreloader.php" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -684,7 +678,7 @@ }, { "name": "Graham Campbell", - "email": "graham@cachethq.io" + "email": "graham@alt-three.com" } ], "description": "Helps class loading performance by generating a single PHP file containing all of the autoloaded files for a specific use case", @@ -693,7 +687,7 @@ "class", "preload" ], - "time": "2015-05-26 10:57:51" + "time": "2015-11-09 22:51:51" }, { "name": "coatesap/omnipay-datacash", @@ -2143,16 +2137,16 @@ }, { "name": "guzzlehttp/psr7", - "version": "1.2.2", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb" + "reference": "2e89629ff057ebb49492ba08e6995d3a6a80021b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5d04bdd2881ac89abde1fb78cc234bce24327bb", - "reference": "f5d04bdd2881ac89abde1fb78cc234bce24327bb", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/2e89629ff057ebb49492ba08e6995d3a6a80021b", + "reference": "2e89629ff057ebb49492ba08e6995d3a6a80021b", "shasum": "" }, "require": { @@ -2197,7 +2191,7 @@ "stream", "uri" ], - "time": "2016-01-23 01:23:02" + "time": "2016-02-18 21:54:00" }, { "name": "illuminate/html", @@ -2362,48 +2356,6 @@ ], "time": "2016-01-10 11:20:02" }, - { - "name": "ircmaxell/password-compat", - "version": "v1.0.4", - "source": { - "type": "git", - "url": "https://github.com/ircmaxell/password_compat.git", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c", - "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c", - "shasum": "" - }, - "require-dev": { - "phpunit/phpunit": "4.*" - }, - "type": "library", - "autoload": { - "files": [ - "lib/password.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Anthony Ferrara", - "email": "ircmaxell@php.net", - "homepage": "http://blog.ircmaxell.com" - } - ], - "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash", - "homepage": "https://github.com/ircmaxell/password_compat", - "keywords": [ - "hashing", - "password" - ], - "time": "2014-11-20 16:49:30" - }, { "name": "jakub-onderka/php-console-color", "version": "0.1", @@ -2786,48 +2738,49 @@ }, { "name": "laravel/framework", - "version": "v5.0.35", + "version": "v5.1.30", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "37151cf533f468e2227605e4b9ac596154f6b92b" + "reference": "f00b80d4d33cf67815d1b4aaae8d4b47af2f2a2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/37151cf533f468e2227605e4b9ac596154f6b92b", - "reference": "37151cf533f468e2227605e4b9ac596154f6b92b", + "url": "https://api.github.com/repos/laravel/framework/zipball/f00b80d4d33cf67815d1b4aaae8d4b47af2f2a2a", + "reference": "f00b80d4d33cf67815d1b4aaae8d4b47af2f2a2a", "shasum": "" }, "require": { - "classpreloader/classpreloader": "~1.2", + "classpreloader/classpreloader": "~2.0|~3.0", "danielstjules/stringy": "~1.8", "doctrine/inflector": "~1.0", "ext-mbstring": "*", - "ext-mcrypt": "*", "ext-openssl": "*", - "ircmaxell/password-compat": "~1.0", "jeremeamia/superclosure": "~2.0", "league/flysystem": "~1.0", "monolog/monolog": "~1.11", "mtdowling/cron-expression": "~1.0", - "nesbot/carbon": "~1.0", - "php": ">=5.4.0", - "psy/psysh": "0.4.*", + "nesbot/carbon": "~1.19", + "paragonie/random_compat": "~1.1", + "php": ">=5.5.9", + "psy/psysh": "0.6.*", "swiftmailer/swiftmailer": "~5.1", - "symfony/console": "2.6.*", - "symfony/debug": "2.6.*", - "symfony/finder": "2.6.*", - "symfony/http-foundation": "2.6.*", - "symfony/http-kernel": "2.6.*", - "symfony/process": "2.6.*", - "symfony/routing": "2.6.*", - "symfony/security-core": "2.6.*", - "symfony/translation": "2.6.*", - "symfony/var-dumper": "2.6.*", + "symfony/console": "2.7.*", + "symfony/css-selector": "2.7.*", + "symfony/debug": "2.7.*", + "symfony/dom-crawler": "2.7.*", + "symfony/finder": "2.7.*", + "symfony/http-foundation": "2.7.*", + "symfony/http-kernel": "2.7.*", + "symfony/process": "2.7.*", + "symfony/routing": "2.7.*", + "symfony/translation": "2.7.*", + "symfony/var-dumper": "2.7.*", "vlucas/phpdotenv": "~1.0" }, "replace": { "illuminate/auth": "self.version", + "illuminate/broadcasting": "self.version", "illuminate/bus": "self.version", "illuminate/cache": "self.version", "illuminate/config": "self.version", @@ -2840,7 +2793,6 @@ "illuminate/events": "self.version", "illuminate/exception": "self.version", "illuminate/filesystem": "self.version", - "illuminate/foundation": "self.version", "illuminate/hashing": "self.version", "illuminate/http": "self.version", "illuminate/log": "self.version", @@ -2857,27 +2809,29 @@ "illuminate/view": "self.version" }, "require-dev": { - "aws/aws-sdk-php": "~2.4", - "iron-io/iron_mq": "~1.5", - "mockery/mockery": "~0.9", + "aws/aws-sdk-php": "~3.0", + "iron-io/iron_mq": "~2.0", + "mockery/mockery": "~0.9.2", "pda/pheanstalk": "~3.0", "phpunit/phpunit": "~4.0", "predis/predis": "~1.0" }, "suggest": { - "aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~2.4).", + "aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~3.0).", "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).", - "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers (~5.0).", - "iron-io/iron_mq": "Required to use the iron queue driver (~1.5).", - "league/flysystem-aws-s3-v2": "Required to use the Flysystem S3 driver (~1.0).", + "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).", + "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~5.3|~6.0).", + "iron-io/iron_mq": "Required to use the iron queue driver (~2.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).", "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0).", "pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).", - "predis/predis": "Required to use the redis cache and queue drivers (~1.0)." + "predis/predis": "Required to use the redis cache and queue drivers (~1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~2.0)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -2908,7 +2862,7 @@ "framework", "laravel" ], - "time": "2016-02-02 14:55:52" + "time": "2016-02-17 18:00:25" }, { "name": "laravel/socialite", @@ -2966,24 +2920,24 @@ }, { "name": "laravelcollective/html", - "version": "v5.0.4", + "version": "v5.1.9", "source": { "type": "git", "url": "https://github.com/LaravelCollective/html.git", - "reference": "c55fda58b1a9a1b58bd04f97e0fb9ebc238a0a94" + "reference": "f62269629b2a1093039733517bd7e75b3f98dffb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/LaravelCollective/html/zipball/c55fda58b1a9a1b58bd04f97e0fb9ebc238a0a94", - "reference": "c55fda58b1a9a1b58bd04f97e0fb9ebc238a0a94", + "url": "https://api.github.com/repos/LaravelCollective/html/zipball/f62269629b2a1093039733517bd7e75b3f98dffb", + "reference": "f62269629b2a1093039733517bd7e75b3f98dffb", "shasum": "" }, "require": { - "illuminate/http": "~5.0", - "illuminate/routing": "~5.0", - "illuminate/session": "~5.0", - "illuminate/support": "~5.0", - "php": ">=5.4.0" + "illuminate/http": "5.1.*", + "illuminate/routing": "5.1.*", + "illuminate/session": "5.1.*", + "illuminate/support": "5.1.*", + "php": ">=5.5.9" }, "require-dev": { "mockery/mockery": "~0.9", @@ -3012,20 +2966,20 @@ "email": "adam@laravelcollective.com" } ], - "time": "2015-05-06 14:23:37" + "time": "2015-11-28 08:27:09" }, { "name": "league/flysystem", - "version": "1.0.16", + "version": "1.0.17", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "183e1a610664baf6dcd6fceda415baf43cbdc031" + "reference": "02f5b6c9a8b9278c8381e3361e7bd9d641c740ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/183e1a610664baf6dcd6fceda415baf43cbdc031", - "reference": "183e1a610664baf6dcd6fceda415baf43cbdc031", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/02f5b6c9a8b9278c8381e3361e7bd9d641c740ca", + "reference": "02f5b6c9a8b9278c8381e3361e7bd9d641c740ca", "shasum": "" }, "require": { @@ -3038,8 +2992,7 @@ "ext-fileinfo": "*", "mockery/mockery": "~0.9", "phpspec/phpspec": "^2.2", - "phpspec/prophecy-phpunit": "~1.0", - "phpunit/phpunit": "~4.8" + "phpunit/phpunit": "~4.8 || ~5.0" }, "suggest": { "ext-fileinfo": "Required for MimeType", @@ -3096,7 +3049,7 @@ "sftp", "storage" ], - "time": "2015-12-19 20:16:43" + "time": "2016-02-19 15:35:38" }, { "name": "league/fractal", @@ -3792,32 +3745,38 @@ }, { "name": "nikic/php-parser", - "version": "v1.4.1", + "version": "v2.0.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51" + "reference": "c542e5d86a9775abd1021618eb2430278bfc1e01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51", - "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c542e5d86a9775abd1021618eb2430278bfc1e01", + "reference": "c542e5d86a9775abd1021618eb2430278bfc1e01", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=5.3" + "php": ">=5.4" }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "bin": [ + "bin/php-parse" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "2.0-dev" } }, "autoload": { - "files": [ - "lib/bootstrap.php" - ] + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3833,7 +3792,7 @@ "parser", "php" ], - "time": "2015-09-19 14:15:08" + "time": "2015-12-04 15:28:43" }, { "name": "omnipay/2checkout", @@ -4654,7 +4613,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/omnipay-mollie/zipball/a89cb0d15447023b24c03f86873c1c1489cd021b", + "url": "https://api.github.com/repos/thephpleague/omnipay-mollie/zipball/efd491fdac7d1243e2dd1da5a964514e3aab2a5a", "reference": "22956c1a62a9662afa5f5d119723b413770ac525", "shasum": "" }, @@ -5164,16 +5123,16 @@ }, { "name": "omnipay/paypal", - "version": "v2.5.1", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/thephpleague/omnipay-paypal.git", - "reference": "b546d24241725061d44e60516f0fbce202336963" + "reference": "2b3624b0d3f359c10c99b83c43f091ac397597b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/omnipay-paypal/zipball/b546d24241725061d44e60516f0fbce202336963", - "reference": "b546d24241725061d44e60516f0fbce202336963", + "url": "https://api.github.com/repos/thephpleague/omnipay-paypal/zipball/2b3624b0d3f359c10c99b83c43f091ac397597b9", + "reference": "2b3624b0d3f359c10c99b83c43f091ac397597b9", "shasum": "" }, "require": { @@ -5218,7 +5177,7 @@ "paypal", "purchase" ], - "time": "2016-01-13 07:03:27" + "time": "2016-02-16 00:01:31" }, { "name": "omnipay/pin", @@ -5866,28 +5825,29 @@ }, { "name": "psy/psysh", - "version": "v0.4.4", + "version": "v0.6.1", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "489816db71649bd95b416e3ed9062d40528ab0ac" + "reference": "0f04df0b23663799a8941fae13cd8e6299bde3ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/489816db71649bd95b416e3ed9062d40528ab0ac", - "reference": "489816db71649bd95b416e3ed9062d40528ab0ac", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/0f04df0b23663799a8941fae13cd8e6299bde3ed", + "reference": "0f04df0b23663799a8941fae13cd8e6299bde3ed", "shasum": "" }, "require": { "dnoegel/php-xdg-base-dir": "0.1", "jakub-onderka/php-console-highlighter": "0.3.*", - "nikic/php-parser": "~1.0", - "php": ">=5.3.0", - "symfony/console": "~2.3.10|~2.4.2|~2.5" + "nikic/php-parser": "^1.2.1|~2.0", + "php": ">=5.3.9", + "symfony/console": "~2.3.10|^2.4.2|~3.0", + "symfony/var-dumper": "~2.7|~3.0" }, "require-dev": { "fabpot/php-cs-fixer": "~1.5", - "phpunit/phpunit": "~3.7|~4.0", + "phpunit/phpunit": "~3.7|~4.0|~5.0", "squizlabs/php_codesniffer": "~2.0", "symfony/finder": "~2.1|~3.0" }, @@ -5903,15 +5863,15 @@ "type": "library", "extra": { "branch-alias": { - "dev-develop": "0.4.x-dev" + "dev-develop": "0.7.x-dev" } }, "autoload": { "files": [ "src/Psy/functions.php" ], - "psr-0": { - "Psy\\": "src/" + "psr-4": { + "Psy\\": "src/Psy/" } }, "notification-url": "https://packagist.org/downloads/", @@ -5933,7 +5893,7 @@ "interactive", "shell" ], - "time": "2015-03-26 18:43:54" + "time": "2015-11-12 16:18:56" }, { "name": "samvaughton/omnipay-barclays-epdq", @@ -6214,26 +6174,24 @@ }, { "name": "symfony/console", - "version": "v2.6.13", - "target-dir": "Symfony/Component/Console", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0e5e18ae09d3f5c06367759be940e9ed3f568359" + "reference": "d3fc138b6ed8f8074591821d3416d8f9c04d6ca6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0e5e18ae09d3f5c06367759be940e9ed3f568359", - "reference": "0e5e18ae09d3f5c06367759be940e9ed3f568359", + "url": "https://api.github.com/repos/symfony/console/zipball/d3fc138b6ed8f8074591821d3416d8f9c04d6ca6", + "reference": "d3fc138b6ed8f8074591821d3416d8f9c04d6ca6", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" }, "require-dev": { "psr/log": "~1.0", "symfony/event-dispatcher": "~2.1", - "symfony/phpunit-bridge": "~2.7", "symfony/process": "~2.1" }, "suggest": { @@ -6244,13 +6202,16 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Console\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6268,29 +6229,29 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2015-07-26 09:08:40" + "time": "2016-01-14 08:26:43" }, { "name": "symfony/css-selector", - "version": "v3.0.2", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "6605602690578496091ac20ec7a5cbd160d4dff4" + "reference": "1a869e59cc3b2802961fc2124139659e12b72fe5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/6605602690578496091ac20ec7a5cbd160d4dff4", - "reference": "6605602690578496091ac20ec7a5cbd160d4dff4", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/1a869e59cc3b2802961fc2124139659e12b72fe5", + "reference": "1a869e59cc3b2802961fc2124139659e12b72fe5", "shasum": "" }, "require": { - "php": ">=5.5.9" + "php": ">=5.3.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "2.7-dev" } }, "autoload": { @@ -6321,25 +6282,24 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2016-01-27 05:14:46" + "time": "2016-01-03 15:32:00" }, { "name": "symfony/debug", - "version": "v2.6.13", - "target-dir": "Symfony/Component/Debug", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "fca5696e0c9787722baa8f2ad6940dfd7a6a6941" + "reference": "5aca4aa9600b943287b4a1799a4d1d78b5388175" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/fca5696e0c9787722baa8f2ad6940dfd7a6a6941", - "reference": "fca5696e0c9787722baa8f2ad6940dfd7a6a6941", + "url": "https://api.github.com/repos/symfony/debug/zipball/5aca4aa9600b943287b4a1799a4d1d78b5388175", + "reference": "5aca4aa9600b943287b4a1799a4d1d78b5388175", "shasum": "" }, "require": { - "php": ">=5.3.3", + "php": ">=5.3.9", "psr/log": "~1.0" }, "conflict": { @@ -6347,24 +6307,21 @@ }, "require-dev": { "symfony/class-loader": "~2.2", - "symfony/http-foundation": "~2.1", - "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2", - "symfony/phpunit-bridge": "~2.7" - }, - "suggest": { - "symfony/http-foundation": "", - "symfony/http-kernel": "" + "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Debug\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6382,7 +6339,62 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2015-07-08 05:59:48" + "time": "2016-01-13 07:57:33" + }, + { + "name": "symfony/dom-crawler", + "version": "v2.7.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "55cc79a177193eb3bd74ac54b353691fbb211d3a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/55cc79a177193eb3bd74ac54b353691fbb211d3a", + "reference": "55cc79a177193eb3bd74ac54b353691fbb211d3a", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "symfony/css-selector": "~2.3" + }, + "suggest": { + "symfony/css-selector": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DomCrawler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DomCrawler Component", + "homepage": "https://symfony.com", + "time": "2016-01-03 15:32:00" }, { "name": "symfony/event-dispatcher", @@ -6445,17 +6457,17 @@ "time": "2016-01-13 10:28:07" }, { - "name": "symfony/filesystem", - "version": "v2.8.2", + "name": "symfony/finder", + "version": "v2.7.9", "source": { "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "637b64d0ee10f44ae98dbad651b1ecdf35a11e8c" + "url": "https://github.com/symfony/finder.git", + "reference": "d20ac81c81a67ab898b0c0afa435f3e9a7d460cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/637b64d0ee10f44ae98dbad651b1ecdf35a11e8c", - "reference": "637b64d0ee10f44ae98dbad651b1ecdf35a11e8c", + "url": "https://api.github.com/repos/symfony/finder/zipball/d20ac81c81a67ab898b0c0afa435f3e9a7d460cf", + "reference": "d20ac81c81a67ab898b0c0afa435f3e9a7d460cf", "shasum": "" }, "require": { @@ -6464,12 +6476,12 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.8-dev" + "dev-master": "2.7-dev" } }, "autoload": { "psr-4": { - "Symfony\\Component\\Filesystem\\": "" + "Symfony\\Component\\Finder\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -6489,94 +6501,45 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Filesystem Component", - "homepage": "https://symfony.com", - "time": "2016-01-13 10:28:07" - }, - { - "name": "symfony/finder", - "version": "v2.6.13", - "target-dir": "Symfony/Component/Finder", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "203a10f928ae30176deeba33512999233181dd28" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/203a10f928ae30176deeba33512999233181dd28", - "reference": "203a10f928ae30176deeba33512999233181dd28", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Finder\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2015-07-09 16:02:48" + "time": "2016-01-14 08:26:43" }, { "name": "symfony/http-foundation", - "version": "v2.6.13", - "target-dir": "Symfony/Component/HttpFoundation", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c" + "reference": "2f9d240056f026af5f7ba7f7052b0c6709bf288c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c", - "reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/2f9d240056f026af5f7ba7f7052b0c6709bf288c", + "reference": "2f9d240056f026af5f7ba7f7052b0c6709bf288c", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" }, "require-dev": { - "symfony/expression-language": "~2.4", - "symfony/phpunit-bridge": "~2.7" + "symfony/expression-language": "~2.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\HttpFoundation\\": "" }, "classmap": [ - "Symfony/Component/HttpFoundation/Resources/stubs" + "Resources/stubs" + ], + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -6595,41 +6558,42 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2015-07-22 10:08:40" + "time": "2016-01-13 10:26:43" }, { "name": "symfony/http-kernel", - "version": "v2.6.13", - "target-dir": "Symfony/Component/HttpKernel", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "cdd991d304fed833514dc44d6aafcf19397c26cb" + "reference": "aa2f1e544d6cb862452504b5479a5095b7bfc53f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/cdd991d304fed833514dc44d6aafcf19397c26cb", - "reference": "cdd991d304fed833514dc44d6aafcf19397c26cb", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/aa2f1e544d6cb862452504b5479a5095b7bfc53f", + "reference": "aa2f1e544d6cb862452504b5479a5095b7bfc53f", "shasum": "" }, "require": { - "php": ">=5.3.3", + "php": ">=5.3.9", "psr/log": "~1.0", "symfony/debug": "~2.6,>=2.6.2", "symfony/event-dispatcher": "~2.6,>=2.6.7", "symfony/http-foundation": "~2.5,>=2.5.4" }, + "conflict": { + "symfony/config": "<2.7" + }, "require-dev": { "symfony/browser-kit": "~2.3", "symfony/class-loader": "~2.1", - "symfony/config": "~2.0,>=2.0.5", + "symfony/config": "~2.7", "symfony/console": "~2.3", "symfony/css-selector": "~2.0,>=2.0.5", "symfony/dependency-injection": "~2.2", "symfony/dom-crawler": "~2.0,>=2.0.5", "symfony/expression-language": "~2.4", "symfony/finder": "~2.0,>=2.0.5", - "symfony/phpunit-bridge": "~2.7", "symfony/process": "~2.0,>=2.0.5", "symfony/routing": "~2.2", "symfony/stopwatch": "~2.3", @@ -6649,13 +6613,16 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\HttpKernel\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6673,7 +6640,7 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2016-01-14 10:11:16" + "time": "2016-01-14 10:41:45" }, { "name": "symfony/polyfill-php56", @@ -6785,35 +6752,34 @@ }, { "name": "symfony/process", - "version": "v2.6.13", - "target-dir": "Symfony/Component/Process", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "57f1e88bb5dafa449b83f9f265b11d52d517b3e9" + "reference": "0570b9ca51135ee7da0f19239eaf7b07ffb87034" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/57f1e88bb5dafa449b83f9f265b11d52d517b3e9", - "reference": "57f1e88bb5dafa449b83f9f265b11d52d517b3e9", + "url": "https://api.github.com/repos/symfony/process/zipball/0570b9ca51135ee7da0f19239eaf7b07ffb87034", + "reference": "0570b9ca51135ee7da0f19239eaf7b07ffb87034", "shasum": "" }, "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" + "php": ">=5.3.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Process\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6831,34 +6797,35 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2015-06-30 16:10:16" + "time": "2016-01-06 09:57:37" }, { "name": "symfony/routing", - "version": "v2.6.13", - "target-dir": "Symfony/Component/Routing", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "0a1764d41bbb54f3864808c50569ac382b44d128" + "reference": "6fec77993acfe19aecf60544b9c7d32f3d5b2506" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/0a1764d41bbb54f3864808c50569ac382b44d128", - "reference": "0a1764d41bbb54f3864808c50569ac382b44d128", + "url": "https://api.github.com/repos/symfony/routing/zipball/6fec77993acfe19aecf60544b9c7d32f3d5b2506", + "reference": "6fec77993acfe19aecf60544b9c7d32f3d5b2506", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" + }, + "conflict": { + "symfony/config": "<2.7" }, "require-dev": { "doctrine/annotations": "~1.0", "doctrine/common": "~2.2", "psr/log": "~1.0", - "symfony/config": "~2.2", + "symfony/config": "~2.7", "symfony/expression-language": "~2.4", "symfony/http-foundation": "~2.3", - "symfony/phpunit-bridge": "~2.7", "symfony/yaml": "~2.0,>=2.0.5" }, "suggest": { @@ -6870,13 +6837,16 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Routing\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6900,96 +6870,32 @@ "uri", "url" ], - "time": "2015-07-09 16:02:48" - }, - { - "name": "symfony/security-core", - "version": "v2.6.13", - "target-dir": "Symfony/Component/Security/Core", - "source": { - "type": "git", - "url": "https://github.com/symfony/security-core.git", - "reference": "813cf2aaacccbbe1a4705aef8d4ac0d79d993a76" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/813cf2aaacccbbe1a4705aef8d4ac0d79d993a76", - "reference": "813cf2aaacccbbe1a4705aef8d4ac0d79d993a76", - "shasum": "" - }, - "require": { - "paragonie/random_compat": "~1.0", - "php": ">=5.3.3" - }, - "require-dev": { - "ircmaxell/password-compat": "1.0.*", - "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1", - "symfony/expression-language": "~2.6", - "symfony/http-foundation": "~2.4", - "symfony/phpunit-bridge": "~2.7", - "symfony/translation": "~2.0,>=2.0.5", - "symfony/validator": "~2.5,>=2.5.5" - }, - "suggest": { - "ircmaxell/password-compat": "For using the BCrypt password encoder in PHP <5.5", - "symfony/event-dispatcher": "", - "symfony/expression-language": "For using the expression voter", - "symfony/http-foundation": "", - "symfony/validator": "For using the user password constraint" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Security\\Core\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Security Component - Core Library", - "homepage": "https://symfony.com", - "time": "2016-01-14 09:04:34" + "time": "2016-01-03 15:32:00" }, { "name": "symfony/translation", - "version": "v2.6.13", - "target-dir": "Symfony/Component/Translation", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "d84291215b5892834dd8ca8ee52f9cbdb8274904" + "reference": "8cbab8445ad4269427077ba02fff8718cb397e22" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/d84291215b5892834dd8ca8ee52f9cbdb8274904", - "reference": "d84291215b5892834dd8ca8ee52f9cbdb8274904", + "url": "https://api.github.com/repos/symfony/translation/zipball/8cbab8445ad4269427077ba02fff8718cb397e22", + "reference": "8cbab8445ad4269427077ba02fff8718cb397e22", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" + }, + "conflict": { + "symfony/config": "<2.7" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.3,>=2.3.12", - "symfony/intl": "~2.3", - "symfony/phpunit-bridge": "~2.7", + "symfony/config": "~2.7", + "symfony/intl": "~2.4", "symfony/yaml": "~2.2" }, "suggest": { @@ -7000,13 +6906,16 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Translation\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -7024,28 +6933,24 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2015-07-08 05:59:48" + "time": "2016-01-03 15:32:00" }, { "name": "symfony/var-dumper", - "version": "v2.6.13", - "target-dir": "Symfony/Component/VarDumper", + "version": "v2.7.9", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "5fba957a30161d8724aade093593cd22f815bea2" + "reference": "ad39199e91f2f845a0181b14d459fda13a622138" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/5fba957a30161d8724aade093593cd22f815bea2", - "reference": "5fba957a30161d8724aade093593cd22f815bea2", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/ad39199e91f2f845a0181b14d459fda13a622138", + "reference": "ad39199e91f2f845a0181b14d459fda13a622138", "shasum": "" }, "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" + "php": ">=5.3.9" }, "suggest": { "ext-symfony_debug": "" @@ -7053,16 +6958,19 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { "files": [ "Resources/functions/dump.php" ], - "psr-0": { + "psr-4": { "Symfony\\Component\\VarDumper\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -7084,7 +6992,7 @@ "debug", "dump" ], - "time": "2015-07-01 10:03:42" + "time": "2016-01-07 11:12:32" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -8707,25 +8615,25 @@ }, { "name": "symfony/browser-kit", - "version": "v3.0.2", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "dde849a0485b70a24b36f826ed3fb95b904d80c3" + "reference": "a93dffaf763182acad12a4c42c7efc372899891e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/dde849a0485b70a24b36f826ed3fb95b904d80c3", - "reference": "dde849a0485b70a24b36f826ed3fb95b904d80c3", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/a93dffaf763182acad12a4c42c7efc372899891e", + "reference": "a93dffaf763182acad12a4c42c7efc372899891e", "shasum": "" }, "require": { - "php": ">=5.5.9", - "symfony/dom-crawler": "~2.8|~3.0" + "php": ">=5.3.9", + "symfony/dom-crawler": "~2.0,>=2.0.5|~3.0.0" }, "require-dev": { - "symfony/css-selector": "~2.8|~3.0", - "symfony/process": "~2.8|~3.0" + "symfony/css-selector": "~2.0,>=2.0.5|~3.0.0", + "symfony/process": "~2.3.34|~2.7,>=2.7.6|~3.0.0" }, "suggest": { "symfony/process": "" @@ -8733,7 +8641,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -8760,122 +8668,7 @@ ], "description": "Symfony BrowserKit Component", "homepage": "https://symfony.com", - "time": "2016-01-27 11:34:55" - }, - { - "name": "symfony/dom-crawler", - "version": "v3.0.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/dom-crawler.git", - "reference": "b693a9650aa004576b593ff2e91ae749dc90123d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b693a9650aa004576b593ff2e91ae749dc90123d", - "reference": "b693a9650aa004576b593ff2e91ae749dc90123d", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "symfony/polyfill-mbstring": "~1.0" - }, - "require-dev": { - "symfony/css-selector": "~2.8|~3.0" - }, - "suggest": { - "symfony/css-selector": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\DomCrawler\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony DomCrawler Component", - "homepage": "https://symfony.com", - "time": "2016-01-25 09:56:57" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.1.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "1289d16209491b584839022f29257ad859b8532d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d", - "reference": "1289d16209491b584839022f29257ad859b8532d", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "time": "2016-01-20 09:13:37" + "time": "2016-01-12 17:46:01" }, { "name": "symfony/yaml", diff --git a/config/app.php b/config/app.php index cd55e8ee965a..dff5b99de6f0 100644 --- a/config/app.php +++ b/config/app.php @@ -137,7 +137,8 @@ return [ 'Illuminate\Translation\TranslationServiceProvider', 'Illuminate\Validation\ValidationServiceProvider', 'Illuminate\View\ViewServiceProvider', - + 'Illuminate\Broadcasting\BroadcastServiceProvider', + /* * Additional Providers */ From 2af155cdee57e00b0358b4d8ff6906ad23a0bc8e Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Mon, 22 Feb 2016 19:55:31 +0200 Subject: [PATCH 003/220] Upgraded to Laravel 5.1 --- bootstrap/cache/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100755 bootstrap/cache/.gitignore diff --git a/bootstrap/cache/.gitignore b/bootstrap/cache/.gitignore new file mode 100755 index 000000000000..d6b7ef32c847 --- /dev/null +++ b/bootstrap/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore From 826d1b868be3ea1a45fbdfa0e5f205649cf96fe0 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Mon, 22 Feb 2016 21:23:15 +0200 Subject: [PATCH 004/220] Enable auto renewing and updated Travis config --- .travis.yml | 24 +- app/Console/Commands/SendRenewalInvoices.php | 2 +- app/Console/Kernel.php | 1 + app/Libraries/Utils.php | 2 +- app/Listeners/SubscriptionListener.php | 20 ++ app/Ninja/Repositories/AccountRepository.php | 9 +- tests/_bootstrap.php.default | 2 +- .../_generated/AcceptanceTesterActions.php | 315 +++++++++++++----- tests/acceptance.suite.yml | 2 +- tests/functional.suite.yml | 2 +- 10 files changed, 276 insertions(+), 103 deletions(-) diff --git a/.travis.yml b/.travis.yml index e3b0e7301e69..bcfe155094b8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -54,26 +54,26 @@ before_script: - php artisan db:seed --no-interaction # default seed - php artisan db:seed --no-interaction --class=UserTableSeeder # development seed # Start webserver on ninja.dev:8000 - - php artisan serve --host=ninja.dev --port=8000 & # '&' allows to run in background + - php artisan serve --host=ninja.dev & # '&' allows to run in background # Start PhantomJS - phantomjs --webdriver=4444 & # '&' allows to run in background # Give it some time to start - sleep 5 # Make sure the app is up-to-date - - curl -L http://ninja.dev:8000/update + - curl -L http://ninja.dev/update script: - php ./vendor/codeception/codeception/codecept run --debug acceptance AllPagesCept.php - - php ./vendor/codeception/codeception/codecept run --debug acceptance APICest.php - - php ./vendor/codeception/codeception/codecept run --debug acceptance CheckBalanceCest.php - - php ./vendor/codeception/codeception/codecept run --debug acceptance ClientCest.php - - php ./vendor/codeception/codeception/codecept run --debug acceptance CreditCest.php - - php ./vendor/codeception/codeception/codecept run --debug acceptance InvoiceCest.php - - php ./vendor/codeception/codeception/codecept run --debug acceptance InvoiceDesignCest.php - - php ./vendor/codeception/codeception/codecept run acceptance OnlinePaymentCest.php - - php ./vendor/codeception/codeception/codecept run --debug acceptance PaymentCest.php - - php ./vendor/codeception/codeception/codecept run --debug acceptance TaskCest.php - - php ./vendor/codeception/codeception/codecept run --debug acceptance TaxRatesCest.php + #- php ./vendor/codeception/codeception/codecept run --debug acceptance APICest.php + #- php ./vendor/codeception/codeception/codecept run --debug acceptance CheckBalanceCest.php + #- php ./vendor/codeception/codeception/codecept run --debug acceptance ClientCest.php + #- php ./vendor/codeception/codeception/codecept run --debug acceptance CreditCest.php + #- php ./vendor/codeception/codeception/codecept run --debug acceptance InvoiceCest.php + #- php ./vendor/codeception/codeception/codecept run --debug acceptance InvoiceDesignCest.php + #- php ./vendor/codeception/codeception/codecept run acceptance OnlinePaymentCest.php + #- php ./vendor/codeception/codeception/codecept run --debug acceptance PaymentCest.php + #- php ./vendor/codeception/codeception/codecept run --debug acceptance TaskCest.php + #- php ./vendor/codeception/codeception/codecept run --debug acceptance TaxRatesCest.php #- sed -i 's/NINJA_DEV=true/NINJA_PROD=true/g' .env #- php ./vendor/codeception/codeception/codecept run acceptance GoProCest.php diff --git a/app/Console/Commands/SendRenewalInvoices.php b/app/Console/Commands/SendRenewalInvoices.php index 1e8ea1b49eb1..0faf1304a964 100644 --- a/app/Console/Commands/SendRenewalInvoices.php +++ b/app/Console/Commands/SendRenewalInvoices.php @@ -47,7 +47,7 @@ class SendRenewalInvoices extends Command } $client = $this->accountRepo->getNinjaClient($account); - $invitation = $this->accountRepo->createNinjaInvoice($client); + $invitation = $this->accountRepo->createNinjaInvoice($client, $account); // set the due date to 10 days from now $invoice = $invitation->invoice; diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index bd2720afa96f..d04eab9fad91 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -16,6 +16,7 @@ class Kernel extends ConsoleKernel 'App\Console\Commands\ResetData', 'App\Console\Commands\CheckData', 'App\Console\Commands\SendRenewalInvoices', + 'App\Console\Commands\ChargeRenewalInvoices', 'App\Console\Commands\SendReminders', 'App\Console\Commands\TestOFX', 'App\Console\Commands\GenerateResources', diff --git a/app/Libraries/Utils.php b/app/Libraries/Utils.php index 027f512a47df..340cfdfeba48 100644 --- a/app/Libraries/Utils.php +++ b/app/Libraries/Utils.php @@ -72,7 +72,7 @@ class Utils public static function requireHTTPS() { - if (Request::root() === 'http://ninja.dev:8000') { + if (Request::root() === 'http://ninja.dev') { return false; } diff --git a/app/Listeners/SubscriptionListener.php b/app/Listeners/SubscriptionListener.php index 2d12fcaeb953..0949e6de9c8c 100644 --- a/app/Listeners/SubscriptionListener.php +++ b/app/Listeners/SubscriptionListener.php @@ -24,29 +24,49 @@ class SubscriptionListener { public function createdClient(ClientWasCreated $event) { + if ( ! Auth::check()) { + return; + } + $transformer = new ClientTransformer(Auth::user()->account); $this->checkSubscriptions(ACTIVITY_TYPE_CREATE_CLIENT, $event->client, $transformer); } public function createdQuote(QuoteWasCreated $event) { + if ( ! Auth::check()) { + return; + } + $transformer = new InvoiceTransformer(Auth::user()->account); $this->checkSubscriptions(ACTIVITY_TYPE_CREATE_QUOTE, $event->quote, $transformer, ENTITY_CLIENT); } public function createdPayment(PaymentWasCreated $event) { + if ( ! Auth::check()) { + return; + } + $transformer = new PaymentTransformer(Auth::user()->account); $this->checkSubscriptions(ACTIVITY_TYPE_CREATE_PAYMENT, $event->payment, $transformer, [ENTITY_CLIENT, ENTITY_INVOICE]); } public function createdCredit(CreditWasCreated $event) { + if ( ! Auth::check()) { + return; + } + //$this->checkSubscriptions(ACTIVITY_TYPE_CREATE_CREDIT, $event->credit); } public function createdInvoice(InvoiceWasCreated $event) { + if ( ! Auth::check()) { + return; + } + $transformer = new InvoiceTransformer(Auth::user()->account); $this->checkSubscriptions(ACTIVITY_TYPE_CREATE_INVOICE, $event->invoice, $transformer, ENTITY_CLIENT); } diff --git a/app/Ninja/Repositories/AccountRepository.php b/app/Ninja/Repositories/AccountRepository.php index 2b469bf0fcf7..eab8ebd22794 100644 --- a/app/Ninja/Repositories/AccountRepository.php +++ b/app/Ninja/Repositories/AccountRepository.php @@ -124,13 +124,14 @@ class AccountRepository return false; } - $client = $this->getNinjaClient(Auth::user()->account); - $invitation = $this->createNinjaInvoice($client); + $account = Auth::user()->account; + $client = $this->getNinjaClient($account); + $invitation = $this->createNinjaInvoice($client, $account); return $invitation; } - public function createNinjaInvoice($client) + public function createNinjaInvoice($client, $account) { $account = $this->getNinjaAccount(); $lastInvoice = Invoice::withTrashed()->whereAccountId($account->id)->orderBy('public_id', 'DESC')->first(); @@ -142,7 +143,7 @@ class AccountRepository $invoice->public_id = $publicId; $invoice->client_id = $client->id; $invoice->invoice_number = $account->getNextInvoiceNumber($invoice); - $invoice->invoice_date = Auth::user()->account->getRenewalDate(); + $invoice->invoice_date = $account->getRenewalDate(); $invoice->amount = PRO_PLAN_PRICE; $invoice->balance = PRO_PLAN_PRICE; $invoice->save(); diff --git a/tests/_bootstrap.php.default b/tests/_bootstrap.php.default index 33ecdcb60782..2f520aacb010 100644 --- a/tests/_bootstrap.php.default +++ b/tests/_bootstrap.php.default @@ -2,7 +2,7 @@ // This is global bootstrap for autoloading use Codeception\Util\Fixtures; -Fixtures::add('url', 'http://ninja.dev:8000'); +Fixtures::add('url', 'http://ninja.dev'); Fixtures::add('username', 'user@example.com'); Fixtures::add('password', 'password'); diff --git a/tests/_support/_generated/AcceptanceTesterActions.php b/tests/_support/_generated/AcceptanceTesterActions.php index 3135d9aa0510..cebe7fff8f20 100644 --- a/tests/_support/_generated/AcceptanceTesterActions.php +++ b/tests/_support/_generated/AcceptanceTesterActions.php @@ -1,4 +1,4 @@ -getScenario()->runStep(new \Codeception\Step\Action('debugWebDriverLogs', func_get_args())); + } + + /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -166,7 +177,7 @@ trait AcceptanceTesterActions * [!] Method is generated. Documentation taken from corresponding module. * * Sets a cookie with the given name and value. - * You can set additional cookie params like `domain`, `path`, `expire`, `secure` in array passed as last argument. + * You can set additional cookie params like `domain`, `path`, `expires`, `secure` in array passed as last argument. * * ``` php * amOnPage('/'); * // opens /register page * $I->amOnPage('/register'); - * ?> * ``` * * @param $page @@ -263,16 +273,31 @@ trait AcceptanceTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Checks that the current page contains the given string. - * Specify a locator as the second parameter to match a specific region. + * Checks that the current page contains the given string (case insensitive). + * + * You can specify a specific HTML element (via CSS or XPath) as the second + * parameter to only search within that element. * * ``` php * see('Logout'); // I can suppose user is logged in - * $I->see('Sign Up','h1'); // I can suppose it's a signup page - * $I->see('Sign Up','//body/h1'); // with XPath - * ?> + * $I->see('Logout'); // I can suppose user is logged in + * $I->see('Sign Up', 'h1'); // I can suppose it's a signup page + * $I->see('Sign Up', '//body/h1'); // with XPath * ``` + * + * Note that the search is done after stripping all HTML tags from the body, + * so `$I->see('strong')` will return true for strings like: + * + * - `

I am Stronger than thou

` + * - `` + * + * But will *not* be true for strings like: + * + * - `Home` + * - `
Home` + * - `` + * + * For checking the raw source code, use `seeInSource()`. * * @param $text * @param null $selector @@ -285,16 +310,31 @@ trait AcceptanceTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Checks that the current page contains the given string. - * Specify a locator as the second parameter to match a specific region. + * Checks that the current page contains the given string (case insensitive). + * + * You can specify a specific HTML element (via CSS or XPath) as the second + * parameter to only search within that element. * * ``` php * see('Logout'); // I can suppose user is logged in - * $I->see('Sign Up','h1'); // I can suppose it's a signup page - * $I->see('Sign Up','//body/h1'); // with XPath - * ?> + * $I->see('Logout'); // I can suppose user is logged in + * $I->see('Sign Up', 'h1'); // I can suppose it's a signup page + * $I->see('Sign Up', '//body/h1'); // with XPath * ``` + * + * Note that the search is done after stripping all HTML tags from the body, + * so `$I->see('strong')` will return true for strings like: + * + * - `

I am Stronger than thou

` + * - `` + * + * But will *not* be true for strings like: + * + * - `Home` + * - `
Home` + * - `` + * + * For checking the raw source code, use `seeInSource()`. * * @param $text * @param null $selector @@ -308,16 +348,29 @@ trait AcceptanceTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Checks that the current page doesn't contain the text specified. + * Checks that the current page doesn't contain the text specified (case insensitive). * Give a locator as the second parameter to match a specific region. * * ```php * dontSee('Login'); // I can suppose user is already logged in - * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page - * $I->dontSee('Sign Up','//body/h1'); // with XPath - * ?> + * $I->dontSee('Login'); // I can suppose user is already logged in + * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page + * $I->dontSee('Sign Up','//body/h1'); // with XPath * ``` + * + * Note that the search is done after stripping all HTML tags from the body, + * so `$I->dontSee('strong')` will fail on strings like: + * + * - `

I am Stronger than thou

` + * - `` + * + * But will ignore strings like: + * + * - `Home` + * - `
Home` + * - `` + * + * For checking the raw source code, use `seeInSource()`. * * @param $text * @param null $selector @@ -330,16 +383,29 @@ trait AcceptanceTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Checks that the current page doesn't contain the text specified. + * Checks that the current page doesn't contain the text specified (case insensitive). * Give a locator as the second parameter to match a specific region. * * ```php * dontSee('Login'); // I can suppose user is already logged in - * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page - * $I->dontSee('Sign Up','//body/h1'); // with XPath - * ?> + * $I->dontSee('Login'); // I can suppose user is already logged in + * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page + * $I->dontSee('Sign Up','//body/h1'); // with XPath * ``` + * + * Note that the search is done after stripping all HTML tags from the body, + * so `$I->dontSee('strong')` will fail on strings like: + * + * - `

I am Stronger than thou

` + * - `` + * + * But will ignore strings like: + * + * - `Home` + * - `
Home` + * - `` + * + * For checking the raw source code, use `seeInSource()`. * * @param $text * @param null $selector @@ -350,6 +416,80 @@ trait AcceptanceTesterActions } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page contains the given string in its + * raw source code. + * + * ``` php + * seeInSource('

Green eggs & ham

'); + * ``` + * + * @param $raw + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\WebDriver::seeInSource() + */ + public function canSeeInSource($raw) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeInSource', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page contains the given string in its + * raw source code. + * + * ``` php + * seeInSource('

Green eggs & ham

'); + * ``` + * + * @param $raw + * @see \Codeception\Module\WebDriver::seeInSource() + */ + public function seeInSource($raw) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeInSource', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page contains the given string in its + * raw source code. + * + * ```php + * dontSeeInSource('

Green eggs & ham

'); + * ``` + * + * @param $raw + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\WebDriver::dontSeeInSource() + */ + public function cantSeeInSource($raw) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInSource', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page contains the given string in its + * raw source code. + * + * ```php + * dontSeeInSource('

Green eggs & ham

'); + * ``` + * + * @param $raw + * @see \Codeception\Module\WebDriver::dontSeeInSource() + */ + public function dontSeeInSource($raw) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeInSource', func_get_args())); + } + + /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -790,7 +930,6 @@ trait AcceptanceTesterActions * * @param null $uri * - * @internal param $url * @return mixed * @see \Codeception\Module\WebDriver::grabFromCurrentUrl() */ @@ -1388,7 +1527,7 @@ trait AcceptanceTesterActions * * @param $cssOrXpath * @param $attribute - * @internal param $element + * * @return mixed * @see \Codeception\Module\WebDriver::grabAttributeFrom() */ @@ -1425,7 +1564,28 @@ trait AcceptanceTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * + * Grabs either the text content, or attribute values, of nodes + * matched by $cssOrXpath and returns them as an array. + * + * ```html + * First + * Second + * Third + * ``` + * + * ```php + * grabMultiple('a'); + * + * // would return ['#first', '#second', '#third'] + * $aLinks = $I->grabMultiple('a', 'href'); + * ?> + * ``` + * + * @param $cssOrXpath + * @param $attribute + * @return string[] * @see \Codeception\Module\WebDriver::grabMultiple() */ public function grabMultiple($cssOrXpath, $attribute = null) { @@ -1640,6 +1800,27 @@ trait AcceptanceTesterActions } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\WebDriver::seeNumberOfElementsInDOM() + */ + public function canSeeNumberOfElementsInDOM($selector, $expected) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeNumberOfElementsInDOM', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * + * @see \Codeception\Module\WebDriver::seeNumberOfElementsInDOM() + */ + public function seeNumberOfElementsInDOM($selector, $expected) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeNumberOfElementsInDOM', func_get_args())); + } + + /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -1957,13 +2138,13 @@ trait AcceptanceTesterActions * ``` * Note that "2" will be the submitted value for the "plan" field, as it is * the selected option. - * + * * Also note that this differs from PhpBrowser, in that * ```'user' => [ 'login' => 'Davert' ]``` is not supported at the moment. * Named array keys *must* be included in the name as above. - * + * * Pair this with seeInFormFields for quick testing magic. - * + * * ``` php * submitForm('#my-form', [ * 'field[]' => 'value', * 'field[]' => 'another value', // 'field[]' is already a defined key * ]); * ``` - * + * * The solution is to pass an array value: - * + * * ```php * // this way both values are submitted * $I->submitForm('#my-form', [ @@ -2179,7 +2360,7 @@ trait AcceptanceTesterActions * If Codeception commands are not enough, this allows you to use Selenium WebDriver methods directly: * * ``` php - * $I->executeInSelenium(function(\Facebook\WebDriver\RemoteWebDriver $webdriver) { + * $I->executeInSelenium(function(\Facebook\WebDriver\Remote\RemoteWebDriver $webdriver) { * $webdriver->get('http://google.com'); * }); * ``` @@ -2222,7 +2403,7 @@ trait AcceptanceTesterActions * * ``` php * executeInSelenium(function (\Facebook\WebDriver\RemoteWebDriver $webdriver) { + * $I->executeInSelenium(function (\Facebook\WebDriver\Remote\RemoteWebDriver $webdriver) { * $handles=$webdriver->getWindowHandles(); * $last_window = end($handles); * $webdriver->switchTo()->window($last_window); @@ -2463,34 +2644,7 @@ trait AcceptanceTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Saves current cookies into named snapshot in order to restore them in other tests - * This is useful to save session state between tests. - * For example, if user needs log in to site for each test this scenario can be executed once - * while other tests can just restore saved cookies. - * - * ``` php - * loadSessionSnapshot('login')) return; - * - * // logging in - * $I->amOnPage('/login'); - * $I->fillField('name', 'jon'); - * $I->fillField('password', '123345'); - * $I->click('Login'); - * - * // saving snapshot - * $I->saveSessionSnapshot('login'); - * } - * ?> - * ``` - * - * @param $name - * @return mixed + * @param string $name * @see \Codeception\Module\WebDriver::saveSessionSnapshot() */ public function saveSessionSnapshot($name) { @@ -2501,11 +2655,8 @@ trait AcceptanceTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Loads cookies from saved snapshot. - * - * @param $name - * @see saveSessionSnapshot - * @return mixed + * @param string $name + * @return bool * @see \Codeception\Module\WebDriver::loadSessionSnapshot() */ public function loadSessionSnapshot($name) { @@ -2516,7 +2667,7 @@ trait AcceptanceTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Inserts SQL record into database. This record will be erased after the test. + * Inserts an SQL record into a database. This record will be erased after the test. * * ``` php * * ``` * - * @param int $num Expected number + * @param int $expectedNumber Expected number * @param string $table Table name * @param array $criteria Search criteria [Optional] * Conditional Assertion: Test won't be stopped on fail * @see \Codeception\Module\Db::seeNumRecords() */ - public function canSeeNumRecords($num, $table, $criteria = null) { + public function canSeeNumRecords($expectedNumber, $table, $criteria = null) { return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeNumRecords', func_get_args())); } /** * [!] Method is generated. Documentation taken from corresponding module. * - * Asserts that found number of records in database + * Asserts that the given number of records were found in the database. * * ``` php * * ``` * - * @param int $num Expected number + * @param int $expectedNumber Expected number * @param string $table Table name * @param array $criteria Search criteria [Optional] * @see \Codeception\Module\Db::seeNumRecords() */ - public function seeNumRecords($num, $table, $criteria = null) { + public function seeNumRecords($expectedNumber, $table, $criteria = null) { return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeNumRecords', func_get_args())); } @@ -2638,7 +2789,7 @@ trait AcceptanceTesterActions * * Effect is opposite to ->seeInDatabase * - * Checks if there is no record with such column values in database. + * Asserts that there is no record with the given column values in a database. * Provide table name and column values. * * Example: @@ -2668,7 +2819,7 @@ trait AcceptanceTesterActions * * Effect is opposite to ->seeInDatabase * - * Checks if there is no record with such column values in database. + * Asserts that there is no record with the given column values in a database. * Provide table name and column values. * * Example: diff --git a/tests/acceptance.suite.yml b/tests/acceptance.suite.yml index 05dcbc71eca7..293645697bef 100644 --- a/tests/acceptance.suite.yml +++ b/tests/acceptance.suite.yml @@ -8,7 +8,7 @@ class_name: AcceptanceTester modules: enabled: - WebDriver: - url: 'http://ninja.dev:8000/' + url: 'http://ninja.dev/' window_size: 1024x768 wait: 5 browser: firefox diff --git a/tests/functional.suite.yml b/tests/functional.suite.yml index b89e2023daba..7c84b1000840 100644 --- a/tests/functional.suite.yml +++ b/tests/functional.suite.yml @@ -9,7 +9,7 @@ modules: enabled: - \Helper\Functional - PhpBrowser: - url: 'http://ninja.dev:8000' + url: 'http://ninja.dev' curl: CURLOPT_RETURNTRANSFER: true - Laravel5: From e6141abde42a20849b58e314ed53f849b6fca5b9 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Mon, 22 Feb 2016 21:34:21 +0200 Subject: [PATCH 005/220] Enable auto renewing and updated Travis config --- .../Commands/ChargeRenewalInvoices.php | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 app/Console/Commands/ChargeRenewalInvoices.php diff --git a/app/Console/Commands/ChargeRenewalInvoices.php b/app/Console/Commands/ChargeRenewalInvoices.php new file mode 100644 index 000000000000..39d63ee44c06 --- /dev/null +++ b/app/Console/Commands/ChargeRenewalInvoices.php @@ -0,0 +1,63 @@ +mailer = $mailer; + $this->accountRepo = $repo; + $this->paymentService = $paymentService; + } + + public function fire() + { + $this->info(date('Y-m-d').' ChargeRenewalInvoices...'); + + $account = $this->accountRepo->getNinjaAccount(); + $invoices = Invoice::whereAccountId($account->id) + ->whereDueDate(date('Y-m-d')) + ->with('client') + ->orderBy('id') + ->get(); + + $this->info(count($invoices).' invoices found'); + + foreach ($invoices as $invoice) { + $this->info("Charging invoice {$invoice->invoice_number}"); + $this->paymentService->autoBillInvoice($invoice); + } + + $this->info('Done'); + } + + protected function getArguments() + { + return array( + //array('example', InputArgument::REQUIRED, 'An example argument.'), + ); + } + + protected function getOptions() + { + return array( + //array('example', null, InputOption::VALUE_OPTIONAL, 'An example option.', null), + ); + } +} From c9f38699d206a9086e60ac53a589c0eb3ada2172 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Mon, 22 Feb 2016 21:58:16 +0200 Subject: [PATCH 006/220] Updated Travis config --- .travis.yml | 4 ++-- app/Libraries/Utils.php | 2 +- tests/_bootstrap.php.default | 2 +- tests/acceptance.suite.yml | 2 +- tests/functional.suite.yml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index bcfe155094b8..c7dd08d994c6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -54,13 +54,13 @@ before_script: - php artisan db:seed --no-interaction # default seed - php artisan db:seed --no-interaction --class=UserTableSeeder # development seed # Start webserver on ninja.dev:8000 - - php artisan serve --host=ninja.dev & # '&' allows to run in background + - php artisan serve --host=ninja.dev --port=8000 & # '&' allows to run in background # Start PhantomJS - phantomjs --webdriver=4444 & # '&' allows to run in background # Give it some time to start - sleep 5 # Make sure the app is up-to-date - - curl -L http://ninja.dev/update + - curl -L http://ninja.dev:8000/update script: - php ./vendor/codeception/codeception/codecept run --debug acceptance AllPagesCept.php diff --git a/app/Libraries/Utils.php b/app/Libraries/Utils.php index 340cfdfeba48..027f512a47df 100644 --- a/app/Libraries/Utils.php +++ b/app/Libraries/Utils.php @@ -72,7 +72,7 @@ class Utils public static function requireHTTPS() { - if (Request::root() === 'http://ninja.dev') { + if (Request::root() === 'http://ninja.dev:8000') { return false; } diff --git a/tests/_bootstrap.php.default b/tests/_bootstrap.php.default index 2f520aacb010..33ecdcb60782 100644 --- a/tests/_bootstrap.php.default +++ b/tests/_bootstrap.php.default @@ -2,7 +2,7 @@ // This is global bootstrap for autoloading use Codeception\Util\Fixtures; -Fixtures::add('url', 'http://ninja.dev'); +Fixtures::add('url', 'http://ninja.dev:8000'); Fixtures::add('username', 'user@example.com'); Fixtures::add('password', 'password'); diff --git a/tests/acceptance.suite.yml b/tests/acceptance.suite.yml index 293645697bef..05dcbc71eca7 100644 --- a/tests/acceptance.suite.yml +++ b/tests/acceptance.suite.yml @@ -8,7 +8,7 @@ class_name: AcceptanceTester modules: enabled: - WebDriver: - url: 'http://ninja.dev/' + url: 'http://ninja.dev:8000/' window_size: 1024x768 wait: 5 browser: firefox diff --git a/tests/functional.suite.yml b/tests/functional.suite.yml index 7c84b1000840..b89e2023daba 100644 --- a/tests/functional.suite.yml +++ b/tests/functional.suite.yml @@ -9,7 +9,7 @@ modules: enabled: - \Helper\Functional - PhpBrowser: - url: 'http://ninja.dev' + url: 'http://ninja.dev:8000' curl: CURLOPT_RETURNTRANSFER: true - Laravel5: From 3ca89b2792361d00cd4c4b32fdfad43f14d58782 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Mon, 22 Feb 2016 23:23:28 +0200 Subject: [PATCH 007/220] Added navigation to search --- app/Ninja/Repositories/AccountRepository.php | 62 +++++++++++++++++++- resources/lang/en/texts.php | 16 ++++- resources/views/header.blade.php | 4 +- 3 files changed, 75 insertions(+), 7 deletions(-) diff --git a/app/Ninja/Repositories/AccountRepository.php b/app/Ninja/Repositories/AccountRepository.php index eab8ebd22794..3a2ea488e850 100644 --- a/app/Ninja/Repositories/AccountRepository.php +++ b/app/Ninja/Repositories/AccountRepository.php @@ -5,6 +5,7 @@ use Request; use Session; use Utils; use DB; +use URL; use stdClass; use Validator; use Schema; @@ -70,6 +71,16 @@ class AccountRepository } public function getSearchData() + { + $data = $this->getAccountSearchData(); + + $type = trans('texts.navigation'); + $data[$type] = $this->getNavigationSearchData(); + + return $data; + } + + private function getAccountSearchData() { $clients = \DB::table('clients') ->where('clients.deleted_at', '=', null) @@ -109,9 +120,56 @@ class AccountRepository $data[$type][] = [ 'value' => $row->name, - 'public_id' => $row->public_id, 'tokens' => $tokens, - 'entity_type' => $row->type, + 'url' => URL::to("/{$row->type}/{$row->public_id}"), + ]; + } + + return $data; + } + + private function getNavigationSearchData() + { + $features = [ + ['dashboard', '/dashboard'], + ['customize_design', '/settings/customize_design'], + ]; + + $entityTypes = [ + ENTITY_INVOICE, + ENTITY_CLIENT, + ENTITY_QUOTE, + ENTITY_TASK, + ENTITY_EXPENSE, + ENTITY_RECURRING_INVOICE, + ENTITY_PAYMENT, + ENTITY_CREDIT + ]; + + foreach ($entityTypes as $entityType) { + $features[] = [ + "new_{$entityType}", + "/{$entityType}s/create", + ]; + $features[] = [ + "list_{$entityType}s", + "/{$entityType}s", + ]; + } + + $settings = array_merge(Account::$basicSettings, Account::$advancedSettings); + + foreach ($settings as $setting) { + $features[] = [ + $setting, + "/settings/{$setting}", + ]; + } + + foreach ($features as $feature) { + $data[] = [ + 'value' => trans('texts.' . $feature[0]), + 'url' => URL::to($feature[1]) ]; } diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 0c9bfac16536..e063596ebc1d 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -122,8 +122,8 @@ $LANG = array( 'filter' => 'Filter', 'new_client' => 'New Client', 'new_invoice' => 'New Invoice', - 'new_payment' => 'Enter Payment', - 'new_credit' => 'Enter Credit', + 'new_payment' => 'New Payment', + 'new_credit' => 'New Credit', 'contact' => 'Contact', 'date_created' => 'Date Created', 'last_login' => 'Last Login', @@ -868,7 +868,7 @@ $LANG = array( 'white_label_purchase_link' => 'Purchase a white label license', 'expense' => 'Expense', 'expenses' => 'Expenses', - 'new_expense' => 'Enter Expense', + 'new_expense' => 'New Expense', 'enter_expense' => 'Enter Expense', 'vendors' => 'Vendors', 'new_vendor' => 'New Vendor', @@ -1028,6 +1028,16 @@ $LANG = array( 'user_unconfirmed' => 'Please confirm your account to send emails', 'invalid_contact_email' => 'Invalid contact email', ], + + 'navigation' => 'Navigation', + 'list_invoices' => 'List Invoices', + 'list_clients' => 'List Clients', + 'list_quotes' => 'List Quotes', + 'list_tasks' => 'List Tasks', + 'list_expensess' => 'List Expenses', + 'list_recurring_invoices' => 'List Recurring Invoices', + 'list_payments' => 'List Payments', + 'list_credits' => 'List Credits', ); return $LANG; diff --git a/resources/views/header.blade.php b/resources/views/header.blade.php index 7cadbb7a6a45..8b316660542a 100644 --- a/resources/views/header.blade.php +++ b/resources/views/header.blade.php @@ -268,6 +268,7 @@ } else { trackEvent('/activity', '/search'); $.get('{{ URL::route('getSearchData') }}', function(data) { + console.log(data); window.searchData = true; var datasets = []; for (var type in data) @@ -283,8 +284,7 @@ return; } $('#search').typeahead(datasets).on('typeahead:selected', function(element, datum, name) { - var type = name == 'Contacts' ? 'clients' : name.toLowerCase(); - window.location = '{{ URL::to('/') }}' + '/' + datum.entity_type + '/' + datum.public_id; + window.location = datum.url; }).focus().typeahead('setQuery', $('#search').val()); }); } From 1c864f4304198db03f5899992e7d9072d614eb86 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Tue, 23 Feb 2016 23:32:39 +0200 Subject: [PATCH 008/220] Added tax report --- app/Http/Controllers/ReportController.php | 361 +++++++++++------- app/Libraries/Utils.php | 6 +- app/Models/Client.php | 5 + app/Models/Invoice.php | 92 +++++ app/Ninja/Presenters/ClientPresenter.php | 4 + app/Ninja/Presenters/InvoicePresenter.php | 5 + resources/lang/en/texts.php | 2 + .../views/reports/chart_builder.blade.php | 74 ++-- 8 files changed, 374 insertions(+), 175 deletions(-) diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index 1757cb58501c..99fc922b09c9 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -10,6 +10,8 @@ use DatePeriod; use Session; use View; use App\Models\Account; +use App\Models\Client; +use App\Models\Payment; class ReportController extends BaseController { @@ -76,6 +78,7 @@ class ReportController extends BaseController ENTITY_CLIENT => trans('texts.client'), ENTITY_INVOICE => trans('texts.invoice'), ENTITY_PAYMENT => trans('texts.payment'), + ENTITY_TAX_RATE => trans('texts.taxes'), ]; $params = [ @@ -94,10 +97,11 @@ class ReportController extends BaseController if (Auth::user()->account->isPro()) { if ($enableReport) { - $params = array_merge($params, self::generateReport($reportType, $groupBy, $startDate, $endDate)); + $isExport = $action == 'export'; + $params = array_merge($params, self::generateReport($reportType, $startDate, $endDate, $isExport)); - if ($action == 'export') { - self::export($params['exportData'], $params['reportTotals']); + if ($isExport) { + self::export($params['displayData'], $params['columns'], $params['reportTotals']); } } if ($enableChart) { @@ -212,165 +216,258 @@ class ReportController extends BaseController ]; } - private function generateReport($reportType, $groupBy, $startDate, $endDate) + private function generateReport($reportType, $startDate, $endDate, $isExport) { if ($reportType == ENTITY_CLIENT) { - $columns = ['client', 'amount', 'paid', 'balance']; + return $this->generateClientReport($startDate, $endDate, $isExport); } elseif ($reportType == ENTITY_INVOICE) { - $columns = ['client', 'invoice_number', 'invoice_date', 'amount', 'paid', 'balance']; - } else { - $columns = ['client', 'invoice_number', 'invoice_date', 'amount', 'payment_date', 'paid', 'method']; + return $this->generateInvoiceReport($startDate, $endDate, $isExport); + } elseif ($reportType == ENTITY_PAYMENT) { + return $this->generatePaymentReport($startDate, $endDate, $isExport); + } elseif ($reportType == ENTITY_TAX_RATE) { + return $this->generateTaxRateReport($startDate, $endDate, $isExport); } + } - $query = DB::table('invoices') - ->join('accounts', 'accounts.id', '=', 'invoices.account_id') - ->join('clients', 'clients.id', '=', 'invoices.client_id') - ->join('contacts', 'contacts.client_id', '=', 'clients.id') - ->where('invoices.account_id', '=', Auth::user()->account_id) - ->where('invoices.is_deleted', '=', false) - ->where('clients.is_deleted', '=', false) - ->where('contacts.deleted_at', '=', null) - ->where('invoices.invoice_date', '>=', $startDate->format('Y-m-d')) - ->where('invoices.invoice_date', '<=', $endDate->format('Y-m-d')) - ->where('invoices.is_quote', '=', false) - ->where('invoices.is_recurring', '=', false) - ->where('contacts.is_primary', '=', true); + private function generateTaxRateReport($startDate, $endDate, $isExport) + { + $columns = ['tax_name', 'tax_rate', 'amount', 'paid']; - $select = [ - DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'), - 'accounts.country_id', - 'contacts.first_name', - 'contacts.last_name', - 'contacts.email', - 'clients.name as client_name', - 'clients.public_id as client_public_id', - 'invoices.public_id as invoice_public_id' - ]; - - if ($reportType == ENTITY_CLIENT) { - $query->groupBy('clients.id'); - array_push($select, DB::raw('sum(invoices.amount) amount'), DB::raw('sum(invoices.balance) balance'), DB::raw('sum(invoices.amount - invoices.balance) paid')); - } else { - $query->orderBy('invoices.id'); - array_push($select, 'invoices.invoice_number', 'invoices.amount', 'invoices.balance', 'invoices.invoice_date'); - if ($reportType == ENTITY_INVOICE) { - array_push($select, DB::raw('(invoices.amount - invoices.balance) paid')); - } else { - $query->join('payments', 'payments.invoice_id', '=', 'invoices.id') - ->leftJoin('payment_types', 'payment_types.id', '=', 'payments.payment_type_id') - ->leftJoin('account_gateways', 'account_gateways.id', '=', 'payments.account_gateway_id') - ->leftJoin('gateways', 'gateways.id', '=', 'account_gateways.gateway_id'); - array_push($select, 'payments.payment_date', 'payments.amount as paid', 'payment_types.name as payment_type', 'gateways.name as gateway'); - } - } - - $query->select($select); - $data = $query->get(); - - $lastInvoiceId = null; - $sameAsLast = false; + $account = Auth::user()->account; $displayData = []; + $reportTotals = []; - $exportData = []; - $reportTotals = [ - 'amount' => [], - 'balance' => [], - 'paid' => [], - ]; + $clients = Client::scope() + ->withTrashed() + ->with('contacts') + ->where('is_deleted', '=', false) + ->with(['invoices' => function($query) use ($startDate, $endDate) { + $query->where('invoice_date', '>=', $startDate) + ->where('invoice_date', '<=', $endDate) + ->where('is_deleted', '=', false) + ->withTrashed(); + }]); - foreach ($data as $record) { - $sameAsLast = ($lastInvoiceId == $record->invoice_public_id); - $lastInvoiceId = $record->invoice_public_id; + foreach ($clients->get() as $client) { + $currencyId = $client->currency_id ?: Auth::user()->account->getCurrencyId(); + $amount = 0; + $paid = 0; + $taxTotals = []; - $displayRow = []; - if ($sameAsLast) { - array_push($displayRow, '', '', '', ''); - } else { - array_push($displayRow, link_to('/clients/'.$record->client_public_id, Utils::getClientDisplayName($record))); - if ($reportType != ENTITY_CLIENT) { - array_push($displayRow, - link_to('/invoices/'.$record->invoice_public_id, $record->invoice_number), - Utils::fromSqlDate($record->invoice_date, true) - ); + foreach ($client->invoices as $invoice) { + foreach ($invoice->getTaxes() as $key => $tax) { + if ( ! isset($taxTotals[$currencyId])) { + $taxTotals[$currencyId] = []; + } + if (isset($taxTotals[$currencyId][$key])) { + $taxTotals[$currencyId][$key]['amount'] += $tax['amount']; + $taxTotals[$currencyId][$key]['paid'] += $tax['paid']; + } else { + $taxTotals[$currencyId][$key] = $tax; + } } - array_push($displayRow, Utils::formatMoney($record->amount, $record->currency_id, $record->country_id)); - } - if ($reportType != ENTITY_PAYMENT) { - array_push($displayRow, Utils::formatMoney($record->paid, $record->currency_id, $record->country_id)); - } - if ($reportType == ENTITY_PAYMENT) { - array_push($displayRow, - Utils::fromSqlDate($record->payment_date, true), - Utils::formatMoney($record->paid, $record->currency_id, $record->country_id), - $record->gateway ?: $record->payment_type - ); - } else { - array_push($displayRow, Utils::formatMoney($record->balance, $record->currency_id, $record->country_id)); + + $amount += $invoice->amount; + $paid += $invoice->getAmountPaid(); } - // export data - $exportRow = []; - if ($sameAsLast) { - $exportRow[trans('texts.client')] = ' '; - $exportRow[trans('texts.invoice_number')] = ' '; - $exportRow[trans('texts.invoice_date')] = ' '; - $exportRow[trans('texts.amount')] = ' '; - } else { - $exportRow[trans('texts.client')] = Utils::getClientDisplayName($record); - if ($reportType != ENTITY_CLIENT) { - $exportRow[trans('texts.invoice_number')] = $record->invoice_number; - $exportRow[trans('texts.invoice_date')] = Utils::fromSqlDate($record->invoice_date, true); + foreach ($taxTotals as $currencyId => $taxes) { + foreach ($taxes as $tax) { + $displayData[] = [ + $tax['name'], + $tax['rate'], + $account->formatMoney($tax['amount'], $client), + $account->formatMoney($tax['paid'], $client) + ]; } - $exportRow[trans('texts.amount')] = Utils::formatMoney($record->amount, $record->currency_id, $record->country_id); + + $reportTotals = $this->addToTotals($reportTotals, $client, 'amount', $tax['amount']); + $reportTotals = $this->addToTotals($reportTotals, $client, 'paid', $tax['paid']); } - if ($reportType != ENTITY_PAYMENT) { - $exportRow[trans('texts.paid')] = Utils::formatMoney($record->paid, $record->currency_id, $record->country_id); - } - if ($reportType == ENTITY_PAYMENT) { - $exportRow[trans('texts.payment_date')] = Utils::fromSqlDate($record->payment_date, true); - $exportRow[trans('texts.payment_amount')] = Utils::formatMoney($record->paid, $record->currency_id, $record->country_id); - $exportRow[trans('texts.method')] = $record->gateway ?: $record->payment_type; - } else { - $exportRow[trans('texts.balance')] = Utils::formatMoney($record->balance, $record->currency_id, $record->country_id); - } - - $displayData[] = $displayRow; - $exportData[] = $exportRow; - - $accountCurrencyId = Auth::user()->account->currency_id; - $currencyId = $record->currency_id ? $record->currency_id : ($accountCurrencyId ? $accountCurrencyId : DEFAULT_CURRENCY); - if (!isset($reportTotals['amount'][$currencyId])) { - $reportTotals['amount'][$currencyId] = 0; - $reportTotals['balance'][$currencyId] = 0; - $reportTotals['paid'][$currencyId] = 0; - } - if (!$sameAsLast) { - $reportTotals['amount'][$currencyId] += $record->amount; - $reportTotals['balance'][$currencyId] += $record->balance; - } - $reportTotals['paid'][$currencyId] += $record->paid; } return [ 'columns' => $columns, 'displayData' => $displayData, 'reportTotals' => $reportTotals, - 'exportData' => $exportData + ]; + + } + + private function generatePaymentReport($startDate, $endDate, $isExport) + { + $columns = ['client', 'invoice_number', 'invoice_date', 'amount', 'payment_date', 'paid', 'method']; + + $account = Auth::user()->account; + $displayData = []; + $reportTotals = []; + + $payments = Payment::scope() + ->withTrashed() + ->where('is_deleted', '=', false) + ->whereHas('client', function($query) { + $query->where('is_deleted', '=', false); + }) + ->whereHas('invoice', function($query) { + $query->where('is_deleted', '=', false); + }) + ->with('client.contacts', 'invoice', 'payment_type', 'account_gateway.gateway') + ->where('payment_date', '>=', $startDate) + ->where('payment_date', '<=', $endDate); + + foreach ($payments->get() as $payment) { + $invoice = $payment->invoice; + $client = $payment->client; + $displayData[] = [ + $isExport ? $client->getDisplayName() : $client->present()->link, + $isExport ? $invoice->invoice_number : $invoice->present()->link, + $invoice->present()->invoice_date, + $account->formatMoney($invoice->amount, $client), + $payment->present()->payment_date, + $account->formatMoney($payment->amount, $client), + $payment->present()->method, + ]; + + $reportTotals = $this->addToTotals($reportTotals, $client, 'amount', $invoice->amount); + $reportTotals = $this->addToTotals($reportTotals, $client, 'paid', $payment->amount); + } + + return [ + 'columns' => $columns, + 'displayData' => $displayData, + 'reportTotals' => $reportTotals, ]; } - private function export($data, $totals) + private function generateInvoiceReport($startDate, $endDate, $isExport) + { + $columns = ['client', 'invoice_number', 'invoice_date', 'amount', 'paid', 'balance']; + + $account = Auth::user()->account; + $displayData = []; + $reportTotals = []; + + $clients = Client::scope() + ->withTrashed() + ->with('contacts') + ->where('is_deleted', '=', false) + ->with(['invoices' => function($query) use ($startDate, $endDate) { + $query->where('invoice_date', '>=', $startDate) + ->where('invoice_date', '<=', $endDate) + ->where('is_deleted', '=', false) + ->with(['payments' => function($query) { + $query->withTrashed() + ->with('payment_type', 'account_gateway.gateway') + ->where('is_deleted', '=', false); + }, 'invoice_items']) + ->withTrashed(); + }]); + + foreach ($clients->get() as $client) { + $currencyId = $client->currency_id ?: Auth::user()->account->getCurrencyId(); + + foreach ($client->invoices as $invoice) { + $displayData[] = [ + $isExport ? $client->getDisplayName() : $client->present()->link, + $isExport ? $invoice->invoice_number : $invoice->present()->link, + $invoice->present()->invoice_date, + $account->formatMoney($invoice->amount, $client), + $account->formatMoney($invoice->getAmountPaid(), $client), + $account->formatMoney($invoice->balance, $client), + ]; + $reportTotals = $this->addToTotals($reportTotals, $client, 'amount', $invoice->amount); + $reportTotals = $this->addToTotals($reportTotals, $client, 'paid', $invoice->getAmountPaid()); + $reportTotals = $this->addToTotals($reportTotals, $client, 'balance', $invoice->balance); + } + } + + return [ + 'columns' => $columns, + 'displayData' => $displayData, + 'reportTotals' => $reportTotals, + ]; + } + + private function generateClientReport($startDate, $endDate, $isExport) + { + $columns = ['client', 'amount', 'paid', 'balance']; + + $account = Auth::user()->account; + $displayData = []; + $reportTotals = []; + + $clients = Client::scope() + ->withTrashed() + ->with('contacts') + ->where('is_deleted', '=', false) + ->with(['invoices' => function($query) use ($startDate, $endDate) { + $query->where('invoice_date', '>=', $startDate) + ->where('invoice_date', '<=', $endDate) + ->where('is_deleted', '=', false) + ->withTrashed(); + }]); + + foreach ($clients->get() as $client) { + $amount = 0; + $paid = 0; + + foreach ($client->invoices as $invoice) { + $amount += $invoice->amount; + $paid += $invoice->getAmountPaid(); + } + + $displayData[] = [ + $isExport ? $client->getDisplayName() : $client->present()->link, + $account->formatMoney($amount, $client), + $account->formatMoney($paid, $client), + $account->formatMoney($amount - $paid, $client) + ]; + + $reportTotals = $this->addToTotals($reportTotals, $client, 'amount', $amount); + $reportTotals = $this->addToTotals($reportTotals, $client, 'paid', $paid); + $reportTotals = $this->addToTotals($reportTotals, $client, 'balance', $amount - $paid); + } + + return [ + 'columns' => $columns, + 'displayData' => $displayData, + 'reportTotals' => $reportTotals, + ]; + } + + private function addToTotals($data, $client, $field, $value) { + $currencyId = $client->currency_id ?: Auth::user()->account->getCurrencyId(); + + if (!isset($data[$currencyId][$field])) { + $data[$currencyId][$field] = 0; + } + + $data[$currencyId][$field] += $value; + + return $data; + } + + private function export($data, $columns, $totals) { $output = fopen('php://output', 'w') or Utils::fatalError(); header('Content-Type:application/csv'); header('Content-Disposition:attachment;filename=ninja-report.csv'); - Utils::exportData($output, $data); + Utils::exportData($output, $data, Utils::trans($columns)); + + fwrite($output, trans('texts.totals')); + foreach ($totals as $currencyId => $fields) { + foreach ($fields as $key => $value) { + fwrite($output, ',' . trans("texts.{$key}")); + } + fwrite($output, "\n"); + break; + } - foreach (['amount', 'paid', 'balance'] as $type) { - $csv = trans("texts.{$type}").','; - foreach ($totals[$type] as $currencyId => $amount) { - $csv .= Utils::formatMoney($amount, $currencyId).','; + foreach ($totals as $currencyId => $fields) { + $csv = Utils::getFromCache($currencyId, 'currencies')->name . ','; + foreach ($fields as $key => $value) { + $csv .= '"' . Utils::formatMoney($value, $currencyId).'",'; } fwrite($output, $csv."\n"); } diff --git a/app/Libraries/Utils.php b/app/Libraries/Utils.php index 027f512a47df..14c3a6f2b802 100644 --- a/app/Libraries/Utils.php +++ b/app/Libraries/Utils.php @@ -767,9 +767,11 @@ class Utils return $str; } - public static function exportData($output, $data) + public static function exportData($output, $data, $headers = false) { - if (count($data) > 0) { + if ($headers) { + fputcsv($output, $headers); + } elseif (count($data) > 0) { fputcsv($output, array_keys($data[0])); } diff --git a/app/Models/Client.php b/app/Models/Client.php index 2167af0ddfc6..61194fe93cef 100644 --- a/app/Models/Client.php +++ b/app/Models/Client.php @@ -272,6 +272,11 @@ class Client extends EntityModel return $token ? "https://dashboard.stripe.com/customers/{$token}" : false; } + public function getAmount() + { + return $this->balance + $this->paid_to_date; + } + public function getCurrencyId() { if ($this->currency_id) { diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 4e15934efeb3..6bb1ff9408e8 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -752,6 +752,98 @@ class Invoice extends EntityModel implements BalanceAffecting return Utils::decodePDF($pdfString); } + + public function getItemTaxable($invoiceItem, $invoiceTotal) + { + $total = $invoiceItem->qty * $invoiceItem->cost; + + if ($this->discount > 0) { + if ($this->is_amount_discount) { + $total -= $invoiceTotal ? ($total / $invoiceTotal * $this->discount) : 0; + } else { + $total *= (100 - $this->discount) / 100; + $total = round($total, 2); + } + } + + return $total; + } + + public function getTaxable() + { + $total = 0; + + foreach ($this->invoice_items as $invoiceItem) { + $total += $invoiceItem->qty * $invoiceItem->cost; + } + + if ($this->discount > 0) { + if ($this->is_amount_discount) { + $total -= $this->discount; + } else { + $total *= (100 - $this->discount) / 100; + $total = round($total, 2); + } + } + + if ($this->custom_value1 && $this->custom_taxes1) { + $total += $this->custom_value1; + } + + if ($this->custom_value2 && $this->custom_taxes2) { + $total += $this->custom_value2; + } + + return $total; + } + + public function getTaxes() + { + $taxes = []; + $taxable = $this->getTaxable(); + + if ($this->tax_rate && $this->tax_name) { + $taxAmount = $taxable * ($this->tax_rate / 100); + $taxAmount = round($taxAmount, 2); + + if ($taxAmount) { + $taxes[$this->tax_name.$this->tax_rate] = [ + 'name' => $this->tax_name, + 'rate' => $this->tax_rate, + 'amount' => $taxAmount, + 'paid' => $this->getAmountPaid() / $this->amount * $taxAmount + ]; + } + } + + foreach ($this->invoice_items as $invoiceItem) { + if ( ! $invoiceItem->tax_rate || ! $invoiceItem->tax_name) { + continue; + } + + $taxAmount = $this->getItemTaxable($invoiceItem, $taxable); + $taxAmount = $taxable * ($invoiceItem->tax_rate / 100); + $taxAmount = round($taxAmount, 2); + + if ($taxAmount) { + $key = $invoiceItem->tax_name.$invoiceItem->tax_rate; + + if ( ! isset($taxes[$key])) { + $taxes[$key] = [ + 'amount' => 0, + 'paid' => 0 + ]; + } + + $taxes[$key]['amount'] += $taxAmount; + $taxes[$key]['paid'] += $this->amount && $taxAmount ? ($this->getAmountPaid() / $this->amount * $taxAmount) : 0; + $taxes[$key]['name'] = $invoiceItem->tax_name; + $taxes[$key]['rate'] = $invoiceItem->tax_rate; + } + } + + return $taxes; + } } Invoice::creating(function ($invoice) { diff --git a/app/Ninja/Presenters/ClientPresenter.php b/app/Ninja/Presenters/ClientPresenter.php index 97551185d514..cd32151a3752 100644 --- a/app/Ninja/Presenters/ClientPresenter.php +++ b/app/Ninja/Presenters/ClientPresenter.php @@ -26,6 +26,10 @@ class ClientPresenter extends Presenter { } return "{$text}"; + } + public function link() + { + return link_to('/clients/' . $this->entity->public_id, $this->entity->getDisplayName()); } } \ No newline at end of file diff --git a/app/Ninja/Presenters/InvoicePresenter.php b/app/Ninja/Presenters/InvoicePresenter.php index fb292a8859b9..2bab049d2a31 100644 --- a/app/Ninja/Presenters/InvoicePresenter.php +++ b/app/Ninja/Presenters/InvoicePresenter.php @@ -55,4 +55,9 @@ class InvoicePresenter extends Presenter { return Utils::fromSqlDate($this->entity->due_date); } + public function link() + { + return link_to('/invoices/' . $this->entity->public_id, $this->entity->invoice_number); + } + } \ No newline at end of file diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index e063596ebc1d..bb236d904cd6 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -1038,6 +1038,8 @@ $LANG = array( 'list_recurring_invoices' => 'List Recurring Invoices', 'list_payments' => 'List Payments', 'list_credits' => 'List Credits', + 'tax_name' => 'Tax Name', + ); return $LANG; diff --git a/resources/views/reports/chart_builder.blade.php b/resources/views/reports/chart_builder.blade.php index 159b71b177bd..d0beac93a3b0 100644 --- a/resources/views/reports/chart_builder.blade.php +++ b/resources/views/reports/chart_builder.blade.php @@ -54,12 +54,12 @@ @endif -
+
- {!! Former::checkbox('enable_report')->text(trans('texts.enable')) !!} - {!! Former::select('report_type')->options($reportTypes, $reportType)->label(trans('texts.group_by')) !!} + {!! Former::checkbox('enable_report')->text(trans('texts.enable')) !!} + {!! Former::select('report_type')->options($reportTypes, $reportType)->label(trans('texts.type')) !!}

 

- {!! Former::checkbox('enable_chart')->text(trans('texts.enable')) !!} + {!! Former::checkbox('enable_chart')->text(trans('texts.enable')) !!} {!! Former::select('group_by')->options($dateTypes, $groupBy) !!} {!! Former::select('chart_type')->options($chartTypes, $chartType) !!} @@ -77,56 +77,48 @@ @foreach ($columns as $column) - - {{ trans("texts.{$column}") }} - + {{ trans("texts.{$column}") }} @endforeach - + @foreach ($displayData as $record) @foreach ($record as $field) - - {!! $field !!} - + {!! $field !!} @endforeach @endforeach - - - {{ trans('texts.totals') }} - @if ($reportType != ENTITY_CLIENT) - - - @endif - - @foreach ($reportTotals['amount'] as $currencyId => $total) - {{ Utils::formatMoney($total, $currencyId) }}
- @endforeach - - @if ($reportType == ENTITY_PAYMENT) - - @endif - - @foreach ($reportTotals['paid'] as $currencyId => $total) - {{ Utils::formatMoney($total, $currencyId) }}
- @endforeach - - @if ($reportType != ENTITY_PAYMENT) - - @foreach ($reportTotals['balance'] as $currencyId => $total) - {{ Utils::formatMoney($total, $currencyId) }}
- @endforeach - - @endif - - +

 

+ + @if (count(array_values($reportTotals))) + + + + + @foreach (array_values($reportTotals)[0] as $key => $val) + + @endforeach + + + + @foreach ($reportTotals as $currencyId => $val) + + + @foreach ($val as $id => $field) + + @endforeach + + @endforeach + +
{{ trans("texts.totals") }}{{ trans("texts.{$key}") }}
{!! Utils::getFromCache($currencyId, 'currencies')->name !!}{!! Utils::formatMoney($field, $currencyId) !!}
+ @endif + +
-
@endif @if ($enableChart) From a1d13cc84cab863d18e2e269b5fb95f7850eae19 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 24 Feb 2016 22:58:42 +0200 Subject: [PATCH 009/220] Improvements to the tax report --- app/Http/Controllers/ReportController.php | 39 ++++++++++++------- app/Http/routes.php | 4 ++ app/Models/EntityModel.php | 5 +++ app/Models/Invoice.php | 18 ++++++--- app/Ninja/Repositories/AccountRepository.php | 11 +++--- app/Providers/AppServiceProvider.php | 5 --- resources/lang/en/texts.php | 7 +++- resources/views/header.blade.php | 2 +- .../views/reports/chart_builder.blade.php | 16 +++++++- 9 files changed, 76 insertions(+), 31 deletions(-) diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index 99fc922b09c9..6ef53ffc6ebe 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -49,6 +49,7 @@ class ReportController extends BaseController $groupBy = Input::get('group_by'); $chartType = Input::get('chart_type'); $reportType = Input::get('report_type'); + $dateField = Input::get('date_field'); $startDate = Utils::toSqlDate(Input::get('start_date'), false); $endDate = Utils::toSqlDate(Input::get('end_date'), false); $enableReport = Input::get('enable_report') ? true : false; @@ -57,6 +58,7 @@ class ReportController extends BaseController $groupBy = 'MONTH'; $chartType = 'Bar'; $reportType = ENTITY_INVOICE; + $dateField = FILTER_INVOICE_DATE; $startDate = Utils::today(false)->modify('-3 month'); $endDate = Utils::today(false); $enableReport = true; @@ -98,7 +100,7 @@ class ReportController extends BaseController if (Auth::user()->account->isPro()) { if ($enableReport) { $isExport = $action == 'export'; - $params = array_merge($params, self::generateReport($reportType, $startDate, $endDate, $isExport)); + $params = array_merge($params, self::generateReport($reportType, $startDate, $endDate, $dateField, $isExport)); if ($isExport) { self::export($params['displayData'], $params['columns'], $params['reportTotals']); @@ -216,7 +218,7 @@ class ReportController extends BaseController ]; } - private function generateReport($reportType, $startDate, $endDate, $isExport) + private function generateReport($reportType, $startDate, $endDate, $dateField, $isExport) { if ($reportType == ENTITY_CLIENT) { return $this->generateClientReport($startDate, $endDate, $isExport); @@ -225,11 +227,11 @@ class ReportController extends BaseController } elseif ($reportType == ENTITY_PAYMENT) { return $this->generatePaymentReport($startDate, $endDate, $isExport); } elseif ($reportType == ENTITY_TAX_RATE) { - return $this->generateTaxRateReport($startDate, $endDate, $isExport); + return $this->generateTaxRateReport($startDate, $endDate, $dateField, $isExport); } } - private function generateTaxRateReport($startDate, $endDate, $isExport) + private function generateTaxRateReport($startDate, $endDate, $dateField, $isExport) { $columns = ['tax_name', 'tax_rate', 'amount', 'paid']; @@ -238,14 +240,25 @@ class ReportController extends BaseController $reportTotals = []; $clients = Client::scope() - ->withTrashed() + ->withArchived() ->with('contacts') - ->where('is_deleted', '=', false) - ->with(['invoices' => function($query) use ($startDate, $endDate) { - $query->where('invoice_date', '>=', $startDate) - ->where('invoice_date', '<=', $endDate) - ->where('is_deleted', '=', false) - ->withTrashed(); + ->with(['invoices' => function($query) use ($startDate, $endDate, $dateField) { + $query->withArchived(); + if ($dateField == FILTER_PAYMENT_DATE) { + $query->where('invoice_date', '>=', $startDate) + ->where('invoice_date', '<=', $endDate) + ->whereHas('payments', function($query) use ($startDate, $endDate) { + $query->where('payment_date', '>=', $startDate) + ->where('payment_date', '<=', $endDate) + ->withArchived(); + }) + ->with(['payments' => function($query) use ($startDate, $endDate) { + $query->where('payment_date', '>=', $startDate) + ->where('payment_date', '<=', $endDate) + ->withArchived() + ->with('payment_type', 'account_gateway.gateway'); + }, 'invoice_items']); + } }]); foreach ($clients->get() as $client) { @@ -255,7 +268,7 @@ class ReportController extends BaseController $taxTotals = []; foreach ($client->invoices as $invoice) { - foreach ($invoice->getTaxes() as $key => $tax) { + foreach ($invoice->getTaxes(true) as $key => $tax) { if ( ! isset($taxTotals[$currencyId])) { $taxTotals[$currencyId] = []; } @@ -331,7 +344,7 @@ class ReportController extends BaseController $reportTotals = $this->addToTotals($reportTotals, $client, 'amount', $invoice->amount); $reportTotals = $this->addToTotals($reportTotals, $client, 'paid', $payment->amount); } - + return [ 'columns' => $columns, 'displayData' => $displayData, diff --git a/app/Http/routes.php b/app/Http/routes.php index f7bed59f6879..7789d4825353 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -1,5 +1,6 @@ withTrashed()->where('is_deleted', '=', false); + } + public function getName() { return $this->public_id; diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 6bb1ff9408e8..835de501c67d 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -129,13 +129,21 @@ class Invoice extends EntityModel implements BalanceAffecting return false; } - public function getAmountPaid() + public function getAmountPaid($calculate = false) { if ($this->is_quote || $this->is_recurring) { return 0; } - return ($this->amount - $this->balance); + if ($calculate) { + $amount = 0; + foreach ($this->payments as $payment) { + $amount += $payment->amount; + } + return $amount; + } else { + return ($this->amount - $this->balance); + } } public function trashed() @@ -797,7 +805,7 @@ class Invoice extends EntityModel implements BalanceAffecting return $total; } - public function getTaxes() + public function getTaxes($calculatePaid = false) { $taxes = []; $taxable = $this->getTaxable(); @@ -811,7 +819,7 @@ class Invoice extends EntityModel implements BalanceAffecting 'name' => $this->tax_name, 'rate' => $this->tax_rate, 'amount' => $taxAmount, - 'paid' => $this->getAmountPaid() / $this->amount * $taxAmount + 'paid' => round($this->getAmountPaid($calculatePaid) / $this->amount * $taxAmount, 2) ]; } } @@ -836,7 +844,7 @@ class Invoice extends EntityModel implements BalanceAffecting } $taxes[$key]['amount'] += $taxAmount; - $taxes[$key]['paid'] += $this->amount && $taxAmount ? ($this->getAmountPaid() / $this->amount * $taxAmount) : 0; + $taxes[$key]['paid'] += $this->amount && $taxAmount ? round($this->getAmountPaid($calculatePaid) / $this->amount * $taxAmount, 2) : 0; $taxes[$key]['name'] = $invoiceItem->tax_name; $taxes[$key]['rate'] = $invoiceItem->tax_rate; } diff --git a/app/Ninja/Repositories/AccountRepository.php b/app/Ninja/Repositories/AccountRepository.php index 3a2ea488e850..880ded2baf47 100644 --- a/app/Ninja/Repositories/AccountRepository.php +++ b/app/Ninja/Repositories/AccountRepository.php @@ -130,11 +130,6 @@ class AccountRepository private function getNavigationSearchData() { - $features = [ - ['dashboard', '/dashboard'], - ['customize_design', '/settings/customize_design'], - ]; - $entityTypes = [ ENTITY_INVOICE, ENTITY_CLIENT, @@ -157,6 +152,12 @@ class AccountRepository ]; } + $features[] = ['dashboard', '/dashboard']; + $features[] = ['customize_design', '/settings/customize_design']; + $features[] = ['new_tax_rate', '/tax_rates/create']; + $features[] = ['new_product', '/products/create']; + $features[] = ['new_user', '/users/create']; + $settings = array_merge(Account::$basicSettings, Account::$advancedSettings); foreach ($settings as $setting) { diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 0309b6a8fe83..2d6689b55456 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -223,11 +223,6 @@ class AppServiceProvider extends ServiceProvider { 'Illuminate\Contracts\Auth\Registrar', 'App\Services\Registrar' ); - - $this->app->bind( - 'App\Ninja\Import\DataImporterServiceInterface', - 'App\Ninja\Import\FreshBooks\FreshBooksDataImporterService' - ); } } diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index bb236d904cd6..23d8b719e40d 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -1039,7 +1039,12 @@ $LANG = array( 'list_payments' => 'List Payments', 'list_credits' => 'List Credits', 'tax_name' => 'Tax Name', - + 'report_settings' => 'Report Settings', + 'search_hotkey' => 'shortcut is /', + + 'new_user' => 'New User', + 'new_product' => 'New Product', + 'new_tax_rate' => 'New Tax Rate', ); return $LANG; diff --git a/resources/views/header.blade.php b/resources/views/header.blade.php index 8b316660542a..e5f52b0a7a90 100644 --- a/resources/views/header.blade.php +++ b/resources/views/header.blade.php @@ -498,7 +498,7 @@ diff --git a/resources/views/reports/chart_builder.blade.php b/resources/views/reports/chart_builder.blade.php index d0beac93a3b0..5095c097f77d 100644 --- a/resources/views/reports/chart_builder.blade.php +++ b/resources/views/reports/chart_builder.blade.php @@ -26,7 +26,7 @@
-

{!! trans('texts.settings') !!}

+

{!! trans('texts.report_settings') !!}

@@ -58,6 +58,11 @@
{!! Former::checkbox('enable_report')->text(trans('texts.enable')) !!} {!! Former::select('report_type')->options($reportTypes, $reportType)->label(trans('texts.type')) !!} +
+ {!! Former::select('date_field')->label(trans('texts.filter')) + ->addOption(trans('texts.invoice_date'), FILTER_INVOICE_DATE) + ->addOption(trans('texts.payment_date'), FILTER_PAYMENT_DATE) !!} +

 

{!! Former::checkbox('enable_chart')->text(trans('texts.enable')) !!} {!! Former::select('group_by')->options($dateTypes, $groupBy) !!} @@ -186,6 +191,15 @@ $('.end_date .input-group-addon').click(function() { toggleDatePicker('end_date'); }); + + $('#report_type').change(function() { + var val = $('#report_type').val(); + if (val == '{{ ENTITY_TAX_RATE }}') { + $('#dateField').fadeIn(); + } else { + $('#dateField').fadeOut(); + } + }); }) From 88fcc059023074c015876e8e289d08835b907360 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 24 Feb 2016 23:54:43 +0200 Subject: [PATCH 010/220] Implemented basic expense report --- app/Http/Controllers/ReportController.php | 75 ++++++++++++++++++----- app/Ninja/Presenters/ExpensePresenter.php | 10 +++ app/Ninja/Presenters/VendorPresenter.php | 5 ++ resources/lang/en/texts.php | 4 +- 4 files changed, 77 insertions(+), 17 deletions(-) diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index 6ef53ffc6ebe..a37705f06ceb 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -12,6 +12,7 @@ use View; use App\Models\Account; use App\Models\Client; use App\Models\Payment; +use App\Models\Expense; class ReportController extends BaseController { @@ -81,6 +82,7 @@ class ReportController extends BaseController ENTITY_INVOICE => trans('texts.invoice'), ENTITY_PAYMENT => trans('texts.payment'), ENTITY_TAX_RATE => trans('texts.taxes'), + ENTITY_EXPENSE => trans('texts.expenses'), ]; $params = [ @@ -228,6 +230,8 @@ class ReportController extends BaseController return $this->generatePaymentReport($startDate, $endDate, $isExport); } elseif ($reportType == ENTITY_TAX_RATE) { return $this->generateTaxRateReport($startDate, $endDate, $dateField, $isExport); + } elseif ($reportType == ENTITY_EXPENSE) { + return $this->generateExpenseReport($startDate, $endDate, $isExport); } } @@ -294,8 +298,8 @@ class ReportController extends BaseController ]; } - $reportTotals = $this->addToTotals($reportTotals, $client, 'amount', $tax['amount']); - $reportTotals = $this->addToTotals($reportTotals, $client, 'paid', $tax['paid']); + $reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'amount', $tax['amount']); + $reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'paid', $tax['paid']); } } @@ -341,8 +345,8 @@ class ReportController extends BaseController $payment->present()->method, ]; - $reportTotals = $this->addToTotals($reportTotals, $client, 'amount', $invoice->amount); - $reportTotals = $this->addToTotals($reportTotals, $client, 'paid', $payment->amount); + $reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'amount', $invoice->amount); + $reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'paid', $payment->amount); } return [ @@ -388,9 +392,9 @@ class ReportController extends BaseController $account->formatMoney($invoice->getAmountPaid(), $client), $account->formatMoney($invoice->balance, $client), ]; - $reportTotals = $this->addToTotals($reportTotals, $client, 'amount', $invoice->amount); - $reportTotals = $this->addToTotals($reportTotals, $client, 'paid', $invoice->getAmountPaid()); - $reportTotals = $this->addToTotals($reportTotals, $client, 'balance', $invoice->balance); + $reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'amount', $invoice->amount); + $reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'paid', $invoice->getAmountPaid()); + $reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'balance', $invoice->balance); } } @@ -410,14 +414,12 @@ class ReportController extends BaseController $reportTotals = []; $clients = Client::scope() - ->withTrashed() + ->withArchived() ->with('contacts') - ->where('is_deleted', '=', false) ->with(['invoices' => function($query) use ($startDate, $endDate) { $query->where('invoice_date', '>=', $startDate) ->where('invoice_date', '<=', $endDate) - ->where('is_deleted', '=', false) - ->withTrashed(); + ->withArchived(); }]); foreach ($clients->get() as $client) { @@ -436,9 +438,9 @@ class ReportController extends BaseController $account->formatMoney($amount - $paid, $client) ]; - $reportTotals = $this->addToTotals($reportTotals, $client, 'amount', $amount); - $reportTotals = $this->addToTotals($reportTotals, $client, 'paid', $paid); - $reportTotals = $this->addToTotals($reportTotals, $client, 'balance', $amount - $paid); + $reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'amount', $amount); + $reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'paid', $paid); + $reportTotals = $this->addToTotals($reportTotals, $client->currency_id, 'balance', $amount - $paid); } return [ @@ -448,8 +450,49 @@ class ReportController extends BaseController ]; } - private function addToTotals($data, $client, $field, $value) { - $currencyId = $client->currency_id ?: Auth::user()->account->getCurrencyId(); + private function generateExpenseReport($startDate, $endDate, $isExport) + { + $columns = ['vendor', 'client', 'date', 'expense_amount', 'invoiced_amount']; + + $account = Auth::user()->account; + $displayData = []; + $reportTotals = []; + + $expenses = Expense::scope() + ->withTrashed() + ->with('client.contacts', 'vendor') + ->where('expense_date', '>=', $startDate) + ->where('expense_date', '<=', $endDate); + + + foreach ($expenses->get() as $expense) { + $amount = $expense->amount; + $invoiced = $expense->present()->invoiced_amount; + + $displayData[] = [ + $expense->vendor ? ($isExport ? $expense->vendor->name : $expense->vendor->present()->link) : '', + $expense->client ? ($isExport ? $expense->client->getDisplayName() : $expense->client->present()->link) : '', + $expense->present()->expense_date, + Utils::formatMoney($amount, $expense->currency_id), + Utils::formatMoney($invoiced, $expense->invoice_currency_id), + ]; + + $reportTotals = $this->addToTotals($reportTotals, $expense->expense_currency_id, 'amount', $amount); + $reportTotals = $this->addToTotals($reportTotals, $expense->invoice_currency_id, 'amount', 0); + + $reportTotals = $this->addToTotals($reportTotals, $expense->invoice_currency_id, 'invoiced', $invoiced); + $reportTotals = $this->addToTotals($reportTotals, $expense->expense_currency_id, 'invoiced', 0); + } + + return [ + 'columns' => $columns, + 'displayData' => $displayData, + 'reportTotals' => $reportTotals, + ]; + } + + private function addToTotals($data, $currencyId, $field, $value) { + $currencyId = $currencyId ?: Auth::user()->account->getCurrencyId(); if (!isset($data[$currencyId][$field])) { $data[$currencyId][$field] = 0; diff --git a/app/Ninja/Presenters/ExpensePresenter.php b/app/Ninja/Presenters/ExpensePresenter.php index 9cede24d039e..6b66080ded85 100644 --- a/app/Ninja/Presenters/ExpensePresenter.php +++ b/app/Ninja/Presenters/ExpensePresenter.php @@ -20,4 +20,14 @@ class ExpensePresenter extends Presenter { { return round($this->entity->amount * $this->entity->exchange_rate, 2); } + + public function invoiced_amount() + { + return $this->entity->invoice_id ? $this->converted_amount() : 0; + } + + public function link() + { + return link_to('/expenses/' . $this->entity->public_id, $this->entity->name); + } } \ No newline at end of file diff --git a/app/Ninja/Presenters/VendorPresenter.php b/app/Ninja/Presenters/VendorPresenter.php index b3da402bec40..d0bef4e0c828 100644 --- a/app/Ninja/Presenters/VendorPresenter.php +++ b/app/Ninja/Presenters/VendorPresenter.php @@ -9,4 +9,9 @@ class VendorPresenter extends Presenter { { return $this->entity->country ? $this->entity->country->name : ''; } + + public function link() + { + return link_to('/vendors/' . $this->entity->public_id, $this->entity->name); + } } \ No newline at end of file diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 23d8b719e40d..d130919802a7 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -1034,7 +1034,7 @@ $LANG = array( 'list_clients' => 'List Clients', 'list_quotes' => 'List Quotes', 'list_tasks' => 'List Tasks', - 'list_expensess' => 'List Expenses', + 'list_expenses' => 'List Expenses', 'list_recurring_invoices' => 'List Recurring Invoices', 'list_payments' => 'List Payments', 'list_credits' => 'List Credits', @@ -1045,6 +1045,8 @@ $LANG = array( 'new_user' => 'New User', 'new_product' => 'New Product', 'new_tax_rate' => 'New Tax Rate', + 'invoiced_amount' => 'Invoiced Amount', + ); return $LANG; From 6cdbc159614fb959807b56618ad05ea3e5e351c9 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 24 Feb 2016 23:54:56 +0200 Subject: [PATCH 011/220] Implemented basic expense report --- app/Http/Controllers/ReportController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index a37705f06ceb..f6aa72bf535b 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -81,8 +81,8 @@ class ReportController extends BaseController ENTITY_CLIENT => trans('texts.client'), ENTITY_INVOICE => trans('texts.invoice'), ENTITY_PAYMENT => trans('texts.payment'), - ENTITY_TAX_RATE => trans('texts.taxes'), ENTITY_EXPENSE => trans('texts.expenses'), + ENTITY_TAX_RATE => trans('texts.taxes'), ]; $params = [ From fb959c1487b3f0b7d9ab11493a3d51a8aaebdfd0 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 25 Feb 2016 10:32:31 +0200 Subject: [PATCH 012/220] Refinements to reports --- app/Http/Controllers/ReportController.php | 2 +- resources/views/reports/chart_builder.blade.php | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index f6aa72bf535b..690775318aea 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -292,7 +292,7 @@ class ReportController extends BaseController foreach ($taxes as $tax) { $displayData[] = [ $tax['name'], - $tax['rate'], + $tax['rate'] . '%', $account->formatMoney($tax['amount'], $client), $account->formatMoney($tax['paid'], $client) ]; diff --git a/resources/views/reports/chart_builder.blade.php b/resources/views/reports/chart_builder.blade.php index 5095c097f77d..defe7405e08b 100644 --- a/resources/views/reports/chart_builder.blade.php +++ b/resources/views/reports/chart_builder.blade.php @@ -87,13 +87,19 @@ - @foreach ($displayData as $record) + @if (count($displayData)) + @foreach ($displayData as $record) + + @foreach ($record as $field) + {!! $field !!} + @endforeach + + @endforeach + @else - @foreach ($record as $field) - {!! $field !!} - @endforeach + {{ trans('texts.empty_table') }} - @endforeach + @endif From 01f9634237c1309580a68474393efae42703240c Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 25 Feb 2016 11:25:07 +0200 Subject: [PATCH 013/220] Improvements to data export --- app/Http/Controllers/ExportController.php | 26 ++++++++++++----------- app/Models/Invoice.php | 5 +++++ app/Ninja/Presenters/InvoicePresenter.php | 22 ++++++++++++++++--- resources/lang/en/texts.php | 2 +- resources/views/export.blade.php | 5 +++++ resources/views/export/invoices.blade.php | 2 ++ 6 files changed, 46 insertions(+), 16 deletions(-) diff --git a/app/Http/Controllers/ExportController.php b/app/Http/Controllers/ExportController.php index 540e38d97296..a7f5db4b577d 100644 --- a/app/Http/Controllers/ExportController.php +++ b/app/Http/Controllers/ExportController.php @@ -109,8 +109,7 @@ class ExportController extends BaseController if ($request->input(ENTITY_CLIENT)) { $data['clients'] = Client::scope() ->with('user', 'contacts', 'country') - ->withTrashed() - ->where('is_deleted', '=', false) + ->withArchived() ->get(); $data['contacts'] = Contact::scope() @@ -126,33 +125,36 @@ class ExportController extends BaseController if ($request->input(ENTITY_TASK)) { $data['tasks'] = Task::scope() ->with('user', 'client.contacts') - ->withTrashed() - ->where('is_deleted', '=', false) + ->withArchived() ->get(); } if ($request->input(ENTITY_INVOICE)) { $data['invoices'] = Invoice::scope() ->with('user', 'client.contacts', 'invoice_status') - ->withTrashed() - ->where('is_deleted', '=', false) + ->withArchived() ->where('is_quote', '=', false) ->where('is_recurring', '=', false) ->get(); $data['quotes'] = Invoice::scope() ->with('user', 'client.contacts', 'invoice_status') - ->withTrashed() - ->where('is_deleted', '=', false) + ->withArchived() ->where('is_quote', '=', true) ->where('is_recurring', '=', false) ->get(); + + $data['recurringInvoices'] = Invoice::scope() + ->with('user', 'client.contacts', 'invoice_status', 'frequency') + ->withArchived() + ->where('is_quote', '=', false) + ->where('is_recurring', '=', true) + ->get(); } if ($request->input(ENTITY_PAYMENT)) { $data['payments'] = Payment::scope() - ->withTrashed() - ->where('is_deleted', '=', false) + ->withArchived() ->with('user', 'client.contacts', 'payment_type', 'invoice', 'account_gateway.gateway') ->get(); } @@ -161,14 +163,14 @@ class ExportController extends BaseController if ($request->input(ENTITY_VENDOR)) { $data['clients'] = Vendor::scope() ->with('user', 'vendorcontacts', 'country') - ->withTrashed() - ->where('is_deleted', '=', false) + ->withArchived() ->get(); $data['vendor_contacts'] = VendorContact::scope() ->with('user', 'vendor.contacts') ->withTrashed() ->get(); + /* $data['expenses'] = Credit::scope() ->with('user', 'client.contacts') diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php index 835de501c67d..e60a06f8d4a4 100644 --- a/app/Models/Invoice.php +++ b/app/Models/Invoice.php @@ -200,6 +200,11 @@ class Invoice extends EntityModel implements BalanceAffecting return $this->hasMany('App\Models\Invoice', 'recurring_invoice_id'); } + public function frequency() + { + return $this->belongsTo('App\Models\Frequency'); + } + public function invitations() { return $this->hasMany('App\Models\Invitation')->orderBy('invitations.contact_id'); diff --git a/app/Ninja/Presenters/InvoicePresenter.php b/app/Ninja/Presenters/InvoicePresenter.php index 2bab049d2a31..0daa73312386 100644 --- a/app/Ninja/Presenters/InvoicePresenter.php +++ b/app/Ninja/Presenters/InvoicePresenter.php @@ -40,9 +40,15 @@ class InvoicePresenter extends Presenter { public function status() { - $status = $this->entity->invoice_status ? $this->entity->invoice_status->name : 'draft'; - $status = strtolower($status); - return trans("texts.status_{$status}"); + if ($this->entity->is_deleted) { + return trans('texts.deleted'); + } elseif ($this->entity->trashed()) { + return trans('texts.archived'); + } else { + $status = $this->entity->invoice_status ? $this->entity->invoice_status->name : 'draft'; + $status = strtolower($status); + return trans("texts.status_{$status}"); + } } public function invoice_date() @@ -55,9 +61,19 @@ class InvoicePresenter extends Presenter { return Utils::fromSqlDate($this->entity->due_date); } + public function frequency() + { + return $this->entity->frequency ? $this->entity->frequency->name : ''; + } + public function link() { return link_to('/invoices/' . $this->entity->public_id, $this->entity->invoice_number); } + public function email() + { + $client = $this->entity->client; + return count($client->contacts) ? $client->contacts[0]->email : ''; + } } \ No newline at end of file diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index d130919802a7..d98821b83fee 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -81,7 +81,7 @@ $LANG = array( 'company_details' => 'Company Details', 'online_payments' => 'Online Payments', 'notifications' => 'Email Notifications', - 'import_export' => 'Import/Export/Cancel', + 'import_export' => 'Import | Export | Cancel', 'done' => 'Done', 'save' => 'Save', 'create' => 'Create', diff --git a/resources/views/export.blade.php b/resources/views/export.blade.php index f2fa8dbbe7fe..6625dee11c5a 100644 --- a/resources/views/export.blade.php +++ b/resources/views/export.blade.php @@ -35,6 +35,11 @@ @include('export.invoices', ['entityType' => ENTITY_QUOTE]) @endif + @if (isset($recurringInvoices) && $recurringInvoices && count($recurringInvoices)) + {{ strtoupper(trans('texts.recurring_invoices')) }} + @include('export.recurring_invoices', ['entityType' => ENTITY_RECURRING_INVOICE]) + @endif + @if (isset($payments) && $payments && count($payments)) {{ strtoupper(trans('texts.payments')) }} @include('export.payments') diff --git a/resources/views/export/invoices.blade.php b/resources/views/export/invoices.blade.php index fab37fbf8cb7..6aa9fd65169e 100644 --- a/resources/views/export/invoices.blade.php +++ b/resources/views/export/invoices.blade.php @@ -1,5 +1,6 @@ {{ trans('texts.client') }} + {{ trans('texts.email') }} @if ($multiUser) {{ trans('texts.user') }} @endif @@ -28,6 +29,7 @@ @if (!$invoice->client->is_deleted) {{ $invoice->present()->client }} + {{ $invoice->present()->email }} @if ($multiUser) {{ $invoice->present()->user }} @endif From 0e3b78097c4a5f2e317c407033c7491e8ce8fa23 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 25 Feb 2016 11:25:19 +0200 Subject: [PATCH 014/220] Improvements to data export --- .../views/export/recurring_invoices.blade.php | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 resources/views/export/recurring_invoices.blade.php diff --git a/resources/views/export/recurring_invoices.blade.php b/resources/views/export/recurring_invoices.blade.php new file mode 100644 index 000000000000..0548c14b9b15 --- /dev/null +++ b/resources/views/export/recurring_invoices.blade.php @@ -0,0 +1,55 @@ + + {{ trans('texts.client') }} + {{ trans('texts.email') }} + @if ($multiUser) + {{ trans('texts.user') }} + @endif + {{ trans('texts.frequency') }} + {{ trans('texts.balance') }} + {{ trans('texts.amount') }} + {{ trans('texts.po_number') }} + {{ trans('texts.status') }} + @if ($account->custom_invoice_label1) + {{ $account->custom_invoice_label1 }} + @endif + @if ($account->custom_invoice_label2) + {{ $account->custom_invoice_label2 }} + @endif + @if ($account->custom_invoice_text_label1) + {{ $account->custom_invoice_text_label1 }} + @endif + @if ($account->custom_invoice_text_label2) + {{ $account->custom_invoice_text_label2 }} + @endif + + +@foreach ($recurringInvoices as $invoice) + @if (!$invoice->client->is_deleted) + + {{ $invoice->present()->client }} + {{ $invoice->present()->email }} + @if ($multiUser) + {{ $invoice->present()->user }} + @endif + {{ $invoice->present()->frequency }} + {{ $account->formatMoney($invoice->balance, $invoice->client) }} + {{ $account->formatMoney($invoice->amount, $invoice->client) }} + {{ $invoice->po_number }} + {{ $invoice->present()->status }} + @if ($account->custom_invoice_label1) + {{ $invoice->custom_value1 }} + @endif + @if ($account->custom_invoice_label2) + {{ $invoice->custom_value2 }} + @endif + @if ($account->custom_invoice_label1) + {{ $invoice->custom_text_value1 }} + @endif + @if ($account->custom_invoice_label2) + {{ $invoice->custom_text_value2 }} + @endif + + @endif +@endforeach + + \ No newline at end of file From 689efc3e3e900c35b3bafbbd5065e465e2012ee4 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 25 Feb 2016 12:16:27 +0200 Subject: [PATCH 015/220] Lazy load images --- Gruntfile.js | 2 - app/Http/routes.php | 2 + public/built.js | 17 +- public/css/built.css | 211 ------------------ public/js/script.js | 8 + .../views/accounts/invoice_design.blade.php | 4 +- resources/views/header.blade.php | 6 +- resources/views/invoices/edit.blade.php | 14 +- resources/views/invoices/pdf.blade.php | 25 ++- 9 files changed, 51 insertions(+), 238 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 05dab35047ec..8b50d2d5b2fe 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -107,7 +107,6 @@ module.exports = function(grunt) { //'public/vendor/pdfmake/build/pdfmake.min.js', //'public/vendor/pdfmake/build/vfs_fonts.js', //'public/js/vfs_fonts.js', - 'public/js/lightbox.min.js', 'public/js/bootstrap-combobox.js', 'public/js/script.js', 'public/js/pdf.pdfmake.js', @@ -140,7 +139,6 @@ module.exports = function(grunt) { 'public/vendor/spectrum/spectrum.css', 'public/css/bootstrap-combobox.css', 'public/css/typeahead.js-bootstrap.css', - 'public/css/lightbox.css', //'public/vendor/handsontable/dist/jquery.handsontable.full.css', 'public/css/style.css', ], diff --git a/app/Http/routes.php b/app/Http/routes.php index 7789d4825353..1a9240377010 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -528,6 +528,8 @@ if (!defined('CONTACT_EMAIL')) { define('EMAIL_MARKUP_URL', 'https://developers.google.com/gmail/markup'); define('OFX_HOME_URL', 'http://www.ofxhome.com/index.php/home/directory/all'); + define('BLANK_IMAGE', 'data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs='); + define('COUNT_FREE_DESIGNS', 4); define('COUNT_FREE_DESIGNS_SELF_HOST', 5); // include the custom design define('PRODUCT_ONE_CLICK_INSTALL', 1); diff --git a/public/built.js b/public/built.js index ec11a94ceb11..81952805cb58 100644 --- a/public/built.js +++ b/public/built.js @@ -29450,15 +29450,6 @@ links:["Africa/Abidjan|Africa/Bamako","Africa/Abidjan|Africa/Banjul","Africa/Abi (function(){"use strict";function e(e){return"function"==typeof e||"object"==typeof e&&null!==e}function t(e){return"function"==typeof e}function r(e){return"object"==typeof e&&null!==e}function n(e){q=e}function o(e){Z=e}function i(){return function(){process.nextTick(l)}}function a(){return function(){I(l)}}function s(){var e=0,t=new Y(l),r=document.createTextNode("");return t.observe(r,{characterData:!0}),function(){r.data=e=++e%2}}function u(){var e=new MessageChannel;return e.port1.onmessage=l,function(){e.port2.postMessage(0)}}function c(){return function(){setTimeout(l,1)}}function l(){for(var e=0;B>e;e+=2){var t=K[e],r=K[e+1];t(r),K[e]=void 0,K[e+1]=void 0}B=0}function f(){try{var e=require,t=e("vertx");return I=t.runOnLoop||t.runOnContext,a()}catch(r){return c()}}function p(){}function h(){return new TypeError("You cannot resolve a promise with itself")}function g(){return new TypeError("A promises callback cannot return that same promise.")}function d(e){try{return e.then}catch(t){return te.error=t,te}}function m(e,t,r,n){try{e.call(t,r,n)}catch(o){return o}}function y(e,t,r){Z(function(e){var n=!1,o=m(r,t,function(r){n||(n=!0,t!==r?b(e,r):A(e,r))},function(t){n||(n=!0,C(e,t))},"Settle: "+(e._label||" unknown promise"));!n&&o&&(n=!0,C(e,o))},e)}function v(e,t){t._state===W?A(e,t._result):t._state===ee?C(e,t._result):S(t,void 0,function(t){b(e,t)},function(t){C(e,t)})}function _(e,r){if(r.constructor===e.constructor)v(e,r);else{var n=d(r);n===te?C(e,te.error):void 0===n?A(e,r):t(n)?y(e,r,n):A(e,r)}}function b(t,r){t===r?C(t,h()):e(r)?_(t,r):A(t,r)}function w(e){e._onerror&&e._onerror(e._result),O(e)}function A(e,t){e._state===Q&&(e._result=t,e._state=W,0!==e._subscribers.length&&Z(O,e))}function C(e,t){e._state===Q&&(e._state=ee,e._result=t,Z(w,e))}function S(e,t,r,n){var o=e._subscribers,i=o.length;e._onerror=null,o[i]=t,o[i+W]=r,o[i+ee]=n,0===i&&e._state&&Z(O,e)}function O(e){var t=e._subscribers,r=e._state;if(0!==t.length){for(var n,o,i=e._result,a=0;aa;a++)S(n.resolve(e[a]),void 0,t,r);return o}function L(e){var t=this;if(e&&"object"==typeof e&&e.constructor===t)return e;var r=new t(p);return b(r,e),r}function P(e){var t=this,r=new t(p);return C(r,e),r}function F(){throw new TypeError("You must pass a resolver function as the first argument to the promise constructor")}function R(){throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.")}function $(e){this._id=ue++,this._state=void 0,this._result=void 0,this._subscribers=[],p!==e&&(t(e)||F(),this instanceof $||R(),j(this,e))}function G(){var e;if("undefined"!=typeof global)e=global;else if("undefined"!=typeof self)e=self;else try{e=Function("return this")()}catch(t){throw new Error("polyfill failed because global object is unavailable in this environment")}var r=e.Promise;(!r||"[object Promise]"!==Object.prototype.toString.call(r.resolve())||r.cast)&&(e.Promise=ce)}var U;U=Array.isArray?Array.isArray:function(e){return"[object Array]"===Object.prototype.toString.call(e)};var I,q,J,D=U,B=0,Z=({}.toString,function(e,t){K[B]=e,K[B+1]=t,B+=2,2===B&&(q?q(l):J())}),z="undefined"!=typeof window?window:void 0,H=z||{},Y=H.MutationObserver||H.WebKitMutationObserver,X="undefined"!=typeof process&&"[object process]"==={}.toString.call(process),V="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel,K=new Array(1e3);J=X?i():Y?s():V?u():void 0===z&&"function"==typeof require?f():c();var Q=void 0,W=1,ee=2,te=new E,re=new E;M.prototype._validateInput=function(e){return D(e)},M.prototype._validationError=function(){return new Error("Array Methods must be provided an Array")},M.prototype._init=function(){this._result=new Array(this.length)};var ne=M;M.prototype._enumerate=function(){for(var e=this,t=e.length,r=e.promise,n=e._input,o=0;r._state===Q&&t>o;o++)e._eachEntry(n[o],o)},M.prototype._eachEntry=function(e,t){var n=this,o=n._instanceConstructor;r(e)?e.constructor===o&&e._state!==Q?(e._onerror=null,n._settledAt(e._state,t,e._result)):n._willSettleAt(o.resolve(e),t):(n._remaining--,n._result[t]=e)},M.prototype._settledAt=function(e,t,r){var n=this,o=n.promise;o._state===Q&&(n._remaining--,e===ee?C(o,r):n._result[t]=r),0===n._remaining&&A(o,n._result)},M.prototype._willSettleAt=function(e,t){var r=this;S(e,void 0,function(e){r._settledAt(W,t,e)},function(e){r._settledAt(ee,t,e)})};var oe=k,ie=T,ae=L,se=P,ue=0,ce=$;$.all=oe,$.race=ie,$.resolve=ae,$.reject=se,$._setScheduler=n,$._setAsap=o,$._asap=Z,$.prototype={constructor:$,then:function(e,t){var r=this,n=r._state;if(n===W&&!e||n===ee&&!t)return this;var o=new this.constructor(p),i=r._result;if(n){var a=arguments[n-1];Z(function(){x(n,o,a,i)})}else S(r,o,e,t);return o},"catch":function(e){return this.then(null,e)}};var le=G,fe={Promise:ce,polyfill:le};"function"==typeof define&&define.amd?define(function(){return fe}):"undefined"!=typeof module&&module.exports?module.exports=fe:"undefined"!=typeof this&&(this.ES6Promise=fe),le()}).call(this),function(){function e(t,n){function i(e){if(i[e]!==m)return i[e];var t;if("bug-string-char-index"==e)t="a"!="a"[0];else if("json"==e)t=i("json-stringify")&&i("json-parse");else{var r,o='{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';if("json-stringify"==e){var u=n.stringify,l="function"==typeof u&&_;if(l){(r=function(){return 1}).toJSON=r;try{l="0"===u(0)&&"0"===u(new a)&&'""'==u(new s)&&u(v)===m&&u(m)===m&&u()===m&&"1"===u(r)&&"[1]"==u([r])&&"[null]"==u([m])&&"null"==u(null)&&"[null,null,null]"==u([m,v,null])&&u({a:[r,!0,!1,null,"\x00\b\n\f\r "]})==o&&"1"===u(null,r)&&"[\n 1,\n 2\n]"==u([1,2],null,1)&&'"-271821-04-20T00:00:00.000Z"'==u(new c(-864e13))&&'"+275760-09-13T00:00:00.000Z"'==u(new c(864e13))&&'"-000001-01-01T00:00:00.000Z"'==u(new c(-621987552e5))&&'"1969-12-31T23:59:59.999Z"'==u(new c(-1))}catch(f){l=!1}}t=l}if("json-parse"==e){var p=n.parse;if("function"==typeof p)try{if(0===p("0")&&!p(!1)){r=p(o);var h=5==r.a.length&&1===r.a[0];if(h){try{h=!p('" "')}catch(f){}if(h)try{h=1!==p("01")}catch(f){}if(h)try{h=1!==p("1.")}catch(f){}}}}catch(f){h=!1}t=h}}return i[e]=!!t}t||(t=o.Object()),n||(n=o.Object());var a=t.Number||o.Number,s=t.String||o.String,u=t.Object||o.Object,c=t.Date||o.Date,l=t.SyntaxError||o.SyntaxError,f=t.TypeError||o.TypeError,p=t.Math||o.Math,h=t.JSON||o.JSON;"object"==typeof h&&h&&(n.stringify=h.stringify,n.parse=h.parse);var g,d,m,y=u.prototype,v=y.toString,_=new c(-0xc782b5b800cec);try{_=-109252==_.getUTCFullYear()&&0===_.getUTCMonth()&&1===_.getUTCDate()&&10==_.getUTCHours()&&37==_.getUTCMinutes()&&6==_.getUTCSeconds()&&708==_.getUTCMilliseconds()}catch(b){}if(!i("json")){var w="[object Function]",A="[object Date]",C="[object Number]",S="[object String]",O="[object Array]",E="[object Boolean]",N=i("bug-string-char-index");if(!_)var x=p.floor,j=[0,31,59,90,120,151,181,212,243,273,304,334],M=function(e,t){return j[t]+365*(e-1970)+x((e-1969+(t=+(t>1)))/4)-x((e-1901+t)/100)+x((e-1601+t)/400)};if((g=y.hasOwnProperty)||(g=function(e){var t,r={};return(r.__proto__=null,r.__proto__={toString:1},r).toString!=v?g=function(e){var t=this.__proto__,r=e in(this.__proto__=null,this);return this.__proto__=t,r}:(t=r.constructor,g=function(e){var r=(this.constructor||t).prototype;return e in this&&!(e in r&&this[e]===r[e])}),r=null,g.call(this,e)}),d=function(e,t){var n,o,i,a=0;(n=function(){this.valueOf=0}).prototype.valueOf=0,o=new n;for(i in o)g.call(o,i)&&a++;return n=o=null,a?d=2==a?function(e,t){var r,n={},o=v.call(e)==w;for(r in e)o&&"prototype"==r||g.call(n,r)||!(n[r]=1)||!g.call(e,r)||t(r)}:function(e,t){var r,n,o=v.call(e)==w;for(r in e)o&&"prototype"==r||!g.call(e,r)||(n="constructor"===r)||t(r);(n||g.call(e,r="constructor"))&&t(r)}:(o=["valueOf","toString","toLocaleString","propertyIsEnumerable","isPrototypeOf","hasOwnProperty","constructor"],d=function(e,t){var n,i,a=v.call(e)==w,s=!a&&"function"!=typeof e.constructor&&r[typeof e.hasOwnProperty]&&e.hasOwnProperty||g;for(n in e)a&&"prototype"==n||!s.call(e,n)||t(n);for(i=o.length;n=o[--i];s.call(e,n)&&t(n));}),d(e,t)},!i("json-stringify")){var k={92:"\\\\",34:'\\"',8:"\\b",12:"\\f",10:"\\n",13:"\\r",9:"\\t"},T="000000",L=function(e,t){return(T+(t||0)).slice(-e)},P="\\u00",F=function(e){for(var t='"',r=0,n=e.length,o=!N||n>10,i=o&&(N?e.split(""):e);n>r;r++){var a=e.charCodeAt(r);switch(a){case 8:case 9:case 10:case 12:case 13:case 34:case 92:t+=k[a];break;default:if(32>a){t+=P+L(2,a.toString(16));break}t+=o?i[r]:e.charAt(r)}}return t+'"'},R=function(e,t,r,n,o,i,a){var s,u,c,l,p,h,y,_,b,w,N,j,k,T,P,$;try{s=t[e]}catch(G){}if("object"==typeof s&&s)if(u=v.call(s),u!=A||g.call(s,"toJSON"))"function"==typeof s.toJSON&&(u!=C&&u!=S&&u!=O||g.call(s,"toJSON"))&&(s=s.toJSON(e));else if(s>-1/0&&1/0>s){if(M){for(p=x(s/864e5),c=x(p/365.2425)+1970-1;M(c+1,0)<=p;c++);for(l=x((p-M(c,0))/30.42);M(c,l+1)<=p;l++);p=1+p-M(c,l),h=(s%864e5+864e5)%864e5,y=x(h/36e5)%24,_=x(h/6e4)%60,b=x(h/1e3)%60,w=h%1e3}else c=s.getUTCFullYear(),l=s.getUTCMonth(),p=s.getUTCDate(),y=s.getUTCHours(),_=s.getUTCMinutes(),b=s.getUTCSeconds(),w=s.getUTCMilliseconds();s=(0>=c||c>=1e4?(0>c?"-":"+")+L(6,0>c?-c:c):L(4,c))+"-"+L(2,l+1)+"-"+L(2,p)+"T"+L(2,y)+":"+L(2,_)+":"+L(2,b)+"."+L(3,w)+"Z"}else s=null;if(r&&(s=r.call(t,e,s)),null===s)return"null";if(u=v.call(s),u==E)return""+s;if(u==C)return s>-1/0&&1/0>s?""+s:"null";if(u==S)return F(""+s);if("object"==typeof s){for(T=a.length;T--;)if(a[T]===s)throw f();if(a.push(s),N=[],P=i,i+=o,u==O){for(k=0,T=s.length;T>k;k++)j=R(k,s,r,n,o,i,a),N.push(j===m?"null":j);$=N.length?o?"[\n"+i+N.join(",\n"+i)+"\n"+P+"]":"["+N.join(",")+"]":"[]"}else d(n||s,function(e){var t=R(e,s,r,n,o,i,a);t!==m&&N.push(F(e)+":"+(o?" ":"")+t)}),$=N.length?o?"{\n"+i+N.join(",\n"+i)+"\n"+P+"}":"{"+N.join(",")+"}":"{}";return a.pop(),$}};n.stringify=function(e,t,n){var o,i,a,s;if(r[typeof t]&&t)if((s=v.call(t))==w)i=t;else if(s==O){a={};for(var u,c=0,l=t.length;l>c;u=t[c++],s=v.call(u),(s==S||s==C)&&(a[u]=1));}if(n)if((s=v.call(n))==C){if((n-=n%1)>0)for(o="",n>10&&(n=10);o.length$;)switch(o=i.charCodeAt($)){case 9:case 10:case 13:case 32:$++;break;case 123:case 125:case 91:case 93:case 58:case 44:return e=N?i.charAt($):i[$],$++,e;case 34:for(e="@",$++;a>$;)if(o=i.charCodeAt($),32>o)q();else if(92==o)switch(o=i.charCodeAt(++$)){case 92:case 34:case 47:case 98:case 116:case 110:case 102:case 114:e+=I[o],$++;break;case 117:for(t=++$,r=$+4;r>$;$++)o=i.charCodeAt($),o>=48&&57>=o||o>=97&&102>=o||o>=65&&70>=o||q();e+=U("0x"+i.slice(t,$));break;default:q()}else{if(34==o)break;for(o=i.charCodeAt($),t=$;o>=32&&92!=o&&34!=o;)o=i.charCodeAt(++$);e+=i.slice(t,$)}if(34==i.charCodeAt($))return $++,e;q();default:if(t=$,45==o&&(n=!0,o=i.charCodeAt(++$)),o>=48&&57>=o){for(48==o&&(o=i.charCodeAt($+1),o>=48&&57>=o)&&q(),n=!1;a>$&&(o=i.charCodeAt($),o>=48&&57>=o);$++);if(46==i.charCodeAt($)){for(r=++$;a>r&&(o=i.charCodeAt(r),o>=48&&57>=o);r++);r==$&&q(),$=r}if(o=i.charCodeAt($),101==o||69==o){for(o=i.charCodeAt(++$),(43==o||45==o)&&$++,r=$;a>r&&(o=i.charCodeAt(r),o>=48&&57>=o);r++);r==$&&q(),$=r}return+i.slice(t,$)}if(n&&q(),"true"==i.slice($,$+4))return $+=4,!0;if("false"==i.slice($,$+5))return $+=5,!1;if("null"==i.slice($,$+4))return $+=4,null;q()}return"$"},D=function(e){var t,r;if("$"==e&&q(),"string"==typeof e){if("@"==(N?e.charAt(0):e[0]))return e.slice(1);if("["==e){for(t=[];e=J(),"]"!=e;r||(r=!0))r&&(","==e?(e=J(),"]"==e&&q()):q()),","==e&&q(),t.push(D(e));return t}if("{"==e){for(t={};e=J(),"}"!=e;r||(r=!0))r&&(","==e?(e=J(),"}"==e&&q()):q()),(","==e||"string"!=typeof e||"@"!=(N?e.charAt(0):e[0])||":"!=J())&&q(),t[e.slice(1)]=D(J());return t}q()}return e},B=function(e,t,r){var n=Z(e,t,r);n===m?delete e[t]:e[t]=n},Z=function(e,t,r){var n,o=e[t];if("object"==typeof o&&o)if(v.call(o)==O)for(n=o.length;n--;)B(o,n,r);else d(o,function(e){B(o,e,r)});return r.call(e,t,o)};n.parse=function(e,t){var r,n;return $=0,G=""+e,r=D(J()),"$"!=J()&&q(),$=G=null,t&&v.call(t)==w?Z((n={},n[""]=r,n),"",t):r}}}return n.runInContext=e,n}var t="function"==typeof define&&define.amd,r={"function":!0,object:!0},n=r[typeof exports]&&exports&&!exports.nodeType&&exports,o=r[typeof window]&&window||this,i=n&&r[typeof module]&&module&&!module.nodeType&&"object"==typeof global&&global;if(!i||i.global!==i&&i.window!==i&&i.self!==i||(o=i),n&&!t)e(o,n);else{var a=o.JSON,s=o.JSON3,u=!1,c=e(o,o.JSON3={noConflict:function(){return u||(u=!0,o.JSON=a,o.JSON3=s,a=s=null),c}});o.JSON={parse:c.parse,stringify:c.stringify}}t&&define(function(){return c})}.call(this),"undefined"==typeof Promise&&ES6Promise.polyfill(),Function.prototype.bind||(Function.prototype.bind=function(e){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var t=Array.prototype.slice.call(arguments,1),r=this,n=function(){},o=function(){return r.apply(this instanceof n&&e?this:e,t.concat(Array.prototype.slice.call(arguments)))};return n.prototype=this.prototype,o.prototype=new n,o}),Array.prototype.map||(Array.prototype.map=function(e,t){if(void 0===this||null===this)throw new TypeError("this is null or not defined");var r,n=Object(this),o=n.length>>>0;if("function"!=typeof e)throw new TypeError(e+" is not a function");arguments.length>1&&(r=t);for(var i=new Array(o),a=0;o>a;){var s,u;a in n&&(s=n[a],u=e.call(r,s,a,n),i[a]=u),a++}return i}),Array.prototype.filter||(Array.prototype.filter=function(e){if(void 0===this||null===this)throw new TypeError("this is null or not defined");var t=Object(this),r=t.length>>>0;if("function"!=typeof e)throw new TypeError(e+" is not a function");for(var n=[],o=arguments.length>=2?arguments[1]:void 0,i=0;r>i;i++)if(i in t){var a=t[i];e.call(o,a,i,t)&&n.push(a)}return n}),Array.prototype.forEach||(Array.prototype.forEach=function(e,t){var r,n;if(null===this||void 0===this)throw new TypeError(" this is null or not defined");var o=Object(this),i=o.length>>>0;if("function"!=typeof e)throw new TypeError(e+" is not a function");for(arguments.length>1&&(r=t),n=0;i>n;){var a;n in o&&(a=o[n],e.call(r,a,n,o)),n++}}),!function(e,t){"use strict";"function"==typeof define&&define.amd?define("stackframe",[],t):"object"==typeof exports?module.exports=t():e.StackFrame=t()}(this,function(){"use strict";function e(e){return!isNaN(parseFloat(e))&&isFinite(e)}function t(e,t,r,n,o){void 0!==e&&this.setFunctionName(e),void 0!==t&&this.setArgs(t),void 0!==r&&this.setFileName(r),void 0!==n&&this.setLineNumber(n),void 0!==o&&this.setColumnNumber(o)}return t.prototype={getFunctionName:function(){return this.functionName},setFunctionName:function(e){this.functionName=String(e)},getArgs:function(){return this.args},setArgs:function(e){if("[object Array]"!==Object.prototype.toString.call(e))throw new TypeError("Args must be an Array");this.args=e},getFileName:function(){return this.fileName},setFileName:function(e){this.fileName=String(e)},getLineNumber:function(){return this.lineNumber},setLineNumber:function(t){if(!e(t))throw new TypeError("Line Number must be a Number");this.lineNumber=Number(t)},getColumnNumber:function(){return this.columnNumber},setColumnNumber:function(t){if(!e(t))throw new TypeError("Column Number must be a Number");this.columnNumber=Number(t)},toString:function(){var t=this.getFunctionName()||"{anonymous}",r="("+(this.getArgs()||[]).join(",")+")",n=this.getFileName()?"@"+this.getFileName():"",o=e(this.getLineNumber())?":"+this.getLineNumber():"",i=e(this.getColumnNumber())?":"+this.getColumnNumber():"";return t+r+n+o+i}},t});var SourceMap=function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return e[n].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){var n;n=function(e,t,n){function o(e){var t=e;"string"==typeof e&&(t=JSON.parse(e.replace(/^\)\]\}'/,"")));var r=i.getArg(t,"version"),n=i.getArg(t,"sources"),o=i.getArg(t,"names",[]),a=i.getArg(t,"sourceRoot",null),u=i.getArg(t,"sourcesContent",null),c=i.getArg(t,"mappings"),l=i.getArg(t,"file",null);if(r!=this._version)throw new Error("Unsupported version: "+r);n=n.map(i.normalize),this._names=s.fromArray(o,!0),this._sources=s.fromArray(n,!0),this.sourceRoot=a,this.sourcesContent=u,this._mappings=c,this.file=l}var i=r(1),a=r(2),s=r(3).ArraySet,u=r(4);o.fromSourceMap=function(e){var t=Object.create(o.prototype);return t._names=s.fromArray(e._names.toArray(),!0),t._sources=s.fromArray(e._sources.toArray(),!0),t.sourceRoot=e._sourceRoot,t.sourcesContent=e._generateSourcesContent(t._sources.toArray(),t.sourceRoot),t.file=e._file,t.__generatedMappings=e._mappings.toArray().slice(),t.__originalMappings=e._mappings.toArray().slice().sort(i.compareByOriginalPositions),t},o.prototype._version=3,Object.defineProperty(o.prototype,"sources",{get:function(){return this._sources.toArray().map(function(e){return null!=this.sourceRoot?i.join(this.sourceRoot,e):e},this)}}),o.prototype.__generatedMappings=null,Object.defineProperty(o.prototype,"_generatedMappings",{get:function(){return this.__generatedMappings||(this.__generatedMappings=[],this.__originalMappings=[],this._parseMappings(this._mappings,this.sourceRoot)),this.__generatedMappings}}),o.prototype.__originalMappings=null,Object.defineProperty(o.prototype,"_originalMappings",{get:function(){return this.__originalMappings||(this.__generatedMappings=[],this.__originalMappings=[],this._parseMappings(this._mappings,this.sourceRoot)),this.__originalMappings}}),o.prototype._nextCharIsMappingSeparator=function(e){var t=e.charAt(0);return";"===t||","===t},o.prototype._parseMappings=function(e,t){for(var r,n=1,o=0,a=0,s=0,c=0,l=0,f=e,p={};f.length>0;)if(";"===f.charAt(0))n++,f=f.slice(1),o=0;else if(","===f.charAt(0))f=f.slice(1);else{if(r={},r.generatedLine=n,u.decode(f,p),r.generatedColumn=o+p.value,o=r.generatedColumn,f=p.rest,f.length>0&&!this._nextCharIsMappingSeparator(f)){if(u.decode(f,p),r.source=this._sources.at(c+p.value),c+=p.value,f=p.rest,0===f.length||this._nextCharIsMappingSeparator(f))throw new Error("Found a source, but no line and column");if(u.decode(f,p),r.originalLine=a+p.value,a=r.originalLine,r.originalLine+=1,f=p.rest,0===f.length||this._nextCharIsMappingSeparator(f))throw new Error("Found a source and line, but no column");u.decode(f,p),r.originalColumn=s+p.value,s=r.originalColumn,f=p.rest,f.length>0&&!this._nextCharIsMappingSeparator(f)&&(u.decode(f,p),r.name=this._names.at(l+p.value),l+=p.value,f=p.rest)}this.__generatedMappings.push(r),"number"==typeof r.originalLine&&this.__originalMappings.push(r)}this.__generatedMappings.sort(i.compareByGeneratedPositions),this.__originalMappings.sort(i.compareByOriginalPositions)},o.prototype._findMapping=function(e,t,r,n,o){if(e[r]<=0)throw new TypeError("Line must be greater than or equal to 1, got "+e[r]);if(e[n]<0)throw new TypeError("Column must be greater than or equal to 0, got "+e[n]);return a.search(e,t,o)},o.prototype.computeColumnSpans=function(){for(var e=0;e=0){var n=this._generatedMappings[r];if(n.generatedLine===t.generatedLine){var o=i.getArg(n,"source",null);return null!=o&&null!=this.sourceRoot&&(o=i.join(this.sourceRoot,o)),{source:o,line:i.getArg(n,"originalLine",null),column:i.getArg(n,"originalColumn",null),name:i.getArg(n,"name",null)}}}return{source:null,line:null,column:null,name:null}},o.prototype.sourceContentFor=function(e){if(!this.sourcesContent)return null;if(null!=this.sourceRoot&&(e=i.relative(this.sourceRoot,e)),this._sources.has(e))return this.sourcesContent[this._sources.indexOf(e)];var t;if(null!=this.sourceRoot&&(t=i.urlParse(this.sourceRoot))){var r=e.replace(/^file:\/\//,"");if("file"==t.scheme&&this._sources.has(r))return this.sourcesContent[this._sources.indexOf(r)];if((!t.path||"/"==t.path)&&this._sources.has("/"+e))return this.sourcesContent[this._sources.indexOf("/"+e)]}throw new Error('"'+e+'" is not in the SourceMap.')},o.prototype.generatedPositionFor=function(e){var t={source:i.getArg(e,"source"),originalLine:i.getArg(e,"line"),originalColumn:i.getArg(e,"column")};null!=this.sourceRoot&&(t.source=i.relative(this.sourceRoot,t.source));var r=this._findMapping(t,this._originalMappings,"originalLine","originalColumn",i.compareByOriginalPositions);if(r>=0){var n=this._originalMappings[r];return{line:i.getArg(n,"generatedLine",null),column:i.getArg(n,"generatedColumn",null),lastColumn:i.getArg(n,"lastGeneratedColumn",null)}}return{line:null,column:null,lastColumn:null}},o.prototype.allGeneratedPositionsFor=function(e){var t={source:i.getArg(e,"source"),originalLine:i.getArg(e,"line"),originalColumn:1/0};null!=this.sourceRoot&&(t.source=i.relative(this.sourceRoot,t.source));var r=[],n=this._findMapping(t,this._originalMappings,"originalLine","originalColumn",i.compareByOriginalPositions);if(n>=0)for(var o=this._originalMappings[n];o&&o.originalLine===t.originalLine;)r.push({line:i.getArg(o,"generatedLine",null),column:i.getArg(o,"generatedColumn",null),lastColumn:i.getArg(o,"lastGeneratedColumn",null)}),o=this._originalMappings[--n];return r.reverse()},o.GENERATED_ORDER=1,o.ORIGINAL_ORDER=2,o.prototype.eachMapping=function(e,t,r){var n,a=t||null,s=r||o.GENERATED_ORDER;switch(s){case o.GENERATED_ORDER:n=this._generatedMappings;break;case o.ORIGINAL_ORDER:n=this._originalMappings;break;default:throw new Error("Unknown order of iteration.")}var u=this.sourceRoot;n.map(function(e){var t=e.source;return null!=t&&null!=u&&(t=i.join(u,t)),{source:t,generatedLine:e.generatedLine,generatedColumn:e.generatedColumn,originalLine:e.originalLine,originalColumn:e.originalColumn,name:e.name}}).forEach(e,a)},t.SourceMapConsumer=o}.call(t,r,t,e),!(void 0!==n&&(e.exports=n))},function(e,t,r){var n;n=function(e,t,r){function n(e,t,r){if(t in e)return e[t];if(3===arguments.length)return r;throw new Error('"'+t+'" is a required argument.')}function o(e){var t=e.match(g);return t?{scheme:t[1],auth:t[2],host:t[3],port:t[4],path:t[5]}:null}function i(e){var t="";return e.scheme&&(t+=e.scheme+":"),t+="//",e.auth&&(t+=e.auth+"@"),e.host&&(t+=e.host),e.port&&(t+=":"+e.port),e.path&&(t+=e.path),t}function a(e){var t=e,r=o(e);if(r){if(!r.path)return e;t=r.path}for(var n,a="/"===t.charAt(0),s=t.split(/\/+/),u=0,c=s.length-1;c>=0;c--)n=s[c],"."===n?s.splice(c,1):".."===n?u++:u>0&&(""===n?(s.splice(c+1,u),u=0):(s.splice(c,2),u--));return t=s.join("/"),""===t&&(t=a?"/":"."),r?(r.path=t,i(r)):t}function s(e,t){""===e&&(e="."),""===t&&(t=".");var r=o(t),n=o(e);if(n&&(e=n.path||"/"),r&&!r.scheme)return n&&(r.scheme=n.scheme),i(r);if(r||t.match(d))return t;if(n&&!n.host&&!n.path)return n.host=t,i(n);var s="/"===t.charAt(0)?t:a(e.replace(/\/+$/,"")+"/"+t);return n?(n.path=s,i(n)):s}function u(e,t){""===e&&(e="."),e=e.replace(/\/$/,"");var r=o(e);return"/"==t.charAt(0)&&r&&"/"==r.path?t.slice(1):0===t.indexOf(e+"/")?t.substr(e.length+1):t}function c(e){return"$"+e}function l(e){return e.substr(1)}function f(e,t){var r=e||"",n=t||"";return(r>n)-(n>r)}function p(e,t,r){var n;return(n=f(e.source,t.source))?n:(n=e.originalLine-t.originalLine)?n:(n=e.originalColumn-t.originalColumn,n||r?n:(n=f(e.name,t.name))?n:(n=e.generatedLine-t.generatedLine,n?n:e.generatedColumn-t.generatedColumn))}function h(e,t,r){var n;return(n=e.generatedLine-t.generatedLine)?n:(n=e.generatedColumn-t.generatedColumn,n||r?n:(n=f(e.source,t.source))?n:(n=e.originalLine-t.originalLine)?n:(n=e.originalColumn-t.originalColumn,n?n:f(e.name,t.name)))}t.getArg=n;var g=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/,d=/^data:.+\,.+$/;t.urlParse=o,t.urlGenerate=i,t.normalize=a,t.join=s,t.relative=u,t.toSetString=c,t.fromSetString=l,t.compareByOriginalPositions=p,t.compareByGeneratedPositions=h}.call(t,r,t,e),!(void 0!==n&&(e.exports=n))},function(e,t,r){var n;n=function(e,t,r){function n(e,t,r,o,i){var a=Math.floor((t-e)/2)+e,s=i(r,o[a],!0);return 0===s?a:s>0?t-a>1?n(a,t,r,o,i):a:a-e>1?n(e,a,r,o,i):0>e?-1:e}t.search=function(e,t,r){return 0===t.length?-1:n(-1,t.length,e,t,r)}}.call(t,r,t,e),!(void 0!==n&&(e.exports=n))},function(e,t,r){var n;n=function(e,t,n){function o(){this._array=[],this._set={}}var i=r(1);o.fromArray=function(e,t){for(var r=new o,n=0,i=e.length;i>n;n++)r.add(e[n],t);return r},o.prototype.add=function(e,t){var r=this.has(e),n=this._array.length;(!r||t)&&this._array.push(e),r||(this._set[i.toSetString(e)]=n)},o.prototype.has=function(e){return Object.prototype.hasOwnProperty.call(this._set,i.toSetString(e))},o.prototype.indexOf=function(e){if(this.has(e))return this._set[i.toSetString(e)];throw new Error('"'+e+'" is not in the set.')},o.prototype.at=function(e){if(e>=0&&ee?(-e<<1)+1:(e<<1)+0}function i(e){var t=1===(1&e),r=e>>1;return t?-r:r}var a=r(5),s=5,u=1<>>=s,n>0&&(t|=l),r+=a.encode(t);while(n>0);return r},t.decode=function(e,t){var r,n,o=0,u=e.length,f=0,p=0;do{if(o>=u)throw new Error("Expected more digits in base 64 VLQ value.");n=a.decode(e.charAt(o++)),r=!!(n&l),n&=c,f+=n<=200&&o.status<400)return t(o.responseText);n(new Error("Unable to retrieve "+e))}},o.send()}function o(e,t,r){for(var n,o,i,a=/function\s+([^(]*?)\s*\(([^)]*)\)/,s=/['"]?([$_A-Za-z][$_A-Za-z0-9]*)['"]?\s*[:=]\s*function\b/,u=/['"]?([$_A-Za-z][$_A-Za-z0-9]*)['"]?\s*[:=]\s*(?:eval|new Function)\b/,c=e.split("\n"),l="",f=Math.min(t,20),p=0;f>p;++p)if(n=c[t-p-1],i=n.indexOf("//"),i>=0&&(n=n.substr(0,i)),n){if(l=n+l,o=s.exec(l),o&&o[1])return o[1];if(o=a.exec(l),o&&o[1])return o[1];if(o=u.exec(l),o&&o[1])return o[1]}return void 0}function i(){if("function"!=typeof Object.defineProperty||"function"!=typeof Object.create)throw new Error("Unable to consume source maps in older browsers")}function a(e){if("object"!=typeof e)throw new TypeError("Given StackFrame is not an object");if("string"!=typeof e.fileName)throw new TypeError("Given file name is not a String");if("number"!=typeof e.lineNumber||e.lineNumber%1!==0||e.lineNumber<1)throw new TypeError("Given line number must be a positive integer");if("number"!=typeof e.columnNumber||e.columnNumber%1!==0||e.columnNumber<0)throw new TypeError("Given column number must be a non-negative integer");return!0}function s(e){var t=/\/\/[#@] ?sourceMappingURL=([^\s'"]+)$/.exec(e);if(t&&t[1])return t[1];throw new Error("sourceMappingURL not found")}function u(r,n,o,i){var a=new e.SourceMapConsumer(r).originalPositionFor({line:o,column:i});return new t(a.name,n,a.source,a.line,a.column)}return function c(e){return this instanceof c?(e=e||{},this.sourceCache=e.sourceCache||{},this.ajax=n,this._atob=function(e){if(window&&window.atob)return window.atob(e);if("undefined"!=typeof Buffer)return new Buffer(e,"base64").toString("utf-8");throw new Error("No base64 decoder available")},this._get=function(t){return new Promise(function(r,n){var o="data:"===t.substr(0,5);if(this.sourceCache[t])r(this.sourceCache[t]);else if(e.offline&&!o)n(new Error("Cannot make network requests in offline mode"));else if(o){var i="application/json;base64";if(t.substr(5,i.length)!==i)n(new Error("The encoding of the inline sourcemap is not supported"));else{var a="data:".length+i.length+",".length,s=t.substr(a),u=this._atob(s);this.sourceCache[t]=u,r(u)}}else this.ajax(t,function(e){this.sourceCache[t]=e,r(e)}.bind(this),n)}.bind(this))},this.pinpoint=function(e){return new Promise(function(t,r){this.getMappedLocation(e).then(function(e){function r(){t(e)}this.findFunctionName(e).then(t,r)["catch"](r)}.bind(this),r)}.bind(this))},this.findFunctionName=function(e){return new Promise(function(r,n){a(e),this._get(e.fileName).then(function(n){var i=o(n,e.lineNumber,e.columnNumber);r(new t(i,e.args,e.fileName,e.lineNumber,e.columnNumber))},n)}.bind(this))},void(this.getMappedLocation=function(e){return new Promise(function(t,r){i(),a(e);var n=e.fileName;this._get(n).then(function(o){var i=s(o);"/"!==i[0]&&(i=n.substring(0,n.lastIndexOf("/")+1)+i),this._get(i).then(function(r){var n=e.lineNumber,o=e.columnNumber;t(u(r,e.args,n,o))},r)["catch"](r)}.bind(this),r)["catch"](r)}.bind(this))})):new c(e)}}),function(e,t){"use strict";"function"==typeof define&&define.amd?define("stack-generator",["stackframe"],t):"object"==typeof exports?module.exports=t(require("stackframe")):e.StackGenerator=t(e.StackFrame)}(this,function(e){return{backtrace:function(t){var r=[],n=10;"object"==typeof t&&"number"==typeof t.maxStackSize&&(n=t.maxStackSize);for(var o=arguments.callee;o&&r.length-1&&e.message.split("\n").length>e.stacktrace.split("\n").length?this.parseOpera9(e):e.stack?this.parseOpera11(e):this.parseOpera10(e)},parseOpera9:function(t){for(var r=/Line (\d+).*script (?:in )?(\S+)/i,n=t.message.split("\n"),o=[],i=2,a=n.length;a>i;i+=2){var s=r.exec(n[i]);s&&o.push(new e(void 0,void 0,s[2],s[1],void 0,n[i]))}return o},parseOpera10:function(t){for(var r=/Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i,n=t.stacktrace.split("\n"),o=[],i=0,a=n.length;a>i;i+=2){var s=r.exec(n[i]);s&&o.push(new e(s[3]||void 0,void 0,s[2],s[1],void 0,n[i]))}return o},parseOpera11:function(r){return r.stack.split("\n").filter(function(e){return!!e.match(t)&&!e.match(/^Error created at/)},this).map(function(t){var r,n=t.split("@"),o=this.extractLocation(n.pop()),i=n.shift()||"",a=i.replace(//,"$2").replace(/\([^\)]*\)/g,"")||void 0;i.match(/\(([^\)]*)\)/)&&(r=i.replace(/^[^\(]+\(([^\)]*)\)$/,"$1"));var s=void 0===r||"[arguments not available]"===r?void 0:r.split(",");return new e(a,s,o[0],o[1],o[2],t)},this)}}}),function(e,t){"use strict";"function"==typeof define&&define.amd?define("stacktrace",["error-stack-parser","stack-generator","stacktrace-gps"],t):"object"==typeof exports?module.exports=t(require("error-stack-parser"),require("stack-generator"),require("stacktrace-gps")):e.StackTrace=t(e.ErrorStackParser,e.StackGenerator,e.StackTraceGPS)}(this,function(e,t,r){function n(e,t){var r={};return[e,t].forEach(function(e){for(var t in e)e.hasOwnProperty(t)&&(r[t]=e[t]);return r}),r}function o(e){return e.stack||e["opera#sourceloc"]}var i={filter:function(e){return-1===(e.functionName||"").indexOf("StackTrace$$")&&-1===(e.functionName||"").indexOf("ErrorStackParser$$")&&-1===(e.functionName||"").indexOf("StackTraceGPS$$")&&-1===(e.functionName||"").indexOf("StackGenerator$$")}};return{get:function(e){try{throw new Error}catch(t){return o(t)?this.fromError(t,e):this.generateArtificially(e)}},fromError:function(t,o){return o=n(i,o),new Promise(function(n){var i=e.parse(t);"function"==typeof o.filter&&(i=i.filter(o.filter)),n(Promise.all(i.map(function(e){return new Promise(function(t){function n(r){t(e)}new r(o).pinpoint(e).then(t,n)["catch"](n)})})))}.bind(this))},generateArtificially:function(e){e=n(i,e);var r=t.backtrace(e);return"function"==typeof e.filter&&(r=r.filter(e.filter)),Promise.resolve(r)},instrument:function(e,t,r,n){if("function"!=typeof e)throw new Error("Cannot instrument non-function object");if("function"==typeof e.__stacktraceOriginalFn)return e;var i=function(){try{this.get().then(t,r)["catch"](r),e.apply(n||this,arguments)}catch(i){throw o(i)&&this.fromError(i).then(t,r)["catch"](r),i}}.bind(this);return i.__stacktraceOriginalFn=e,i},deinstrument:function(e){if("function"!=typeof e)throw new Error("Cannot de-instrument non-function object");return"function"==typeof e.__stacktraceOriginalFn?e.__stacktraceOriginalFn:e},report:function(e,t){return new Promise(function(r,n){var o=new XMLHttpRequest;o.onerror=n,o.onreadystatechange=function(){4===o.readyState&&(o.status>=200&&o.status<400?r(o.responseText):n(new Error("POST to "+t+" failed with status: "+o.status)))},o.open("post",t),o.setRequestHeader("Content-Type","application/json"),o.send(JSON.stringify({stack:e}))})}}}); //# sourceMappingURL=vendor/stacktrace-js/dist/stacktrace-with-polyfills.min.js.map -/** - * Lightbox v2.7.1 - * by Lokesh Dhakar - http://lokeshdhakar.com/projects/lightbox2/ - * - * @license http://creativecommons.org/licenses/by/2.5/ - * - Free for use in both personal and commercial projects - * - Attribution requires leaving author name, author link, and the license info intact - */ -(function(){var a=jQuery,b=function(){function a(){this.fadeDuration=500,this.fitImagesInViewport=!0,this.resizeDuration=700,this.positionFromTop=50,this.showImageNumberLabel=!0,this.alwaysShowNavOnTouchDevices=!1,this.wrapAround=!1}return a.prototype.albumLabel=function(a,b){return"Image "+a+" of "+b},a}(),c=function(){function b(a){this.options=a,this.album=[],this.currentImageIndex=void 0,this.init()}return b.prototype.init=function(){this.enable(),this.build()},b.prototype.enable=function(){var b=this;a("body").on("click","a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]",function(c){return b.start(a(c.currentTarget)),!1})},b.prototype.build=function(){var b=this;a("
").appendTo(a("body")),this.$lightbox=a("#lightbox"),this.$overlay=a("#lightboxOverlay"),this.$outerContainer=this.$lightbox.find(".lb-outerContainer"),this.$container=this.$lightbox.find(".lb-container"),this.containerTopPadding=parseInt(this.$container.css("padding-top"),10),this.containerRightPadding=parseInt(this.$container.css("padding-right"),10),this.containerBottomPadding=parseInt(this.$container.css("padding-bottom"),10),this.containerLeftPadding=parseInt(this.$container.css("padding-left"),10),this.$overlay.hide().on("click",function(){return b.end(),!1}),this.$lightbox.hide().on("click",function(c){return"lightbox"===a(c.target).attr("id")&&b.end(),!1}),this.$outerContainer.on("click",function(c){return"lightbox"===a(c.target).attr("id")&&b.end(),!1}),this.$lightbox.find(".lb-prev").on("click",function(){return b.changeImage(0===b.currentImageIndex?b.album.length-1:b.currentImageIndex-1),!1}),this.$lightbox.find(".lb-next").on("click",function(){return b.changeImage(b.currentImageIndex===b.album.length-1?0:b.currentImageIndex+1),!1}),this.$lightbox.find(".lb-loader, .lb-close").on("click",function(){return b.end(),!1})},b.prototype.start=function(b){function c(a){d.album.push({link:a.attr("href"),title:a.attr("data-title")||a.attr("title")})}var d=this,e=a(window);e.on("resize",a.proxy(this.sizeOverlay,this)),a("select, object, embed").css({visibility:"hidden"}),this.sizeOverlay(),this.album=[];var f,g=0,h=b.attr("data-lightbox");if(h){f=a(b.prop("tagName")+'[data-lightbox="'+h+'"]');for(var i=0;ij||e.height>i)&&(e.width/j>e.height/i?(h=j,g=parseInt(e.height/(e.width/h),10),d.width(h),d.height(g)):(g=i,h=parseInt(e.width/(e.height/g),10),d.width(h),d.height(g)))),c.sizeContainer(d.width(),d.height())},e.src=this.album[b].link,this.currentImageIndex=b},b.prototype.sizeOverlay=function(){this.$overlay.width(a(window).width()).height(a(document).height())},b.prototype.sizeContainer=function(a,b){function c(){d.$lightbox.find(".lb-dataContainer").width(g),d.$lightbox.find(".lb-prevLink").height(h),d.$lightbox.find(".lb-nextLink").height(h),d.showImage()}var d=this,e=this.$outerContainer.outerWidth(),f=this.$outerContainer.outerHeight(),g=a+this.containerLeftPadding+this.containerRightPadding,h=b+this.containerTopPadding+this.containerBottomPadding;e!==g||f!==h?this.$outerContainer.animate({width:g,height:h},this.options.resizeDuration,"swing",function(){c()}):c()},b.prototype.showImage=function(){this.$lightbox.find(".lb-loader").hide(),this.$lightbox.find(".lb-image").fadeIn("slow"),this.updateNav(),this.updateDetails(),this.preloadNeighboringImages(),this.enableKeyboardNav()},b.prototype.updateNav=function(){var a=!1;try{document.createEvent("TouchEvent"),a=this.options.alwaysShowNavOnTouchDevices?!0:!1}catch(b){}this.$lightbox.find(".lb-nav").show(),this.album.length>1&&(this.options.wrapAround?(a&&this.$lightbox.find(".lb-prev, .lb-next").css("opacity","1"),this.$lightbox.find(".lb-prev, .lb-next").show()):(this.currentImageIndex>0&&(this.$lightbox.find(".lb-prev").show(),a&&this.$lightbox.find(".lb-prev").css("opacity","1")),this.currentImageIndex1&&this.options.showImageNumberLabel?this.$lightbox.find(".lb-number").text(this.options.albumLabel(this.currentImageIndex+1,this.album.length)).fadeIn("fast"):this.$lightbox.find(".lb-number").hide(),this.$outerContainer.removeClass("animating"),this.$lightbox.find(".lb-dataContainer").fadeIn(this.options.resizeDuration,function(){return b.sizeOverlay()})},b.prototype.preloadNeighboringImages=function(){if(this.album.length>this.currentImageIndex+1){var a=new Image;a.src=this.album[this.currentImageIndex+1].link}if(this.currentImageIndex>0){var b=new Image;b.src=this.album[this.currentImageIndex-1].link}},b.prototype.enableKeyboardNav=function(){a(document).on("keyup.keyboard",a.proxy(this.keyboardAction,this))},b.prototype.disableKeyboardNav=function(){a(document).off(".keyboard")},b.prototype.keyboardAction=function(a){var b=27,c=37,d=39,e=a.keyCode,f=String.fromCharCode(e).toLowerCase();e===b||f.match(/x|o|c/)?this.end():"p"===f||e===c?0!==this.currentImageIndex?this.changeImage(this.currentImageIndex-1):this.options.wrapAround&&this.album.length>1&&this.changeImage(this.album.length-1):("n"===f||e===d)&&(this.currentImageIndex!==this.album.length-1?this.changeImage(this.currentImageIndex+1):this.options.wrapAround&&this.album.length>1&&this.changeImage(0))},b.prototype.end=function(){this.disableKeyboardNav(),a(window).off("resize",this.sizeOverlay),this.$lightbox.fadeOut(this.options.fadeDuration),this.$overlay.fadeOut(this.options.fadeDuration),a("select, object, embed").css({visibility:"visible"})},b}();a(function(){{var a=new b;new c(a)}})}).call(this); /* ============================================================= * bootstrap-combobox.js v1.1.5 * ============================================================= @@ -30907,6 +30898,14 @@ function actionListHandler() { }); } +function loadImages(selector) { + $(selector + ' img').each(function(index, item) { + var src = $(item).attr('data-src'); + $(item).attr('src', src); + $(item).attr('data-src', src); + }); +} + var NINJA = NINJA || {}; NINJA.TEMPLATES = { diff --git a/public/css/built.css b/public/css/built.css index 5a511b0f1f1b..763b433e6a0f 100644 --- a/public/css/built.css +++ b/public/css/built.css @@ -2138,217 +2138,6 @@ See http://bgrins.github.io/spectrum/themes/ for instructions. border-radius: 6px; line-height: 1.33; } -/* Preload images */ -body:after { - content: url(../images/lightbox/close.png) url(../images/lightbox/loading.gif) url(../images/lightbox/prev.png) url(../images/lightbox/next.png); - display: none; -} - -.lightboxOverlay { - position: absolute; - top: 0; - left: 0; - z-index: 9999; - background-color: black; - filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); - opacity: 0.8; - display: none; -} - -.lightbox { - position: absolute; - left: 0; - width: 100%; - z-index: 10000; - text-align: center; - line-height: 0; - font-weight: normal; -} - -.lightbox .lb-image { - display: block; - height: auto; - max-width: inherit; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - -ms-border-radius: 3px; - -o-border-radius: 3px; - border-radius: 3px; -} - -.lightbox a img { - border: none; -} - -.lb-outerContainer { - position: relative; - background-color: white; - *zoom: 1; - width: 250px; - height: 250px; - margin: 0 auto; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 4px; -} - -.lb-outerContainer:after { - content: ""; - display: table; - clear: both; -} - -.lb-container { - padding: 4px; -} - -.lb-loader { - position: absolute; - top: 43%; - left: 0; - height: 25%; - width: 100%; - text-align: center; - line-height: 0; -} - -.lb-cancel { - display: block; - width: 32px; - height: 32px; - margin: 0 auto; - background: url(../images/lightbox/loading.gif) no-repeat; -} - -.lb-nav { - position: absolute; - top: 0; - left: 0; - height: 100%; - width: 100%; - z-index: 10; -} - -.lb-container > .nav { - left: 0; -} - -.lb-nav a { - outline: none; - background-image: url('data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='); -} - -.lb-prev, .lb-next { - height: 100%; - cursor: pointer; - display: block; -} - -.lb-nav a.lb-prev { - width: 34%; - left: 0; - float: left; - background: url(../images/lightbox/prev.png) left 48% no-repeat; - filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0); - opacity: 0; - -webkit-transition: opacity 0.6s; - -moz-transition: opacity 0.6s; - -o-transition: opacity 0.6s; - transition: opacity 0.6s; -} - -.lb-nav a.lb-prev:hover { - filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100); - opacity: 1; -} - -.lb-nav a.lb-next { - width: 64%; - right: 0; - float: right; - background: url(../images/lightbox/next.png) right 48% no-repeat; - filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0); - opacity: 0; - -webkit-transition: opacity 0.6s; - -moz-transition: opacity 0.6s; - -o-transition: opacity 0.6s; - transition: opacity 0.6s; -} - -.lb-nav a.lb-next:hover { - filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100); - opacity: 1; -} - -.lb-dataContainer { - margin: 0 auto; - padding-top: 5px; - *zoom: 1; - width: 100%; - -moz-border-radius-bottomleft: 4px; - -webkit-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; - -moz-border-radius-bottomright: 4px; - -webkit-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; -} - -.lb-dataContainer:after { - content: ""; - display: table; - clear: both; -} - -.lb-data { - padding: 0 4px; - color: #ccc; -} - -.lb-data .lb-details { - width: 85%; - float: left; - text-align: left; - line-height: 1.1em; -} - -.lb-data .lb-caption { - font-size: 13px; - font-weight: bold; - line-height: 1em; -} - -.lb-data .lb-number { - display: block; - clear: left; - padding-bottom: 1em; - font-size: 12px; - color: #999999; -} - -.lb-data .lb-close { - display: block; - float: right; - width: 30px; - height: 30px; - background: url(../images/lightbox/close.png) top right no-repeat; - text-align: right; - outline: none; - filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70); - opacity: 0.7; - -webkit-transition: opacity 0.2s; - -moz-transition: opacity 0.2s; - -o-transition: opacity 0.2s; - transition: opacity 0.2s; -} - -.lb-data .lb-close:hover { - cursor: pointer; - filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100); - opacity: 1; -} - body { background: #f8f8f8 !important; font-family: 'Roboto', sans-serif; font-size: 15px; diff --git a/public/js/script.js b/public/js/script.js index a98db86385aa..2dc527f6d3d4 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -1025,3 +1025,11 @@ function actionListHandler() { } }); } + +function loadImages(selector) { + $(selector + ' img').each(function(index, item) { + var src = $(item).attr('data-src'); + $(item).attr('src', src); + $(item).attr('data-src', src); + }); +} diff --git a/resources/views/accounts/invoice_design.blade.php b/resources/views/accounts/invoice_design.blade.php index 2c7468cb1652..09bb55bfb1ba 100644 --- a/resources/views/accounts/invoice_design.blade.php +++ b/resources/views/accounts/invoice_design.blade.php @@ -7,7 +7,9 @@ @foreach ($account->getFontFolders() as $font) @endforeach - + + + @stop diff --git a/resources/views/header.blade.php b/resources/views/header.blade.php index e5f52b0a7a90..6074859a018b 100644 --- a/resources/views/header.blade.php +++ b/resources/views/header.blade.php @@ -736,7 +736,7 @@ @if (Auth::user()->account->isWhiteLabel()) {{ trans('texts.white_labeled') }} @else - {{ trans('texts.white_label_link') }} + {{ trans('texts.white_label_link') }}