From 4586c1ef52b56d35733b2295361acab58926efaa Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 27 Feb 2015 20:45:17 +0100 Subject: [PATCH 01/87] Removed all test cases. --- codeception.yml | 18 - composer.json | 13 +- composer.lock | 1239 +---------------- phpunit.xml | 3 +- tests/_bootstrap.php | 9 - tests/_data/db.sh | 6 - tests/_support/AcceptanceHelper.php | 10 - tests/_support/FunctionalHelper.php | 10 - tests/_support/UnitHelper.php | 10 - tests/acceptance.suite.yml | 10 - tests/acceptance/_bootstrap.php | 2 - tests/functional.suite.yml | 20 - tests/functional/AccountControllerCest.php | 202 --- tests/functional/BillControllerCest.php | 278 ---- tests/functional/BudgetControllerCest.php | 242 ---- tests/functional/CategoryControllerCest.php | 201 --- tests/functional/CurrencyControllerCest.php | 202 --- .../functional/GoogleChartControllerCest.php | 201 --- tests/functional/HelpControllerCest.php | 89 -- tests/functional/HomeControllerCest.php | 98 -- tests/functional/JsonControllerCest.php | 56 - tests/functional/PiggyBankControllerCest.php | 356 ----- .../functional/PreferencesControllerCest.php | 48 - tests/functional/ProfileControllerCest.php | 150 -- tests/functional/RelatedControllerCest.php | 120 -- tests/functional/ReminderControllerCest.php | 87 -- .../RepeatedExpenseControllerCest.php | 298 ---- tests/functional/ReportControllerCest.php | 100 -- tests/functional/SearchControllerCest.php | 45 - .../functional/TransactionControllerCest.php | 416 ------ tests/functional/UserControllerCest.php | 150 -- tests/functional/_bootstrap.php | 8 - tests/unit.suite.yml | 6 - tests/unit/AccountTest.php | 40 - tests/unit/AccountTypeTest.php | 27 - tests/unit/BudgetTest.php | 26 - tests/unit/PiggyBankRepetitionTest.php | 29 - tests/unit/PiggyBankTest.php | 27 - tests/unit/ReminderTest.php | 38 - tests/unit/TransactionGroupTest.php | 25 - tests/unit/TransactionJournalTest.php | 33 - tests/unit/TransactionTest.php | 67 - tests/unit/TransactionTypeTest.php | 30 - tests/unit/UserTest.php | 36 - tests/unit/_bootstrap.php | 2 - 45 files changed, 72 insertions(+), 5011 deletions(-) delete mode 100644 codeception.yml delete mode 100644 tests/_bootstrap.php delete mode 100755 tests/_data/db.sh delete mode 100644 tests/_support/AcceptanceHelper.php delete mode 100644 tests/_support/FunctionalHelper.php delete mode 100644 tests/_support/UnitHelper.php delete mode 100644 tests/acceptance.suite.yml delete mode 100644 tests/acceptance/_bootstrap.php delete mode 100644 tests/functional.suite.yml delete mode 100644 tests/functional/AccountControllerCest.php delete mode 100644 tests/functional/BillControllerCest.php delete mode 100644 tests/functional/BudgetControllerCest.php delete mode 100644 tests/functional/CategoryControllerCest.php delete mode 100644 tests/functional/CurrencyControllerCest.php delete mode 100644 tests/functional/GoogleChartControllerCest.php delete mode 100644 tests/functional/HelpControllerCest.php delete mode 100644 tests/functional/HomeControllerCest.php delete mode 100644 tests/functional/JsonControllerCest.php delete mode 100644 tests/functional/PiggyBankControllerCest.php delete mode 100644 tests/functional/PreferencesControllerCest.php delete mode 100644 tests/functional/ProfileControllerCest.php delete mode 100644 tests/functional/RelatedControllerCest.php delete mode 100644 tests/functional/ReminderControllerCest.php delete mode 100644 tests/functional/RepeatedExpenseControllerCest.php delete mode 100644 tests/functional/ReportControllerCest.php delete mode 100644 tests/functional/SearchControllerCest.php delete mode 100644 tests/functional/TransactionControllerCest.php delete mode 100644 tests/functional/UserControllerCest.php delete mode 100644 tests/functional/_bootstrap.php delete mode 100644 tests/unit.suite.yml delete mode 100644 tests/unit/AccountTest.php delete mode 100644 tests/unit/AccountTypeTest.php delete mode 100644 tests/unit/BudgetTest.php delete mode 100644 tests/unit/PiggyBankRepetitionTest.php delete mode 100644 tests/unit/PiggyBankTest.php delete mode 100644 tests/unit/ReminderTest.php delete mode 100644 tests/unit/TransactionGroupTest.php delete mode 100644 tests/unit/TransactionJournalTest.php delete mode 100644 tests/unit/TransactionTest.php delete mode 100644 tests/unit/TransactionTypeTest.php delete mode 100644 tests/unit/UserTest.php delete mode 100644 tests/unit/_bootstrap.php diff --git a/codeception.yml b/codeception.yml deleted file mode 100644 index 3284792656..0000000000 --- a/codeception.yml +++ /dev/null @@ -1,18 +0,0 @@ -actor: Tester -paths: - tests: tests - log: tests/_output - data: tests/_data - helpers: tests/_support -settings: - bootstrap: _bootstrap.php - colors: true - memory_limit: 1024M -modules: - config: -coverage: - enabled: true - remote: false - whitelist: - include: - - app/* \ No newline at end of file diff --git a/composer.json b/composer.json index 59a4fbdd9c..06b22adc7b 100644 --- a/composer.json +++ b/composer.json @@ -26,23 +26,14 @@ "watson/validating": "dev-master", "doctrine/dbal": "~2.5", "illuminate/html": "~5.0", - "barryvdh/laravel-ide-helper": "~2.0", "league/commonmark": "0.7.*" }, "require-dev": { "barryvdh/laravel-debugbar": "@stable", + "barryvdh/laravel-ide-helper": "~2.0", "phpunit/phpunit": "~4.0", - "phpspec/phpspec": "~2.1", - "codeception/codeception": "@stable", - "codeception/c3": "@stable", - "league/factory-muffin": "~2.1", - "codeception/phpbuiltinserver": "*", - "codeception/specify": "*", - "codeception/verify": "*", - "fzaninotto/faker": "1.*", - "codeclimate/php-test-reporter": "dev-master" - + "phpspec/phpspec": "~2.1" }, "autoload": { "classmap": [ diff --git a/composer.lock b/composer.lock index 95b03522ad..535b49e4e9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,71 +4,8 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "d78d46376975c1bfab9823b66a30ed5f", + "hash": "16fc4f36aacc020097a22c4fe7ef7687", "packages": [ - { - "name": "barryvdh/laravel-ide-helper", - "version": "v2.0.1", - "source": { - "type": "git", - "url": "https://github.com/barryvdh/laravel-ide-helper.git", - "reference": "81b7febfc64168ea1af57261aa4dfc9acefd5429" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/81b7febfc64168ea1af57261aa4dfc9acefd5429", - "reference": "81b7febfc64168ea1af57261aa4dfc9acefd5429", - "shasum": "" - }, - "require": { - "illuminate/console": "5.0.x", - "illuminate/filesystem": "5.0.x", - "illuminate/support": "5.0.x", - "php": ">=5.4.0", - "phpdocumentor/reflection-docblock": "2.0.x", - "symfony/class-loader": "~2.3" - }, - "require-dev": { - "doctrine/dbal": "~2.3" - }, - "suggest": { - "doctrine/dbal": "Load information from the database about models for phpdocs (~2.3)" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "psr-4": { - "Barryvdh\\LaravelIdeHelper\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Barry vd. Heuvel", - "email": "barryvdh@gmail.com" - } - ], - "description": "Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.", - "keywords": [ - "autocomplete", - "codeintel", - "helper", - "ide", - "laravel", - "netbeans", - "phpdoc", - "phpstorm", - "sublime" - ], - "time": "2015-02-23 15:55:54" - }, { "name": "classpreloader/classpreloader", "version": "1.2.0", @@ -1485,55 +1422,6 @@ ], "time": "2015-01-18 11:29:59" }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "dflydev/markdown": "~1.0", - "erusev/parsedown": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "phpDocumentor": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "mike.vanriel@naenius.com" - } - ], - "time": "2015-02-03 12:10:50" - }, { "name": "psr/log", "version": "1.0.0", @@ -1695,56 +1583,6 @@ ], "time": "2014-12-05 14:17:14" }, - { - "name": "symfony/class-loader", - "version": "v2.6.4", - "target-dir": "Symfony/Component/ClassLoader", - "source": { - "type": "git", - "url": "https://github.com/symfony/ClassLoader.git", - "reference": "deac802f76910708ab50d039806cfd1866895b52" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/ClassLoader/zipball/deac802f76910708ab50d039806cfd1866895b52", - "reference": "deac802f76910708ab50d039806cfd1866895b52", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/finder": "~2.0,>=2.0.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\ClassLoader\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Symfony ClassLoader Component", - "homepage": "http://symfony.com", - "time": "2015-01-05 14:28:40" - }, { "name": "symfony/console", "version": "v2.6.4", @@ -2599,103 +2437,42 @@ "time": "2015-02-19 10:26:39" }, { - "name": "codeception/c3", - "version": "2.0.3", + "name": "barryvdh/laravel-ide-helper", + "version": "v2.0.1", "source": { "type": "git", - "url": "https://github.com/Codeception/c3.git", - "reference": "30321efb2421c5d201d02e2cb8da1a1ca96e4a38" + "url": "https://github.com/barryvdh/laravel-ide-helper.git", + "reference": "81b7febfc64168ea1af57261aa4dfc9acefd5429" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/c3/zipball/30321efb2421c5d201d02e2cb8da1a1ca96e4a38", - "reference": "30321efb2421c5d201d02e2cb8da1a1ca96e4a38", + "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/81b7febfc64168ea1af57261aa4dfc9acefd5429", + "reference": "81b7febfc64168ea1af57261aa4dfc9acefd5429", "shasum": "" }, "require": { - "php": ">=5.4.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Codeception\\c3\\": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Bodnarchuk", - "email": "davert.php@resend.cc", - "homepage": "http://codegyre.com" - } - ], - "description": "CodeCoverage collector for Codeception", - "homepage": "http://codeception.com/", - "keywords": [ - "code coverage", - "codecoverage" - ], - "time": "2014-11-18 22:06:45" - }, - { - "name": "codeception/codeception", - "version": "2.0.11", - "source": { - "type": "git", - "url": "https://github.com/Codeception/Codeception.git", - "reference": "9c7f23eff3e607225e9f43277c6d9cdb03d30b84" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/9c7f23eff3e607225e9f43277c6d9cdb03d30b84", - "reference": "9c7f23eff3e607225e9f43277c6d9cdb03d30b84", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "facebook/webdriver": "~0.4|~0.5", - "guzzlehttp/guzzle": "~4.0|~5.0", + "illuminate/console": "5.0.x", + "illuminate/filesystem": "5.0.x", + "illuminate/support": "5.0.x", "php": ">=5.4.0", - "phpunit/phpunit": "~4.5.0", - "symfony/browser-kit": "~2.4", - "symfony/console": "~2.4", - "symfony/css-selector": "~2.4", - "symfony/dom-crawler": "~2.4,!=2.4.5", - "symfony/event-dispatcher": "~2.4", - "symfony/finder": "~2.4", - "symfony/yaml": "~2.4" + "phpdocumentor/reflection-docblock": "2.0.x", + "symfony/class-loader": "~2.3" }, "require-dev": { - "codeception/specify": "~0.3", - "facebook/php-sdk": "~3.2", - "flow/jsonpath": "~0.2", - "monolog/monolog": "~1.8", - "pda/pheanstalk": "~2.0", - "videlalvaro/php-amqplib": "~2.4" + "doctrine/dbal": "~2.3" }, "suggest": { - "codeception/phpbuiltinserver": "Extension to start and stop PHP built-in web server for your tests", - "codeception/specify": "BDD-style code blocks", - "codeception/verify": "BDD-style assertions", - "monolog/monolog": "Log test steps", - "phpseclib/phpseclib": "Extension required to use the SFTP option in the FTP Module." + "doctrine/dbal": "Load information from the database about models for phpdocs (~2.3)" }, - "bin": [ - "codecept" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.0-dev" } }, "autoload": { - "psr-0": { - "Codeception": "src" + "psr-4": { + "Barryvdh\\LaravelIdeHelper\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -2704,190 +2481,23 @@ ], "authors": [ { - "name": "Michael Bodnarchuk", - "email": "davert@mail.ua", - "homepage": "http://codegyre.com" + "name": "Barry vd. Heuvel", + "email": "barryvdh@gmail.com" } ], - "description": "BDD-style testing framework", - "homepage": "http://codeception.com/", + "description": "Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.", "keywords": [ - "BDD", - "TDD", - "acceptance testing", - "functional testing", - "unit testing" + "autocomplete", + "codeintel", + "helper", + "ide", + "laravel", + "netbeans", + "phpdoc", + "phpstorm", + "sublime" ], - "time": "2015-02-23 23:10:03" - }, - { - "name": "codeception/phpbuiltinserver", - "version": "v1.2.1", - "source": { - "type": "git", - "url": "https://github.com/tiger-seo/PhpBuiltinServer.git", - "reference": "730206313b7e85d9ed4838ba02a0aee24fce1239" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tiger-seo/PhpBuiltinServer/zipball/730206313b7e85d9ed4838ba02a0aee24fce1239", - "reference": "730206313b7e85d9ed4838ba02a0aee24fce1239", - "shasum": "" - }, - "require": { - "codeception/codeception": ">=2.0.2", - "php": ">=5.4.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "Codeception": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "tiger-seo", - "email": "tiger.seo@gmail.com" - } - ], - "description": "PhpBuiltinServer extension for Codeception", - "keywords": [ - "codeception" - ], - "time": "2014-09-19 10:14:07" - }, - { - "name": "codeception/specify", - "version": "0.4.1", - "source": { - "type": "git", - "url": "https://github.com/Codeception/Specify.git", - "reference": "0c0ae07adfc231115b3b72ade22f44c23c199ded" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/Specify/zipball/0c0ae07adfc231115b3b72ade22f44c23c199ded", - "reference": "0c0ae07adfc231115b3b72ade22f44c23c199ded", - "shasum": "" - }, - "require": { - "myclabs/deep-copy": "~1.1", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "Codeception\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "authors": [ - { - "name": "Michael Bodnarchuk", - "email": "davert.php@mailican.com" - } - ], - "description": "BDD code blocks for PHPUnit and Codeception", - "time": "2014-10-17 00:06:51" - }, - { - "name": "codeception/verify", - "version": "0.2.7", - "source": { - "type": "git", - "url": "https://github.com/Codeception/Verify.git", - "reference": "66e5074905f4d9590ddb805d123fe632f4baa488" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Codeception/Verify/zipball/66e5074905f4d9590ddb805d123fe632f4baa488", - "reference": "66e5074905f4d9590ddb805d123fe632f4baa488", - "shasum": "" - }, - "require-dev": { - "phpunit/phpunit": "3.7.*" - }, - "type": "library", - "autoload": { - "files": [ - "src/Codeception/function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "authors": [ - { - "name": "Michael Bodnarchuk", - "email": "davert.php@mailican.com", - "homepage": "http://codeception.com" - } - ], - "description": "BDD assertion library for PHPUnit", - "time": "2014-01-22 14:40:33" - }, - { - "name": "codeclimate/php-test-reporter", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/codeclimate/php-test-reporter.git", - "reference": "2a67d5d940e175fddba15f29c81a646ace26dc38" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/codeclimate/php-test-reporter/zipball/2a67d5d940e175fddba15f29c81a646ace26dc38", - "reference": "2a67d5d940e175fddba15f29c81a646ace26dc38", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "php": ">=5.3", - "satooshi/php-coveralls": "0.6.*", - "symfony/console": ">=2.0" - }, - "require-dev": { - "ext-xdebug": "*", - "phpunit/phpunit": "3.7.*@stable" - }, - "bin": [ - "composer/bin/test-reporter" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.1.x-dev" - } - }, - "autoload": { - "psr-0": { - "CodeClimate\\Component": "src/", - "CodeClimate\\Bundle": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Code Climate", - "email": "hello@codeclimate.com", - "homepage": "https://codeclimate.com" - } - ], - "description": "PHP client for reporting test coverage to Code Climate", - "homepage": "https://github.com/codeclimate/php-test-reporter", - "keywords": [ - "codeclimate", - "coverage" - ], - "time": "2015-02-20 22:40:35" + "time": "2015-02-23 15:55:54" }, { "name": "doctrine/instantiator", @@ -2943,407 +2553,6 @@ ], "time": "2014-10-13 12:58:55" }, - { - "name": "facebook/webdriver", - "version": "v0.5.1", - "source": { - "type": "git", - "url": "https://github.com/facebook/php-webdriver.git", - "reference": "bbcb697efb394d17bd9ec3d467e7da847cde4509" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/facebook/php-webdriver/zipball/bbcb697efb394d17bd9ec3d467e7da847cde4509", - "reference": "bbcb697efb394d17bd9ec3d467e7da847cde4509", - "shasum": "" - }, - "require": { - "php": ">=5.3.19" - }, - "require-dev": { - "phpdocumentor/phpdocumentor": "2.*", - "phpunit/phpunit": "3.7.*" - }, - "type": "library", - "autoload": { - "classmap": [ - "lib/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "description": "A php client for WebDriver", - "homepage": "https://github.com/facebook/php-webdriver", - "keywords": [ - "facebook", - "php", - "selenium", - "webdriver" - ], - "time": "2014-11-05 20:53:09" - }, - { - "name": "fzaninotto/faker", - "version": "v1.4.0", - "source": { - "type": "git", - "url": "https://github.com/fzaninotto/Faker.git", - "reference": "010c7efedd88bf31141a02719f51fb44c732d5a0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/010c7efedd88bf31141a02719f51fb44c732d5a0", - "reference": "010c7efedd88bf31141a02719f51fb44c732d5a0", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~1.5" - }, - "type": "library", - "extra": { - "branch-alias": [] - }, - "autoload": { - "psr-0": { - "Faker": "src/", - "Faker\\PHPUnit": "test/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "François Zaninotto" - } - ], - "description": "Faker is a PHP library that generates fake data for you.", - "keywords": [ - "data", - "faker", - "fixtures" - ], - "time": "2014-06-04 14:43:02" - }, - { - "name": "guzzle/guzzle", - "version": "v3.9.2", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle3.git", - "reference": "54991459675c1a2924122afbb0e5609ade581155" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/54991459675c1a2924122afbb0e5609ade581155", - "reference": "54991459675c1a2924122afbb0e5609ade581155", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "php": ">=5.3.3", - "symfony/event-dispatcher": "~2.1" - }, - "replace": { - "guzzle/batch": "self.version", - "guzzle/cache": "self.version", - "guzzle/common": "self.version", - "guzzle/http": "self.version", - "guzzle/inflection": "self.version", - "guzzle/iterator": "self.version", - "guzzle/log": "self.version", - "guzzle/parser": "self.version", - "guzzle/plugin": "self.version", - "guzzle/plugin-async": "self.version", - "guzzle/plugin-backoff": "self.version", - "guzzle/plugin-cache": "self.version", - "guzzle/plugin-cookie": "self.version", - "guzzle/plugin-curlauth": "self.version", - "guzzle/plugin-error-response": "self.version", - "guzzle/plugin-history": "self.version", - "guzzle/plugin-log": "self.version", - "guzzle/plugin-md5": "self.version", - "guzzle/plugin-mock": "self.version", - "guzzle/plugin-oauth": "self.version", - "guzzle/service": "self.version", - "guzzle/stream": "self.version" - }, - "require-dev": { - "doctrine/cache": "~1.3", - "monolog/monolog": "~1.0", - "phpunit/phpunit": "3.7.*", - "psr/log": "~1.0", - "symfony/class-loader": "~2.1", - "zendframework/zend-cache": "2.*,<2.3", - "zendframework/zend-log": "2.*,<2.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.9-dev" - } - }, - "autoload": { - "psr-0": { - "Guzzle": "src/", - "Guzzle\\Tests": "tests/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Guzzle Community", - "homepage": "https://github.com/guzzle/guzzle/contributors" - } - ], - "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ], - "time": "2014-08-11 04:32:36" - }, - { - "name": "guzzlehttp/guzzle", - "version": "5.2.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "475b29ccd411f2fa8a408e64576418728c032cfa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/475b29ccd411f2fa8a408e64576418728c032cfa", - "reference": "475b29ccd411f2fa8a408e64576418728c032cfa", - "shasum": "" - }, - "require": { - "guzzlehttp/ringphp": "~1.0", - "php": ">=5.4.0" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "~4.0", - "psr/log": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ], - "time": "2015-01-28 01:03:29" - }, - { - "name": "guzzlehttp/ringphp", - "version": "1.0.6", - "source": { - "type": "git", - "url": "https://github.com/guzzle/RingPHP.git", - "reference": "f43ab34aad69ca0ba04172cf2c3cd5c12fc0e5a4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/RingPHP/zipball/f43ab34aad69ca0ba04172cf2c3cd5c12fc0e5a4", - "reference": "f43ab34aad69ca0ba04172cf2c3cd5c12fc0e5a4", - "shasum": "" - }, - "require": { - "guzzlehttp/streams": "~3.0", - "php": ">=5.4.0", - "react/promise": "~2.0" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "ext-curl": "Guzzle will use specific adapters if cURL is present" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Ring\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.", - "time": "2015-02-26 20:43:09" - }, - { - "name": "guzzlehttp/streams", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/streams.git", - "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", - "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Stream\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Provides a simple abstraction over streams of data", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "Guzzle", - "stream" - ], - "time": "2014-10-12 19:18:40" - }, - { - "name": "league/factory-muffin", - "version": "v2.1.1", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/factory-muffin.git", - "reference": "91f0adcdac6b5f7bf2277ac2c90f94352afe65de" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/factory-muffin/zipball/91f0adcdac6b5f7bf2277ac2c90f94352afe65de", - "reference": "91f0adcdac6b5f7bf2277ac2c90f94352afe65de", - "shasum": "" - }, - "require": { - "fzaninotto/faker": "1.4.*", - "php": ">=5.3.3" - }, - "replace": { - "zizaco/factory-muff": "self.version" - }, - "require-dev": { - "illuminate/database": "~4.1", - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "illuminate/database": "Factory Muffin works well with eloquent models." - }, - "type": "library", - "autoload": { - "psr-4": { - "League\\FactoryMuffin\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "graham@mineuk.com" - }, - { - "name": "Zizaco Zizuini", - "email": "zizaco@gmail.com" - }, - { - "name": "Scott Robertson", - "email": "scottymeuk@gmail.com" - } - ], - "description": "The goal of this package is to enable the rapid creation of objects for the purpose of testing.", - "homepage": "http://factory-muffin.thephpleague.com/", - "keywords": [ - "factory", - "laravel", - "testing" - ], - "time": "2014-09-18 18:29:06" - }, { "name": "maximebf/debugbar", "version": "v1.10.4", @@ -3401,46 +2610,53 @@ "time": "2015-02-05 07:51:20" }, { - "name": "myclabs/deep-copy", - "version": "1.2.1", + "name": "phpdocumentor/reflection-docblock", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "d93c485e71bcd22df0a994e9e3e03a3ef3a3e3f3" + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/d93c485e71bcd22df0a994e9e3e03a3ef3a3e3f3", - "reference": "d93c485e71bcd22df0a994e9e3e03a3ef3a3e3f3", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", "shasum": "" }, "require": { - "php": ">=5.4.0" + "php": ">=5.3.3" }, "require-dev": { - "doctrine/collections": "1.*", - "phpunit/phpunit": "~4.1" + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" + "psr-0": { + "phpDocumentor": [ + "src/" + ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Create deep copies (clones) of your objects", - "homepage": "https://github.com/myclabs/DeepCopy", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } ], - "time": "2014-11-20 05:11:17" + "time": "2015-02-03 12:10:50" }, { "name": "phpspec/php-diff", @@ -3982,118 +3198,6 @@ ], "time": "2014-10-03 05:12:11" }, - { - "name": "react/promise", - "version": "v2.2.0", - "source": { - "type": "git", - "url": "https://github.com/reactphp/promise.git", - "reference": "365fcee430dfa4ace1fbc75737ca60ceea7eeeef" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise/zipball/365fcee430dfa4ace1fbc75737ca60ceea7eeeef", - "reference": "365fcee430dfa4ace1fbc75737ca60ceea7eeeef", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "psr-4": { - "React\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jan Sorgalla", - "email": "jsorgalla@googlemail.com" - } - ], - "description": "A lightweight implementation of CommonJS Promises/A for PHP", - "time": "2014-12-30 13:32:42" - }, - { - "name": "satooshi/php-coveralls", - "version": "v0.6.1", - "source": { - "type": "git", - "url": "https://github.com/satooshi/php-coveralls.git", - "reference": "dd0df95bd37a7cf5c5c50304dfe260ffe4b50760" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/dd0df95bd37a7cf5c5c50304dfe260ffe4b50760", - "reference": "dd0df95bd37a7cf5c5c50304dfe260ffe4b50760", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-json": "*", - "ext-simplexml": "*", - "guzzle/guzzle": ">=3.0", - "php": ">=5.3", - "psr/log": "1.0.0", - "symfony/config": ">=2.0", - "symfony/console": ">=2.0", - "symfony/stopwatch": ">=2.2", - "symfony/yaml": ">=2.0" - }, - "require-dev": { - "apigen/apigen": "2.8.*@stable", - "pdepend/pdepend": "dev-master", - "phpmd/phpmd": "dev-master", - "phpunit/php-invoker": ">=1.1.0,<1.2.0", - "phpunit/phpunit": "3.7.*@stable", - "sebastian/finder-facade": "dev-master", - "sebastian/phpcpd": "1.4.*@stable", - "squizlabs/php_codesniffer": "1.4.*@stable", - "theseer/fdomdocument": "dev-master" - }, - "bin": [ - "composer/bin/coveralls" - ], - "type": "library", - "autoload": { - "psr-0": { - "Contrib\\Component": "src/", - "Contrib\\Bundle": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kitamura Satoshi", - "email": "with.no.parachute@gmail.com", - "homepage": "https://www.facebook.com/satooshi.jp" - } - ], - "description": "PHP client library for Coveralls API", - "homepage": "https://github.com/satooshi/php-coveralls", - "keywords": [ - "ci", - "coverage", - "github", - "test" - ], - "time": "2013-05-04 08:07:33" - }, { "name": "sebastian/comparator", "version": "1.1.1", @@ -4466,182 +3570,25 @@ "time": "2014-12-15 14:25:24" }, { - "name": "symfony/browser-kit", + "name": "symfony/class-loader", "version": "v2.6.4", - "target-dir": "Symfony/Component/BrowserKit", + "target-dir": "Symfony/Component/ClassLoader", "source": { "type": "git", - "url": "https://github.com/symfony/BrowserKit.git", - "reference": "2ecec44ed5047020c65dd6e4a4b2f3cf13ae3c04" + "url": "https://github.com/symfony/ClassLoader.git", + "reference": "deac802f76910708ab50d039806cfd1866895b52" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/2ecec44ed5047020c65dd6e4a4b2f3cf13ae3c04", - "reference": "2ecec44ed5047020c65dd6e4a4b2f3cf13ae3c04", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "symfony/dom-crawler": "~2.0,>=2.0.5" - }, - "require-dev": { - "symfony/css-selector": "~2.0,>=2.0.5", - "symfony/process": "~2.0,>=2.0.5" - }, - "suggest": { - "symfony/process": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\BrowserKit\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Symfony BrowserKit Component", - "homepage": "http://symfony.com", - "time": "2015-01-03 08:01:59" - }, - { - "name": "symfony/config", - "version": "v2.6.4", - "target-dir": "Symfony/Component/Config", - "source": { - "type": "git", - "url": "https://github.com/symfony/Config.git", - "reference": "a9f781ba1221067d1f07c8cec0bc50f81b8d7408" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/a9f781ba1221067d1f07c8cec0bc50f81b8d7408", - "reference": "a9f781ba1221067d1f07c8cec0bc50f81b8d7408", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "symfony/filesystem": "~2.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Config\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Symfony Config Component", - "homepage": "http://symfony.com", - "time": "2015-01-21 20:57:55" - }, - { - "name": "symfony/css-selector", - "version": "v2.6.4", - "target-dir": "Symfony/Component/CssSelector", - "source": { - "type": "git", - "url": "https://github.com/symfony/CssSelector.git", - "reference": "3f80ecc614fec68d5b4a84a0703db3fdf5ce8584" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/CssSelector/zipball/3f80ecc614fec68d5b4a84a0703db3fdf5ce8584", - "reference": "3f80ecc614fec68d5b4a84a0703db3fdf5ce8584", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\CssSelector\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Symfony CssSelector Component", - "homepage": "http://symfony.com", - "time": "2015-01-03 08:01:59" - }, - { - "name": "symfony/dom-crawler", - "version": "v2.6.4", - "target-dir": "Symfony/Component/DomCrawler", - "source": { - "type": "git", - "url": "https://github.com/symfony/DomCrawler.git", - "reference": "26a9eb302decd828990e1015afaa11b78b016073" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/26a9eb302decd828990e1015afaa11b78b016073", - "reference": "26a9eb302decd828990e1015afaa11b78b016073", + "url": "https://api.github.com/repos/symfony/ClassLoader/zipball/deac802f76910708ab50d039806cfd1866895b52", + "reference": "deac802f76910708ab50d039806cfd1866895b52", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "symfony/css-selector": "~2.3" - }, - "suggest": { - "symfony/css-selector": "" + "symfony/finder": "~2.0,>=2.0.5" }, "type": "library", "extra": { @@ -4651,7 +3598,7 @@ }, "autoload": { "psr-0": { - "Symfony\\Component\\DomCrawler\\": "" + "Symfony\\Component\\ClassLoader\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -4668,56 +3615,9 @@ "email": "fabien@symfony.com" } ], - "description": "Symfony DomCrawler Component", + "description": "Symfony ClassLoader Component", "homepage": "http://symfony.com", - "time": "2015-01-03 08:01:59" - }, - { - "name": "symfony/stopwatch", - "version": "v2.6.4", - "target-dir": "Symfony/Component/Stopwatch", - "source": { - "type": "git", - "url": "https://github.com/symfony/Stopwatch.git", - "reference": "e8da5286132ba75ce4b4275fbf0f4cd369bfd71c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/e8da5286132ba75ce4b4275fbf0f4cd369bfd71c", - "reference": "e8da5286132ba75ce4b4275fbf0f4cd369bfd71c", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Stopwatch\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Symfony Stopwatch Component", - "homepage": "http://symfony.com", - "time": "2015-01-03 08:01:59" + "time": "2015-01-05 14:28:40" }, { "name": "symfony/yaml", @@ -4772,10 +3672,7 @@ "stability-flags": { "grumpydictator/gchart": 20, "watson/validating": 20, - "barryvdh/laravel-debugbar": 0, - "codeception/codeception": 0, - "codeception/c3": 0, - "codeclimate/php-test-reporter": 20 + "barryvdh/laravel-debugbar": 0 }, "prefer-stable": false, "prefer-lowest": false, diff --git a/phpunit.xml b/phpunit.xml index 08522be980..910d6195f7 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -18,5 +18,6 @@ + - + \ No newline at end of file diff --git a/tests/_bootstrap.php b/tests/_bootstrap.php deleted file mode 100644 index 2a9ae24d6c..0000000000 --- a/tests/_bootstrap.php +++ /dev/null @@ -1,9 +0,0 @@ - tests/_data/dump.sql', $out); -} diff --git a/tests/_data/db.sh b/tests/_data/db.sh deleted file mode 100755 index cf12ed0718..0000000000 --- a/tests/_data/db.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -touch tests/_data/db.sqlite -php artisan env -php artisan migrate --seed -sqlite3 tests/_data/db.sqlite .dump > tests/_data/dump.sql -exit 0 \ No newline at end of file diff --git a/tests/_support/AcceptanceHelper.php b/tests/_support/AcceptanceHelper.php deleted file mode 100644 index d09c6e4b18..0000000000 --- a/tests/_support/AcceptanceHelper.php +++ /dev/null @@ -1,10 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - - } - - /** - * @param FunctionalTester $I - */ - public function create(FunctionalTester $I) - { - // @codingStandardsIgnoreStart - $I->wantTo('create a new asset account'); - $I->amOnPage('/accounts/create/asset'); - $I->see('Create a new asset account'); - } - - /** - * @param FunctionalTester $I - */ - public function delete(FunctionalTester $I) - { - $account = Account::where('name', 'Delete me')->first(); - $I->wantTo('delete an asset account'); - $I->amOnPage('/accounts/delete/'.$account->id); - $I->see('Delete account'); - $I->see($account->name); - } - - /** - * @param FunctionalTester $I - */ - public function destroy(FunctionalTester $I) - { - $account = Account::where('name', 'Delete me')->first(); - $I->wantTo('destroy an asset account'); - $I->amOnPage('/accounts/delete/'.$account->id); - $I->see('Delete account'); - $I->see($account->name); - $I->submitForm('#destroy', []); - $I->dontSeeRecord('accounts', ['id' => 3, 'deleted_at' => null]); - } - - /** - * @param FunctionalTester $I - */ - public function edit(FunctionalTester $I) - { - $account = Account::where('name', 'Delete me')->first(); - $I->wantTo('edit an asset account'); - $I->amOnPage('/accounts/edit/'.$account->id); - $I->see('Edit asset account'); - $I->see($account->name); - } - - /** - * @param FunctionalTester $I - */ - public function failUpdate(FunctionalTester $I) - { - $account = Account::where('name', 'Delete me')->first(); - $I->wantTo('update an asset account and fail'); - $I->amOnPage('/accounts/edit/'.$account->id); - $I->see('Edit asset account'); - $I->see($account->name); - $I->submitForm('#update', ['name' => '', 'what' => 'asset', 'account_role' => 'defaultExpense', 'post_submit_action' => 'update']); - $I->seeRecord('accounts', ['name' => 'Delete me']); - - } - - /** - * @param FunctionalTester $I - */ - public function index(FunctionalTester $I) - { - $I->wantTo('see a list of accounts'); - $I->amOnPage('/accounts/asset'); - $I->see('Checking account'); - $I->see('Delete me'); - } - - /** - * @param FunctionalTester $I - */ - public function show(FunctionalTester $I) - { - $account = Account::where('name', 'Delete me')->first(); - $I->wantTo('see one account'); - $I->amOnPage('/accounts/show/'.$account->id); - $I->see('Details for'); - $I->see($account->name); - } - - /** - * @param FunctionalTester $I - */ - public function store(FunctionalTester $I) - { - $I->amOnPage('/accounts/create/asset'); - $I->wantTo('store a new asset account'); - $I->see('Create a new asset account'); - $I->submitForm('#store', ['name' => 'New through tests.', 'what' => 'asset', 'account_role' => 'defaultExpense', 'post_submit_action' => 'store']); - $I->seeRecord('accounts', ['name' => 'New through tests.']); - } - - /** - * @param FunctionalTester $I - */ - public function storeAndCreateAnother(FunctionalTester $I) - { - $I->amOnPage('/accounts/create/asset'); - $I->wantTo('store a new asset account and create another'); - $I->see('Create a new asset account'); - $I->submitForm( - '#store', ['name' => 'New through tests.', 'what' => 'asset', 'account_role' => 'defaultExpense', 'post_submit_action' => 'create_another'] - ); - $I->seeRecord('accounts', ['name' => 'New through tests.']); - } - - /** - * @param FunctionalTester $I - */ - public function storeFail(FunctionalTester $I) - { - $I->amOnPage('/accounts/create/asset'); - $I->wantTo('make storing a new asset account fail.'); - $I->see('Create a new asset account'); - $I->submitForm('#store', ['name' => null, 'what' => 'asset', 'account_role' => 'defaultExpense', 'post_submit_action' => 'validate_only']); - $I->dontSeeRecord('accounts', ['name' => 'New through tests.']); - } - - /** - * @param FunctionalTester $I - */ - public function storeOpeningBalance(FunctionalTester $I) - { - $I->amOnPage('/accounts/create/asset'); - $I->wantTo('store a new asset account with a balance'); - $I->see('Create a new asset account'); - $I->submitForm( - '#store', ['name' => 'New through tests with balance.', - 'openingBalance' => 10, - 'openingBalanceDate' => '2015-01-01', - 'what' => 'asset', 'account_role' => 'defaultExpense', 'post_submit_action' => 'store'] - ); - $I->seeRecord('accounts', ['name' => 'New through tests with balance.']); - } - - /** - * @param FunctionalTester $I - */ - public function update(FunctionalTester $I) - { - $account = Account::where('name', 'Delete me')->first(); - $I->wantTo('update an asset account'); - $I->amOnPage('/accounts/edit/' . $account->id); - $I->see('Edit asset account'); - $I->see($account->name); - $I->submitForm('#update', ['name' => 'Update me', 'what' => 'asset', 'account_role' => 'defaultExpense', 'post_submit_action' => 'update']); - $I->seeRecord('accounts', ['name' => 'Update me']); - - } - - /** - * @param FunctionalTester $I - */ - public function updateAndReturn(FunctionalTester $I) - { - $account = Account::where('name', 'Savings account')->first(); - $I->wantTo('update an asset account and return to form'); - $I->amOnPage('/accounts/edit/' . $account->id); - $I->see('Edit asset account'); - $I->see($account->name); - $I->submitForm( - '#update', ['name' => 'Savings accountXX', 'what' => 'asset', 'account_role' => 'defaultExpense', 'post_submit_action' => 'return_to_edit'] - ); - $I->seeRecord('accounts', ['name' => 'Savings accountXX']); - - } - -} diff --git a/tests/functional/BillControllerCest.php b/tests/functional/BillControllerCest.php deleted file mode 100644 index 5c5362548c..0000000000 --- a/tests/functional/BillControllerCest.php +++ /dev/null @@ -1,278 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - /** - * @param FunctionalTester $I - */ - public function create(FunctionalTester $I) - { - $I->wantTo('create a bill'); - $I->amOnPage('/bills/create'); - } - - /** - * @param FunctionalTester $I - */ - public function delete(FunctionalTester $I) - { - $bill = User::whereEmail('thegrumpydictator@gmail.com')->first()->bills()->first(); - $I->wantTo('delete a bill'); - $I->amOnPage('/bills/delete/' . $bill->id); - $I->see('Delete "' . $bill->name . '"'); - } - - /** - * @param FunctionalTester $I - */ - public function destroy(FunctionalTester $I) - { - $bill = User::whereEmail('thegrumpydictator@gmail.com')->first()->bills()->first(); - $I->wantTo('destroy a bill'); - $I->amOnPage('/bills/delete/' . $bill->id); - $I->see('Delete "' . $bill->name . '"'); - $I->submitForm('#destroy', []); - $I->see('The bill was deleted.'); - - } - - /** - * @param FunctionalTester $I - */ - public function edit(FunctionalTester $I) - { - $bill = User::whereEmail('thegrumpydictator@gmail.com')->first()->bills()->first(); - $I->wantTo('edit a bill'); - $I->amOnPage('/bills/edit/' . $bill->id); - $I->see($bill->name); - - - } - - /** - * @param FunctionalTester $I - */ - public function index(FunctionalTester $I) - { - $bill = User::whereEmail('thegrumpydictator@gmail.com')->first()->bills()->first(); - $I->wantTo('see all bills'); - $I->amOnPage('/bills'); - $I->see('Bills'); - $I->see($bill->name); - } - - /** - * @param FunctionalTester $I - */ - public function rescan(FunctionalTester $I) - { - $bill = User::whereEmail('thegrumpydictator@gmail.com')->first()->bills()->first(); - $I->wantTo('rescan a bill'); - $I->amOnPage('/bills/rescan/' . $bill->id); - $I->see('Rescanned everything.'); - } - - /** - * @param FunctionalTester $I - */ - public function rescanInactive(FunctionalTester $I) - { - $bill = User::whereEmail('thegrumpydictator@gmail.com')->first()->bills()->where('active', 0)->first(); - $I->wantTo('rescan an inactive bill'); - $I->amOnPage('/bills/rescan/' . $bill->id); - $I->see('Inactive bills cannot be scanned.'); - } - - /** - * @param FunctionalTester $I - */ - public function show(FunctionalTester $I) - { - $bill = User::whereEmail('thegrumpydictator@gmail.com')->first()->bills()->first(); - $I->wantTo('show a bill'); - $I->amOnPage('/bills/show/' . $bill->id); - $I->see($bill->name); - } - - /** - * @param FunctionalTester $I - */ - public function store(FunctionalTester $I) - { - $I->wantTo('store a bill'); - $I->amOnPage('/bills/create'); - $I->submitForm( - '#store', [ - 'name' => 'Some bill', - 'match' => 'one,two', - 'amount_min' => 10, - 'amount_max' => 20, - 'post_submit_action' => 'store', - 'date' => date('Y-m-d'), - 'repeat_freq' => 'monthly', - 'skip' => 0 - ] - ); - $I->see('Bill "Some bill" stored.'); - } - - /** - * @param FunctionalTester $I - */ - public function storeFail(FunctionalTester $I) - { - $I->wantTo('store a bill and fail'); - $I->amOnPage('/bills/create'); - $I->submitForm( - '#store', [ - 'name' => 'Some bill', - 'match' => '', - 'amount_min' => 10, - 'amount_max' => 20, - 'date' => date('Y-m-d'), - 'repeat_freq' => 'monthly', - 'skip' => 0 - ] - ); - $I->dontSeeInDatabase('bills', ['name' => 'Some bill']); - $I->see('Could not store bill'); - } - - /** - * @param FunctionalTester $I - */ - public function storeRecreate(FunctionalTester $I) - { - $I->wantTo('validate a bill and create another one'); - $I->amOnPage('/bills/create'); - $I->submitForm( - '#store', [ - 'name' => 'Some bill', - 'match' => 'one,two', - 'amount_min' => 10, - 'amount_max' => 20, - 'post_submit_action' => 'create_another', - 'date' => date('Y-m-d'), - 'repeat_freq' => 'monthly', - 'skip' => 0, - - ] - ); - $I->see('Bill "Some bill" stored.'); - } - - /** - * @param FunctionalTester $I - */ - public function storeValidate(FunctionalTester $I) - { - $I->wantTo('validate a bill'); - $I->amOnPage('/bills/create'); - $I->submitForm( - '#store', [ - 'name' => 'Some bill', - 'match' => 'one,two', - 'amount_min' => 10, - 'amount_max' => 20, - 'post_submit_action' => 'validate_only', - 'date' => date('Y-m-d'), - 'repeat_freq' => 'monthly', - 'skip' => 0, - - ] - ); - $I->see('form-group has-success has-feedback'); - } - - /** - * @param FunctionalTester $I - */ - public function update(FunctionalTester $I) - { - $bill = User::whereEmail('thegrumpydictator@gmail.com')->first()->bills()->first(); - $I->wantTo('update a bill'); - $I->amOnPage('/bills/edit/' . $bill->id); - $I->submitForm( - '#update', [ - 'name' => 'Some bill', - 'match' => 'bla,bla', - 'amount_min' => 10, - 'amount_max' => 20, - 'date' => date('Y-m-d'), - 'repeat_freq' => 'monthly', - 'skip' => 0 - ] - ); - $I->see('Bill "Some bill" updated.'); - } - - /** - * @param FunctionalTester $I - */ - public function updateFail(FunctionalTester $I) - { - $bill = User::whereEmail('thegrumpydictator@gmail.com')->first()->bills()->first(); - $I->wantTo('update a bill and fail'); - $I->amOnPage('/bills/edit/' . $bill->id); - $I->submitForm( - '#update', [ - 'name' => 'Some bill', - 'match' => '', - 'amount_min' => 10, - 'amount_max' => 20, - 'date' => date('Y-m-d'), - 'repeat_freq' => 'monthly', - 'skip' => 0 - ] - ); - $I->see('Could not update bill'); - } - - /** - * @param FunctionalTester $I - */ - public function updateReturn(FunctionalTester $I) - { - $bill = User::whereEmail('thegrumpydictator@gmail.com')->first()->bills()->first(); - $I->wantTo('update a bill and return to edit it'); - $I->amOnPage('/bills/edit/' . $bill->id); - $I->submitForm( - '#update', [ - 'name' => 'Some bill', - 'match' => 'bla,bla', - 'amount_min' => 10, - 'amount_max' => 20, - 'post_submit_action' => 'return_to_edit', - 'date' => date('Y-m-d'), - 'repeat_freq' => 'monthly', - 'skip' => 0 - ] - ); - $I->see('Bill "Some bill" updated.'); - } - -} diff --git a/tests/functional/BudgetControllerCest.php b/tests/functional/BudgetControllerCest.php deleted file mode 100644 index 7259be9975..0000000000 --- a/tests/functional/BudgetControllerCest.php +++ /dev/null @@ -1,242 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - /** - * @param FunctionalTester $I - */ - public function create(FunctionalTester $I) - { - $I->wantTo('create a budget'); - $I->amOnRoute('budgets.create'); - $I->see('Create a new budget'); - } - - /** - * @param FunctionalTester $I - */ - public function delete(FunctionalTester $I) - { - $budget = Budget::where('name', 'Delete me')->first(); - $I->wantTo('delete a budget'); - $I->amOnPage('/budgets/delete/' . $budget->id); - $I->see('Delete budget'); - $I->see($budget->name); - } - - /** - * @param FunctionalTester $I - */ - public function destroy(FunctionalTester $I) - { - $budget = Budget::where('name', 'Delete me')->first(); - $I->wantTo('destroy a budget'); - $I->amOnPage('/budgets/delete/' . $budget->id); - $I->see('Delete budget'); - $I->see($budget->name); - $I->submitForm('#destroy', []); - $I->see(' was deleted.'); - $I->see($budget->name); - } - - /** - * @param FunctionalTester $I - */ - public function edit(FunctionalTester $I) - { - $budget = Budget::where('name', 'Delete me')->first(); - $I->wantTo('edit a budget'); - $I->amOnPage('/budgets/edit/' . $budget->id); - $I->see('Edit budget'); - $I->see($budget->name); - } - - /** - * @param FunctionalTester $I - */ - public function failUpdate(FunctionalTester $I) - { - $budget = Budget::where('name', 'Delete me')->first(); - $I->wantTo('update a budget and fail'); - $I->amOnPage('/budgets/edit/' . $budget->id); - $I->see('Edit budget'); - $I->see($budget->name); - $I->submitForm('#update', ['name' => '', 'post_submit_action' => 'update']); - $I->seeRecord('budgets', ['name' => $budget->name]); - - } - - /** - * @param FunctionalTester $I - */ - public function index(FunctionalTester $I) - { - $I->wantTo('show all budgets'); - $I->amOnPage('/budgets'); - $I->see('Budgets'); - } - - /** - * @param FunctionalTester $I - */ - public function indexNoBudget(FunctionalTester $I) - { - $I->wantTo('see transactions without a budget'); - $I->amOnPage('/budgets/list/noBudget'); - $I->see('Transactions without a budget in'); - } - - /** - * @param FunctionalTester $I - */ - public function postUpdateIncome(FunctionalTester $I) - { - $date = date('FY'); - $I->wantTo('process the update to my monthly income'); - $I->amOnPage('/budgets/income'); - $I->see('Update (expected) income for'); - $I->submitForm('#income', ['amount' => 1200]); - $I->seeRecord('preferences', ['name' => 'budgetIncomeTotal' . $date, 'data' => 1200]); - } - - /** - * @param FunctionalTester $I - */ - public function show(FunctionalTester $I) - { - $I->wantTo('show a budget'); - $I->amOnPage('/budgets/show/3'); - $I->see('Delete me'); - } - - /** - * @param FunctionalTester $I - */ - public function showInvalidRepetition(FunctionalTester $I) - { - $I->wantTo('show a budget with a repetition that does not match the budget.'); - $I->amOnPage('/budgets/show/1/3'); - $I->see('Invalid selection'); - } - - /** - * @param FunctionalTester $I - */ - public function store(FunctionalTester $I) - { - $I->amOnPage('/budgets/create'); - $I->wantTo('store a new budget'); - $I->see('Create a new budget'); - $I->submitForm('#store', ['name' => 'New budget.', 'post_submit_action' => 'store']); - $I->seeRecord('budgets', ['name' => 'New budget.']); - } - - /** - * @param FunctionalTester $I - */ - public function storeAndCreateAnother(FunctionalTester $I) - { - $I->amOnPage('/budgets/create'); - $I->wantTo('store a new budget and create another'); - $I->see('Create a new budget'); - $I->submitForm('#store', ['name' => 'New budget.', 'post_submit_action' => 'create_another']); - $I->seeRecord('budgets', ['name' => 'New budget.']); - } - - /** - * @param FunctionalTester $I - */ - public function storeFail(FunctionalTester $I) - { - $I->amOnPage('/budgets/create'); - $I->wantTo('make storing a new budget fail.'); - $I->see('Create a new budget'); - $I->submitForm('#store', ['name' => null, 'post_submit_action' => 'store']); - $I->dontSeeRecord('budgets', ['name' => 'New budget.']); - } - - /** - * @param FunctionalTester $I - */ - public function testAmount(FunctionalTester $I) - { - $I->wantTo('update the amount for a budget and limit repetition'); - $I->amOnPage('/budgets'); - - ///budgets/income - - $token = $I->grabValueFrom("input[name='_token']"); - - - $I->sendAjaxPostRequest('/budgets/amount/1', ['amount' => 100, '_token' => $token]); - $I->canSeeResponseCodeIs(200); - $I->see('Groceries'); -// $I->seeInDatabase('budgets', ['id' => 1]); - #$I->seeInDatabase('budget_limits', ['budget_id' => 1, 'amount' => 100.00]); - } - - /** - * @param FunctionalTester $I - */ - public function update(FunctionalTester $I) - { - $budget = Budget::where('name', 'Delete me')->first(); - $I->wantTo('update a budget'); - $I->amOnPage('/budgets/edit/'.$budget->id); - $I->see('Edit budget'); - $I->see($budget->name); - $I->submitForm('#update', ['name' => 'Update me', 'post_submit_action' => 'update']); - $I->seeRecord('budgets', ['name' => 'Update me']); - - } - - /** - * @param FunctionalTester $I - */ - public function updateAndReturn(FunctionalTester $I) - { - $budget = Budget::where('name', 'Delete me')->first(); - $I->wantTo('update a budget and return to form'); - $I->amOnPage('/budgets/edit/'.$budget->id); - $I->see('Edit budget'); - $I->see($budget->name); - $I->submitForm( - '#update', ['name' => 'Savings accountXX', 'post_submit_action' => 'return_to_edit'] - ); - $I->seeRecord('budgets', ['name' => 'Savings accountXX']); - - } - - /** - * @param FunctionalTester $I - */ - public function updateIncome(FunctionalTester $I) - { - $I->amOnPage('/budgets/income'); - $I->wantTo('update my monthly income'); - $I->see('Update (expected) income for '); - } -} diff --git a/tests/functional/CategoryControllerCest.php b/tests/functional/CategoryControllerCest.php deleted file mode 100644 index cef60dee22..0000000000 --- a/tests/functional/CategoryControllerCest.php +++ /dev/null @@ -1,201 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - /** - * @param FunctionalTester $I - */ - public function create(FunctionalTester $I) - { - $I->wantTo('create a new category'); - $I->amOnPage('/categories/create'); - } - - /** - * @param FunctionalTester $I - */ - public function delete(FunctionalTester $I) - { - $I->wantTo('delete a category'); - $I->amOnPage('/categories/delete/4'); - $I->see('Delete category "Delete me"'); - } - - /** - * @param FunctionalTester $I - */ - public function destroy(FunctionalTester $I) - { - $I->wantTo('destroy a category'); - $I->amOnPage('/categories/delete/4'); - $I->see('Delete category "Delete me"'); - $I->submitForm('#destroy', []); - $I->see('Category "Delete me" was deleted.'); - - } - - /** - * @param FunctionalTester $I - */ - public function edit(FunctionalTester $I) - { - $I->wantTo('edit a category'); - $I->amOnPage('/categories/edit/4'); - $I->see('Edit category "Delete me"'); - } - - /** - * @param FunctionalTester $I - */ - public function failUpdate(FunctionalTester $I) - { - $I->wantTo('update a category and fail'); - $I->amOnPage('/categories/edit/4'); - $I->see('Edit category "Delete me"'); - $I->submitForm('#update', ['name' => '', 'post_submit_action' => 'update']); - $I->seeRecord('categories', ['name' => 'Delete me']); - - } - - /** - * @param FunctionalTester $I - */ - public function index(FunctionalTester $I) - { - $I->wantTo('show all categories'); - $I->amOnPage('/categories'); - } - /** - * @param FunctionalTester $I - */ - public function indexNoCategory(FunctionalTester $I) - { - $I->wantTo('see transactions without a category'); - $I->amOnPage('/categories/list/noCategory'); - $I->see('Transactions without a category in'); - } - - /** - * @param FunctionalTester $I - */ - public function show(FunctionalTester $I) - { - $I->wantTo('show a category'); - $I->amOnPage('/categories/show/4'); - $I->see('Delete me'); - } - - /** - * @param FunctionalTester $I - */ - public function store(FunctionalTester $I) - { - $I->amOnPage('/categories/create'); - $I->wantTo('store a new category'); - $I->see('Create a new category'); - $I->submitForm('#store', ['name' => 'New category.', 'post_submit_action' => 'store']); - $I->seeRecord('categories', ['name' => 'New category.']); - } - - /** - * @param FunctionalTester $I - */ - public function storeAndCreateAnother(FunctionalTester $I) - { - $I->amOnPage('/categories/create'); - $I->wantTo('store a new category and create another'); - $I->see('Create a new category'); - $I->submitForm('#store', ['name' => 'New category.', 'post_submit_action' => 'create_another']); - $I->seeRecord('categories', ['name' => 'New category.']); - } - - /** - * @param FunctionalTester $I - */ - public function storeFail(FunctionalTester $I) - { - $I->amOnPage('/categories/create'); - $I->wantTo('make storing a new category fail.'); - $I->see('Create a new category'); - $I->submitForm('#store', ['name' => null, 'post_submit_action' => 'validate_only']); - $I->dontSeeRecord('categories', ['name' => 'New category.']); - } - - /** - * @param FunctionalTester $I - */ - public function storeValidateOnly(FunctionalTester $I) - { - $I->amOnPage('/categories/create'); - $I->wantTo('validate a new category'); - $I->see('Create a new category'); - $I->submitForm('#store', ['name' => 'New category.', 'post_submit_action' => 'validate_only']); - $I->dontSeeRecord('categories', ['name' => 'New category.']); - } - - /** - * @param FunctionalTester $I - */ - public function update(FunctionalTester $I) - { - $I->wantTo('update a category'); - $I->amOnPage('/categories/edit/4'); - $I->see('Edit category "Delete me"'); - $I->submitForm('#update', ['name' => 'Update me', 'post_submit_action' => 'update']); - $I->seeRecord('categories', ['name' => 'Update me']); - - } - - /** - * @param FunctionalTester $I - */ - public function updateAndReturn(FunctionalTester $I) - { - $I->wantTo('update a category and return to form'); - $I->amOnPage('/categories/edit/4'); - $I->see('Edit category "Delete me"'); - $I->submitForm( - '#update', ['name' => 'Savings accountXX', 'post_submit_action' => 'return_to_edit'] - ); - $I->seeRecord('categories', ['name' => 'Savings accountXX']); - - } - - /** - * @param FunctionalTester $I - */ - public function validateUpdateOnly(FunctionalTester $I) - { - $I->wantTo('update a category and validate only'); - $I->amOnPage('/categories/edit/4'); - $I->see('Edit category "Delete me"'); - $I->submitForm( - '#update', ['name' => 'Validate Only', 'post_submit_action' => 'validate_only'] - ); - $I->dontSeeRecord('categories', ['name' => 'Savings accountXX']); - $I->seeRecord('categories', ['name' => 'Delete me']); - - } - -} diff --git a/tests/functional/CurrencyControllerCest.php b/tests/functional/CurrencyControllerCest.php deleted file mode 100644 index 168fffc5cb..0000000000 --- a/tests/functional/CurrencyControllerCest.php +++ /dev/null @@ -1,202 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - - /** - * @param FunctionalTester $I - */ - public function create(FunctionalTester $I) - { - $I->wantTo('create a currency'); - $I->amOnRoute('currency.create'); - $I->see('Create a new currency'); - } - - /** - * @param FunctionalTester $I - */ - public function defaultCurrency(FunctionalTester $I) - { - $I->wantTo('make US Dollar the default currency'); - $I->amOnPage('/currency/default/2'); - $I->see('US Dollar is now the default currency.'); - } - - /** - * @param FunctionalTester $I - */ - public function delete(FunctionalTester $I) - { - $I->wantTo('delete a currency'); - $I->amOnPage('/currency/delete/3'); - $I->see('Delete currency "Hungarian forint"'); - } - - /** - * @param FunctionalTester $I - */ - public function destroy(FunctionalTester $I) - { - $I->wantTo('destroy a currency'); - $I->amOnPage('/currency/delete/3'); - $I->see('Delete currency "Hungarian forint"'); - $I->submitForm('#destroy', []); - $I->see('Currency "Hungarian forint" deleted'); - } - - /** - * @param FunctionalTester $I - */ - public function destroyFail(FunctionalTester $I) - { - $I->wantTo('destroy a currency currently in use'); - $I->amOnPage('/currency/delete/1'); - $I->see('Cannot delete Euro because there are still transactions attached to it.'); - } - - /** - * @param FunctionalTester $I - */ - public function edit(FunctionalTester $I) - { - $I->wantTo('edit a currency'); - $I->amOnPage('/currency/edit/2'); - $I->see('Edit currency "US Dollar"'); - } - - /** - * @param FunctionalTester $I - */ - public function failUpdate(FunctionalTester $I) - { - $I->wantTo('update a currency and fail'); - $I->amOnPage('/currency/edit/2'); - $I->see('Edit currency "US Dollar"'); - $I->submitForm('#update', ['name' => 'Failed update', 'code' => '123', 'post_submit_action' => 'update']); - $I->dontSeeRecord('transaction_currencies', ['name' => 'Failed update']); - - } - - /** - * @param FunctionalTester $I - */ - public function index(FunctionalTester $I) - { - $I->wantTo('show all currencies'); - $I->amOnPage('/currency'); - $I->see('fa-usd'); - } - - /** - * @param FunctionalTester $I - */ - public function store(FunctionalTester $I) - { - $I->amOnPage('/currency/create'); - $I->wantTo('store a new currency'); - $I->see('Create a new currency'); - $I->submitForm('#store', ['name' => 'New currency.', 'symbol' => 'C', 'code' => 'CXX', 'post_submit_action' => 'store']); - $I->seeRecord('transaction_currencies', ['name' => 'New currency.']); - } - - /** - * @param FunctionalTester $I - */ - public function storeAndCreateAnother(FunctionalTester $I) - { - $I->amOnPage('/currency/create'); - $I->wantTo('store a new currency and create another'); - $I->see('Create a new currency'); - $I->submitForm('#store', ['name' => 'Store and create another.', 'symbol' => 'C', 'code' => 'CXX', 'post_submit_action' => 'create_another']); - $I->seeRecord('transaction_currencies', ['name' => 'Store and create another.']); - } - - /** - * @param FunctionalTester $I - */ - public function storeFail(FunctionalTester $I) - { - $I->amOnPage('/currency/create'); - $I->wantTo('make storing a new currency fail.'); - $I->see('Create a new currency'); - $I->submitForm('#store', ['name' => 'Store and fail', 'symbol' => null, 'code' => '123', 'post_submit_action' => 'store']); - $I->dontSeeRecord('transaction_currencies', ['name' => 'Store and fail']); - } - - /** - * @param FunctionalTester $I - */ - public function storeValidateOnly(FunctionalTester $I) - { - $I->amOnPage('/currency/create'); - $I->wantTo('validate a new currency'); - $I->see('Create a new currency'); - $I->submitForm('#store', ['name' => 'Store validate only.', 'symbol' => 'C', 'code' => 'CXX', 'post_submit_action' => 'validate_only']); - $I->dontSeeRecord('transaction_currencies', ['name' => 'Store validate only.']); - } - - /** - * @param FunctionalTester $I - */ - public function update(FunctionalTester $I) - { - $I->wantTo('update a currency'); - $I->amOnPage('/currency/edit/2'); - $I->see('Edit currency "US Dollar"'); - $I->submitForm('#update', ['name' => 'Successful update', 'symbol' => '$', 'code' => 'USD', 'post_submit_action' => 'update']); - $I->seeRecord('transaction_currencies', ['name' => 'Successful update']); - - } - - /** - * @param FunctionalTester $I - */ - public function updateAndReturn(FunctionalTester $I) - { - $I->wantTo('update a currency and return to form'); - $I->amOnPage('/currency/edit/2'); - $I->see('Edit currency "US Dollar"'); - $I->submitForm( - '#update', ['name' => 'US DollarXXX', 'symbol' => '$', 'code' => 'USD', 'post_submit_action' => 'return_to_edit'] - ); - $I->seeRecord('transaction_currencies', ['name' => 'US DollarXXX']); - - } - - /** - * @param FunctionalTester $I - */ - public function validateUpdateOnly(FunctionalTester $I) - { - $I->wantTo('update a currency and validate only'); - $I->amOnPage('/currency/edit/2'); - $I->see('Edit currency "US Dollar"'); - $I->submitForm('#update', ['name' => 'Update Validate Only', 'post_submit_action' => 'validate_only']); - $I->dontSeeRecord('transaction_currencies', ['name' => 'Update Validate Only']); - $I->seeRecord('transaction_currencies', ['name' => 'US Dollar']); - - } -} diff --git a/tests/functional/GoogleChartControllerCest.php b/tests/functional/GoogleChartControllerCest.php deleted file mode 100644 index a570d9214d..0000000000 --- a/tests/functional/GoogleChartControllerCest.php +++ /dev/null @@ -1,201 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - /** - * @param FunctionalTester $I - */ - public function accountAllBalanceChart(FunctionalTester $I) - { - $I->wantTo('see the complete balance chart of an account.'); - $I->amOnPage('chart/account/1/all'); - $I->seeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function accountBalanceChart(FunctionalTester $I) - { - $I->wantTo('see the session balance chart of an account.'); - $I->amOnPage('chart/account/1/session'); - $I->seeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function allAccountsBalanceChart(FunctionalTester $I) - { - $I->wantTo('see the chart with the balances of all accounts'); - $I->amOnPage('/chart/home/account'); - $I->seeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function allBudgetsHomeChart(FunctionalTester $I) - { - $I->wantTo('see the chart with all budgets on it'); - $I->amOnPage('/chart/home/budgets'); - $I->seeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function allCategoriesHomeChart(FunctionalTester $I) - { - $I->wantTo('see the chart with all categories on it'); - $I->amOnPage('/chart/home/categories'); - $I->seeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function billOverview(FunctionalTester $I) - { - $I->wantTo('see the chart for the history of a bill'); - $I->amOnPage('/chart/bills/1'); - $I->seeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function billsOverview(FunctionalTester $I) - { - $I->wantTo('see the chart for which bills I have yet to pay'); - $I->amOnPage('/chart/home/bills'); - $I->seeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function budgetLimitSpending(FunctionalTester $I) - { - $I->wantTo('see the chart for a budget and a repetition'); - $I->amOnPage('/chart/budget/1/1'); - $I->seeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function budgetsAndSpending(FunctionalTester $I) - { - $I->wantTo('see the chart for a budget in a specific year'); - $I->amOnPage('/chart/budget/1/spending'); - $I->seeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function categoriesAndSpending(FunctionalTester $I) - { - $year = date('Y'); - $I->wantTo('see the chart for a category in a specific year'); - $I->amOnPage('/chart/category/1/spending/'.$year); - $I->seeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function categoriesAndSpendingInvalidYear(FunctionalTester $I) - { - $I->wantTo('see the chart for a category in an invalid year'); - $I->amOnPage('/chart/category/1/spending/XXXX'); - $I->seeResponseCodeIs(200); - $I->see('Invalid year'); - } - - /** - * @param FunctionalTester $I - */ - public function emptyBillOverview(FunctionalTester $I) - { - $I->wantTo('see the chart for the history of an empty bill'); - $I->amOnPage('/chart/bills/2'); - $I->seeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function piggyBankHistory(FunctionalTester $I) - { - $I->wantTo('see the chart for the history of a piggy bank'); - $I->amOnPage('/chart/piggy_history/1'); - $I->seeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function yearInExp(FunctionalTester $I) - { - $I->wantTo("see this year's expenses"); - $I->amOnPage('/chart/reports/income-expenses/' . date('Y')); - $I->seeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function yearInExpInvalidYear(FunctionalTester $I) - { - $I->wantTo("see the year's expenses of an invalid year"); - $I->amOnPage('/chart/reports/income-expenses/XXXXX'); - $I->seeResponseCodeIs(200); - $I->see('Invalid year'); - } - - /** - * @param FunctionalTester $I - */ - public function yearInExpSum(FunctionalTester $I) - { - $I->wantTo("see this year's expenses summarized"); - $I->amOnPage('/chart/reports/income-expenses-sum/' . date('Y')); - $I->seeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function yearInExpSumInvalidYear(FunctionalTester $I) - { - $I->wantTo("see the year's expenses summarized of an invalid year"); - $I->amOnPage('/chart/reports/income-expenses-sum/XXXXX'); - $I->seeResponseCodeIs(200); - $I->see('Invalid year'); - } - - -} diff --git a/tests/functional/HelpControllerCest.php b/tests/functional/HelpControllerCest.php deleted file mode 100644 index a8bb6c2d66..0000000000 --- a/tests/functional/HelpControllerCest.php +++ /dev/null @@ -1,89 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - /** - * @param FunctionalTester $I - */ - public function show(FunctionalTester $I) - { - $I->wantTo('show help for the index page'); - $I->amOnPage('/help/index'); - $I->canSeeResponseCodeIs(200); - $I->see('text'); - - } - - /** - * @param FunctionalTester $I - */ - public function showFromCache(FunctionalTester $I) - { - $I->wantTo('show help for the index page from the cache.'); - $I->amOnPage('/help/index'); - $I->amOnPage('/help/index'); - $I->canSeeResponseCodeIs(200); - $I->see('text'); - - } - - /** - * @param FunctionalTester $I - */ - public function showHelpEmptyHelpFile(FunctionalTester $I) - { - $I->wantTo('show help for a route with no text.'); - $I->amOnPage('/help/transactions.doRelate'); - $I->canSeeResponseCodeIs(200); - $I->see('There is no help for this route'); - - } - - /** - * @param FunctionalTester $I - */ - public function showHelpInvalidRoute(FunctionalTester $I) - { - $I->wantTo('show help for a non-existing route.'); - $I->amOnPage('/help/indexXXXX'); - $I->canSeeResponseCodeIs(200); - $I->see('There is no help for this route'); - - } - // - - /** - * @param FunctionalTester $I - */ - public function showHelpNoHelpFile(FunctionalTester $I) - { - $I->wantTo('show help for route that has no help file.'); - $I->amOnPage('/help/help.show'); - $I->canSeeResponseCodeIs(200); - $I->see('text'); - - } - -} diff --git a/tests/functional/HomeControllerCest.php b/tests/functional/HomeControllerCest.php deleted file mode 100644 index 62302e91e1..0000000000 --- a/tests/functional/HomeControllerCest.php +++ /dev/null @@ -1,98 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - /** - * @param FunctionalTester $I - */ - public function flush(FunctionalTester $I) - { - $I->wantTo('flush the cache'); - $I->amOnPage('/flush'); - $I->canSeeResponseCodeIs(200); - $I->see('Firefly'); - } - - /** - * @param FunctionalTester $I - */ - public function index(FunctionalTester $I) - { - $I->wantTo('see the home page of Firefly'); - $I->amOnPage('/'); - $I->canSeeResponseCodeIs(200); - $I->see('Firefly'); - } - - /** - * @param FunctionalTester $I - */ - public function indexWithPrefs(FunctionalTester $I) - { - Preference::whereName('frontPageAccounts')->delete(); - Preference::create( - [ - 'user_id' => 1, - 'name' => 'frontPageAccounts', - 'data' => [1,2] - ] - ); - $I->wantTo('see the home page of Firefly using pre-set accounts'); - $I->amOnPage('/'); - $I->canSeeResponseCodeIs(200); - $I->see('Firefly'); - } - - /** - * @param FunctionalTester $I - */ - public function rangeJump(FunctionalTester $I) - { - $I->wantTo('switch to another date range'); - $I->amOnPage('/jump/6M'); - $I->canSeeResponseCodeIs(200); - - } - - /** - * @param FunctionalTester $I - */ - public function sessionNext(FunctionalTester $I) - { - $I->wantTo('jump to the next period'); - $I->amOnPage('/next'); - $I->canSeeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function sessionPrev(FunctionalTester $I) - { - $I->wantTo('jump to the previous period'); - $I->amOnPage('/prev'); - $I->canSeeResponseCodeIs(200); - } -} diff --git a/tests/functional/JsonControllerCest.php b/tests/functional/JsonControllerCest.php deleted file mode 100644 index 907d6cf724..0000000000 --- a/tests/functional/JsonControllerCest.php +++ /dev/null @@ -1,56 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - /** - * @param FunctionalTester $I - */ - public function categories(FunctionalTester $I) - { - $I->wantTo('See a JSON list of categories.'); - $I->amOnPage('/json/categories'); - $I->canSeeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function expenseAccounts(FunctionalTester $I) - { - $I->wantTo('See a JSON list of expense accounts.'); - $I->amOnPage('/json/expense-accounts'); - $I->canSeeResponseCodeIs(200); - } - - /** - * @param FunctionalTester $I - */ - public function revenueAccounts(FunctionalTester $I) - { - $I->wantTo('See a JSON list of revenue accounts.'); - $I->amOnPage('/json/revenue-accounts'); - $I->canSeeResponseCodeIs(200); - } -} diff --git a/tests/functional/PiggyBankControllerCest.php b/tests/functional/PiggyBankControllerCest.php deleted file mode 100644 index c0651993e8..0000000000 --- a/tests/functional/PiggyBankControllerCest.php +++ /dev/null @@ -1,356 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - /** - * @param FunctionalTester $I - */ - public function add(FunctionalTester $I) - { - $I->wantTo('add money to a piggy bank'); - $I->amOnPage('/piggy_banks/add/1'); - $I->see('Add money to New camera'); - } - - /** - * @param FunctionalTester $I - */ - public function create(FunctionalTester $I) - { - $I->wantTo('create a piggy bank'); - $I->amOnPage('/piggy_banks/create'); - $I->see('Create new piggy bank'); - } - - /** - * @param FunctionalTester $I - */ - public function delete(FunctionalTester $I) - { - $I->wantTo('delete a piggy bank'); - $I->amOnPage('/piggy_banks/delete/1'); - $I->see('Delete "New camera"'); - - } - - /** - * @param FunctionalTester $I - */ - public function destroy(FunctionalTester $I) - { - $I->wantTo('destroy a piggy bank'); - $I->amOnPage('/piggy_banks/delete/1'); - $I->see('Delete "New camera"'); - $I->submitForm('#destroy', []); - $I->see('Piggy bank "New camera" deleted.'); - - } - - /** - * @param FunctionalTester $I - */ - public function edit(FunctionalTester $I) - { - $I->wantTo('edit a piggy bank'); - $I->amOnPage('/piggy_banks/edit/1'); - $I->see('Edit piggy bank "New camera"'); - } - - /** - * @param FunctionalTester $I - */ - public function editWithTargetDate(FunctionalTester $I) - { - $I->wantTo('edit a piggy bank with a target date'); - $I->amOnPage('/piggy_banks/edit/2'); - $I->see('Edit piggy bank "New clothes"'); - } - - /** - * @param FunctionalTester $I - */ - public function index(FunctionalTester $I) - { - $I->wantTo('view all piggy banks'); - $I->amOnPage('/piggy_banks'); - $I->see('Piggy banks'); - $I->see('New camera'); - } - - /** - * @param FunctionalTester $I - */ - public function postAdd(FunctionalTester $I) - { - $I->wantTo('process adding money to a piggy bank'); - $I->amOnPage('/piggy_banks/add/1'); - $I->see('Add money to New camera'); - $I->submitForm('#add', ['amount' => 100]); - $I->see(',00 to "New camera".'); - } - - /** - * @param FunctionalTester $I - */ - public function postAddTooMuch(FunctionalTester $I) - { - $I->wantTo('try to add too much money to a piggy bank'); - $I->amOnPage('/piggy_banks/add/1'); - $I->see('Add money to New camera'); - $I->submitForm('#add', ['amount' => 100000]); - $I->see(',00 to "New camera".'); - } - - /** - * @param FunctionalTester $I - */ - public function postRemove(FunctionalTester $I) - { - $I->wantTo('process removing money from a piggy bank'); - $I->amOnPage('/piggy_banks/add/1'); - $I->see('Add money to New camera'); - $I->submitForm('#add', ['amount' => 100]); - $I->see(',00 to "New camera".'); - $I->amOnPage('/piggy_banks/remove/1'); - $I->see('Remove money from New camera'); - $I->submitForm('#remove', ['amount' => 50]); - $I->see(',00 from "New camera".'); - } - - /** - * @param FunctionalTester $I - */ - public function postRemoveFail(FunctionalTester $I) - { - $I->wantTo('process removing too much money from a piggy bank'); - $I->amOnPage('/piggy_banks/add/1'); - $I->see('Add money to New camera'); - $I->submitForm('#add', ['amount' => 100]); - $I->see(',00 to "New camera".'); - $I->amOnPage('/piggy_banks/remove/1'); - $I->see('Remove money from New camera'); - $I->submitForm('#remove', ['amount' => 500]); - $I->see(',00 from "New camera".'); - } - - - /** - * @param FunctionalTester $I - */ - public function remove(FunctionalTester $I) - { - $I->wantTo('removing money from a piggy bank'); - $I->amOnPage('/piggy_banks/remove/1'); - $I->see('Remove money from New camera'); - } - - /** - * @param FunctionalTester $I - */ - public function show(FunctionalTester $I) - { - $I->wantTo('view a piggy bank'); - $I->amOnPage('/piggy_banks/show/1'); - $I->see('New camera'); - } - - /** - * @param FunctionalTester $I - */ - public function store(FunctionalTester $I) - { - $I->wantTo('store a new piggy bank'); - $I->amOnPage('/piggy_banks/create'); - $I->see('Create new piggy bank'); - $I->submitForm( - '#store', ['name' => 'Some new piggy bank', - 'rep_every' => 0, - 'reminder_skip' => 0, - 'remind_me' => 0, - 'order' => 3, - 'account_id' => 1, 'targetamount' => 1000] - ); - $I->see('Piggy bank "Some new piggy bank" stored.'); - $I->seeRecord('piggy_banks', ['name' => 'Some new piggy bank']); - } - - /** - * @param FunctionalTester $I - */ - public function storeValidate(FunctionalTester $I) - { - $I->wantTo('validate a new piggy bank'); - $I->amOnPage('/piggy_banks/create'); - $I->see('Create new piggy bank'); - $I->submitForm( - '#store', ['name' => 'Some new piggy bank validated', - 'rep_every' => 0, - 'reminder_skip' => 0, - 'remind_me' => 0, - 'order' => 3, - 'post_submit_action' => 'validate_only', - 'account_id' => 1, - 'targetamount' => 1000] - ); - $I->see('OK'); - $I->seeInSession('successes'); - $I->dontSeeRecord('piggy_banks', ['name' => 'Some new piggy bank validated']); - } - - /** - * @param FunctionalTester $I - */ - public function storeAndReturn(FunctionalTester $I) - { - $I->wantTo('store a new piggy bank and return'); - $I->amOnPage('/piggy_banks/create'); - $I->see('Create new piggy bank'); - $I->submitForm( - '#store', ['name' => 'Some new piggy bank', - 'rep_every' => 0, - 'reminder_skip' => 0, - 'post_submit_action' => 'create_another', - 'remind_me' => 0, - 'order' => 3, - 'account_id' => 1, - 'targetamount' => 1000] - ); - $I->see('Piggy bank "Some new piggy bank" stored.'); - } - - /** - * @param FunctionalTester $I - */ - public function storeFail(FunctionalTester $I) - { - $I->wantTo('fail storing a new piggy bank'); - $I->amOnPage('/piggy_banks/create'); - $I->see('Create new piggy bank'); - $I->submitForm( - '#store', ['name' => null, - 'rep_every' => 0, - 'reminder_skip' => 0, - 'remind_me' => 0, - 'order' => 3, - 'account_id' => 1, - 'post_submit_action' => 'store', - 'targetamount' => 1000] - ); - $I->see('The name field is required.'); - } - - /** - * @param FunctionalTester $I - */ - public function update(FunctionalTester $I) - { - $I->wantTo('update a piggy bank'); - $I->amOnPage('/piggy_banks/edit/1'); - $I->see('Edit piggy bank "New camera"'); - $I->submitForm( - '#update', [ - 'name' => 'Updated camera', - 'account_id' => 2, - 'targetamount' => 2000, - 'targetdate' => '', - 'reminder' => 'week', - 'post_submit_action' => 'update', - ] - ); - $I->see('Piggy bank "Updated camera" updated.'); - - - } - - /** - * @param FunctionalTester $I - */ - public function updateAndReturn(FunctionalTester $I) - { - $I->wantTo('update a piggy bank and return'); - $I->amOnPage('/piggy_banks/edit/1'); - $I->see('Edit piggy bank "New camera"'); - $I->submitForm( - '#update', [ - 'name' => 'Updated camera', - 'account_id' => 2, - 'targetamount' => 2000, - 'targetdate' => '', - 'reminder' => 'week', - 'post_submit_action' => 'return_to_edit', - ] - ); - $I->see('Piggy bank "Updated camera" updated.'); - - - } - - /** - * @param FunctionalTester $I - */ - public function updateFail(FunctionalTester $I) - { - $I->wantTo('update a piggy bank and fail'); - $I->amOnPage('/piggy_banks/edit/1'); - $I->see('Edit piggy bank "New camera"'); - $I->submitForm( - '#update', [ - 'name' => '', - 'account_id' => 2, - 'targetamount' => 2000, - 'targetdate' => '', - 'reminder' => 'week', - 'post_submit_action' => 'update', - ] - ); - $I->see('The name field is required.'); - $I->seeInDatabase('piggy_banks', ['name' => 'New camera']); - - } - - /** - * @param FunctionalTester $I - */ - public function updateValidateOnly(FunctionalTester $I) - { - $I->wantTo('validate a piggy bank'); - $I->amOnPage('/piggy_banks/edit/1'); - $I->see('Edit piggy bank "New camera"'); - $I->submitForm( - '#update', [ - 'name' => 'Updated camera', - 'account_id' => 2, - 'targetamount' => 2000, - 'targetdate' => '', - 'reminder' => 'week', - 'post_submit_action' => 'validate_only', - ] - ); - $I->see('Updated camera'); - - - } - -} diff --git a/tests/functional/PreferencesControllerCest.php b/tests/functional/PreferencesControllerCest.php deleted file mode 100644 index 44080b93d6..0000000000 --- a/tests/functional/PreferencesControllerCest.php +++ /dev/null @@ -1,48 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - /** - * @param FunctionalTester $I - */ - public function index(FunctionalTester $I) - { - $I->wantTo('see my current set of preferences'); - $I->amOnPage('/preferences'); - $I->see('Preferences'); - } - - /** - * @param FunctionalTester $I - */ - public function postIndex(FunctionalTester $I) - { - $I->wantTo('want to update my preferences'); - $I->amOnPage('/preferences'); - $I->see('Preferences'); - $I->submitForm('#preferences', []); - $I->see('Preferences saved!'); - } -} diff --git a/tests/functional/ProfileControllerCest.php b/tests/functional/ProfileControllerCest.php deleted file mode 100644 index 7f6c980d20..0000000000 --- a/tests/functional/ProfileControllerCest.php +++ /dev/null @@ -1,150 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - /** - * @param FunctionalTester $I - */ - public function changePassword(FunctionalTester $I) - { - $I->wantTo('change my password.'); - $I->amOnPage('/profile/change-password'); - $I->see('thegrumpydictator@gmail.com'); - $I->see('Change your password'); - } - - /** - * @param FunctionalTester $I - */ - public function index(FunctionalTester $I) - { - $I->wantTo('see my profile options'); - $I->amOnPage('/profile'); - $I->see('thegrumpydictator@gmail.com'); - $I->see('Profile'); - } - - /** - * @param FunctionalTester $I - */ - public function postChangePassword(FunctionalTester $I) - { - $I->wantTo('submit a new password.'); - $I->amOnPage('/profile/change-password'); - $I->see('thegrumpydictator@gmail.com'); - $I->see('Change your password'); - $I->submitForm( - '#change-password', [ - 'old' => 'james', - 'new1' => 'James', - 'new2' => 'James' - ] - ); - $I->see('Password changed!'); - } - - /** - * @param FunctionalTester $I - */ - public function postChangePasswordInvalidCurrent(FunctionalTester $I) - { - $I->wantTo('submit a new password and enter the wrong current password.'); - $I->amOnPage('/profile/change-password'); - $I->see('thegrumpydictator@gmail.com'); - $I->see('Change your password'); - - $I->submitForm( - '#change-password', [ - 'old' => 'Blablabla', - 'new1' => 'James', - 'new2' => 'James' - ] - ); - $I->see('Invalid current password!'); - } - - /** - * @param FunctionalTester $I - */ - public function postChangePasswordNoMatch(FunctionalTester $I) - { - $I->wantTo('submit a new password but make a mistake in filling it in twice.'); - $I->amOnPage('/profile/change-password'); - $I->see('thegrumpydictator@gmail.com'); - $I->see('Change your password'); - - $I->submitForm( - '#change-password', [ - 'old' => 'james', - 'new1' => 'blabla', - 'new2' => 'bla' - ] - ); - $I->see('New passwords do not match!'); - } - - /** - * @param FunctionalTester $I - */ - public function postChangePasswordNoNewPassword(FunctionalTester $I) - { - $I->wantTo('submit a new password and forget to fill in a new one.'); - $I->amOnPage('/profile/change-password'); - $I->see('thegrumpydictator@gmail.com'); - $I->see('Change your password'); - - $I->submitForm( - '#change-password', [ - 'old' => 'james', - 'new1' => '', - 'new2' => '' - ] - ); - $I->see('Do fill in a password!'); - - } - - /** - * @param FunctionalTester $I - */ - public function postChangePasswordToSame(FunctionalTester $I) - { - $I->wantTo('submit a new password but fill in my old one twice.'); - $I->amOnPage('/profile/change-password'); - $I->see('thegrumpydictator@gmail.com'); - $I->see('Change your password'); - - $I->submitForm( - '#change-password', [ - 'old' => 'james', - 'new1' => 'james', - 'new2' => 'james' - ] - ); - $I->see('The idea is to change your password.'); - } - - -} diff --git a/tests/functional/RelatedControllerCest.php b/tests/functional/RelatedControllerCest.php deleted file mode 100644 index 7e7ae49ae7..0000000000 --- a/tests/functional/RelatedControllerCest.php +++ /dev/null @@ -1,120 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - - } - - /** - * @param FunctionalTester $I - */ - public function alreadyRelated(FunctionalTester $I) - { - $group = TransactionGroup::first(); - $journal = $group->transactionjournals()->first(); - - $I->wantTo('see already related transactions'); - $I->amOnPage('/related/alreadyRelated/' . $journal->id); - $I->see('Big expense in '); - - } - - /** - * @param FunctionalTester $I - */ - public function alreadyRelatedNoRelations(FunctionalTester $I) - { - $journal = TransactionJournal::first(); - - $I->wantTo('see already related transactions for a journal without any'); - $I->amOnPage('/related/alreadyRelated/' . $journal->id); - $I->see('[]'); - - } - - /** - * @param FunctionalTester $I - */ - public function relate(FunctionalTester $I) - { - $journal = TransactionJournal::leftJoin( - 'transaction_group_transaction_journal', 'transaction_journals.id', '=', 'transaction_group_transaction_journal.transaction_journal_id' - ) - ->whereNull('transaction_group_transaction_journal.transaction_group_id')->first(['transaction_journals.*']); - $otherJournal = TransactionJournal::leftJoin( - 'transaction_group_transaction_journal', 'transaction_journals.id', '=', 'transaction_group_transaction_journal.transaction_journal_id' - ) - ->whereNull('transaction_group_transaction_journal.transaction_group_id')->where( - 'transaction_journals.id', '!=', $journal->id - )->first( - ['transaction_journals.*'] - ); - $I->wantTo('relate two journals'); - $I->sendAjaxPostRequest('/related/relate/' . $journal->id . '/' . $otherJournal->id); - $I->see('true'); - } - - /** - * @param FunctionalTester $I - */ - public function related(FunctionalTester $I) - { - $group = TransactionGroup::first(); - $journal = $group->transactionjournals()->first(); - - $I->wantTo('see the popup with already related transactions'); - $I->amOnPage('/related/related/' . $journal->id); - $I->see('Big expense in '); - } - - /** - * @param FunctionalTester $I - */ - public function removeRelation(FunctionalTester $I) - { - $group = TransactionGroup::first(); - $one = $group->transactionjournals[0]; - $two = $group->transactionjournals[1]; - $I->wantTo('relate two journals'); - $I->amOnPage('/related/removeRelation/' . $one->id . '/' . $two->id); - $I->see('true'); - - } - - /** - * @param FunctionalTester $I - */ - public function search(FunctionalTester $I) - { - $one = TransactionJournal::first();//$group = TransactionGroup::first(); - //$one = $group->transactionjournals[0]; - - $I->wantTo('search for a transaction to relate'); - - $I->sendAjaxPostRequest('/related/search/' . $one->id . '?searchValue=expense'); - $I->see('Big expense in'); - } -} \ No newline at end of file diff --git a/tests/functional/ReminderControllerCest.php b/tests/functional/ReminderControllerCest.php deleted file mode 100644 index 8a28f5657f..0000000000 --- a/tests/functional/ReminderControllerCest.php +++ /dev/null @@ -1,87 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - /** - * @param FunctionalTester $I - */ - public function act(FunctionalTester $I) - { - $reminder = Reminder::leftJoin('piggy_banks', 'piggy_banks.id', '=', 'reminders.remindersable_id')->where('piggy_banks.reminder', '!=', '')->first( - ['reminders.*'] - ); - - $I->wantTo('act on a reminder'); - $I->amOnPage('/reminders/' . $reminder->id . '/act'); - $I->see('Money for Nieuwe spullen'); - } - - /** - * @param FunctionalTester $I - */ - public function actOnInvalid(FunctionalTester $I) - { - $I->wantTo('act on an invalid reminder'); - $I->amOnPage('/reminders/2/act'); - $I->see('This reminder has an invalid class connected to it.'); - } - - /** - * @param FunctionalTester $I - */ - public function dismiss(FunctionalTester $I) - { - $I->wantTo('dismiss a reminder'); - $I->amOnPage('/reminders/1/dismiss'); - $I->see('Reminder dismissed'); - } - - /** - * @param FunctionalTester $I - */ - public function notNow(FunctionalTester $I) - { - $I->wantTo('ignore a reminder'); - $I->amOnPage('/reminders/1/notNow'); - $I->see('Reminder dismissed'); - } - - /** - * @param FunctionalTester $I - */ - public function show(FunctionalTester $I) - { - $reminder = Reminder::leftJoin('piggy_banks', 'piggy_banks.id', '=', 'reminders.remindersable_id')->where('piggy_banks.reminder', '!=', '')->first( - ['reminders.*'] - ); - - $I->wantTo('see a reminder'); - $I->amOnPage('/reminders/' . $reminder->id); - $I->see('A reminder about'); - $I->see('your piggy bank labelled "Nieuwe spullen"'); - } - -} diff --git a/tests/functional/RepeatedExpenseControllerCest.php b/tests/functional/RepeatedExpenseControllerCest.php deleted file mode 100644 index 3c00f64687..0000000000 --- a/tests/functional/RepeatedExpenseControllerCest.php +++ /dev/null @@ -1,298 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - /** - * @param FunctionalTester $I - */ - public function create(FunctionalTester $I) - { - $I->wantTo('create a repeated expense'); - $I->amOnPage('/repeatedexpenses/create'); - $I->see('Create new repeated expense'); - } - - /** - * @param FunctionalTester $I - */ - public function delete(FunctionalTester $I) - { - $repeatedExpense = PiggyBank::where('repeats', 1)->first(); - $I->wantTo('delete a repeated expense'); - $I->amOnPage('/repeatedexpenses/delete/' . $repeatedExpense->id); - $I->see('Delete "' . $repeatedExpense->name . '"'); - } - - /** - * @param FunctionalTester $I - */ - public function destroy(FunctionalTester $I) - { - $repeatedExpense = PiggyBank::where('repeats', 1)->first(); - $I->wantTo('destroy a repeated expense'); - $I->amOnPage('/repeatedexpenses/delete/' . $repeatedExpense->id); - $I->submitForm('#destroy', []); - $I->see('Repeated expense "' . $repeatedExpense->name . '" deleted.'); - } - - /** - * @param FunctionalTester $I - */ - public function edit(FunctionalTester $I) - { - $repeatedExpense = PiggyBank::where('repeats', 1)->first(); - $I->wantTo('edit a repeated expense'); - $I->amOnPage('/repeatedexpenses/edit/' . $repeatedExpense->id); - $I->see('Edit repeated expense "' . $repeatedExpense->name . '"'); - - } - - /** - * @param FunctionalTester $I - */ - public function index(FunctionalTester $I) - { - $repeatedExpense = PiggyBank::where('repeats', 1)->first(); - $I->wantTo('see all repeated expenses'); - $I->amOnPage('/repeatedexpenses'); - $I->see('Overview'); - $I->see($repeatedExpense->name); - } - - /** - * @param FunctionalTester $I - */ - public function show(FunctionalTester $I) - { - $repeatedExpense = PiggyBank::where('repeats', 1)->first(); - $I->wantTo('view a repeated expense'); - $I->amOnPage('/repeatedexpenses/show/' . $repeatedExpense->id); - $I->see($repeatedExpense->name); - } - - /** - * @param FunctionalTester $I - */ - public function store(FunctionalTester $I) - { - $I->wantTo('store a repeated expense'); - $I->amOnPage('/repeatedexpenses/create'); - $I->submitForm( - '#store', [ - 'name' => 'TestRepeatedExpense', - 'account_id' => 1, - 'targetamount' => 1000, - 'targetdate' => Carbon::now()->format('Y-m-d'), - 'rep_length' => 'month', - 'rep_every' => 0, - 'rep_times' => 0, - 'remind_me' => 1, - 'reminder' => 'month', - 'post_submit_action' => 'store', - ] - ); - - $I->see('Piggy bank "TestRepeatedExpense" stored.'); - } - - /** - * @param FunctionalTester $I - */ - public function storeValidate(FunctionalTester $I) - { - $I->wantTo('validate a repeated expense'); - $I->amOnPage('/repeatedexpenses/create'); - $I->submitForm( - '#store', [ - 'name' => 'TestRepeatedExpenseXX', - 'account_id' => 1, - 'targetamount' => 1000, - 'targetdate' => Carbon::now()->format('Y-m-d'), - 'rep_length' => 'month', - 'rep_every' => 0, - 'rep_times' => 0, - 'remind_me' => 1, - 'reminder' => 'month', - 'post_submit_action' => 'validate_only', - ] - ); - - $I->see('TestRepeatedExpenseXX'); - $I->see('OK'); - $I->seeInSession('successes'); - } - - /** - * @param FunctionalTester $I - */ - public function storeAndReturn(FunctionalTester $I) - { - $I->wantTo('store a repeated expense and return'); - $I->amOnPage('/repeatedexpenses/create'); - $I->submitForm( - '#store', [ - 'name' => 'TestRepeatedExpense', - 'account_id' => 1, - 'targetamount' => 1000, - 'targetdate' => Carbon::now()->format('Y-m-d'), - 'rep_length' => 'month', - 'rep_every' => 0, - 'rep_times' => 0, - 'remind_me' => 1, - 'reminder' => 'month', - 'post_submit_action' => 'create_another', - ] - ); - - $I->see('Piggy bank "TestRepeatedExpense" stored.'); - } - - /** - * @param FunctionalTester $I - */ - public function storeFail(FunctionalTester $I) - { - $I->wantTo('store a repeated expense and fail'); - $I->amOnPage('/repeatedexpenses/create'); - $I->submitForm( - '#store', [ - 'name' => '', - 'account_id' => 1, - 'targetamount' => 1000, - 'targetdate' => Carbon::now()->format('Y-m-d'), - 'rep_length' => 'month', - 'rep_every' => 0, - 'rep_times' => 0, - 'remind_me' => 1, - 'reminder' => 'month', - 'post_submit_action' => 'store', - ] - ); - - $I->see('Could not store repeated expense: The name field is required.'); - } - - /** - * @param FunctionalTester $I - */ - public function update(FunctionalTester $I) - { - $repeatedExpense = PiggyBank::where('repeats', 1)->first(); - $I->wantTo('update a repeated expense'); - $I->amOnPage('/repeatedexpenses/edit/' . $repeatedExpense->id); - $I->submitForm( - '#update', [ - 'name' => $repeatedExpense->name . '!', - 'account_id' => 2, - 'targetamount' => 1000.00, - 'targetdate' => $repeatedExpense->targetdate->format('Y-m-d'), - 'rep_length' => 'month', - 'rep_every' => 0, - 'rep_times' => 0, - 'remind_me' => 1, - 'reminder' => 'month', - 'post_submit_action' => 'update', - ] - ); - $I->see('Repeated expense "' . $repeatedExpense->name . '!" updated.'); - } - - /** - * @param FunctionalTester $I - */ - public function updateValidate(FunctionalTester $I) - { - $repeatedExpense = PiggyBank::where('repeats', 1)->first(); - $I->wantTo('validate an updated repeated expense'); - $I->amOnPage('/repeatedexpenses/edit/' . $repeatedExpense->id); - $I->submitForm( - '#update', [ - 'name' => $repeatedExpense->name . 'ABCD', - 'account_id' => 2, - 'targetamount' => 1000.00, - 'targetdate' => $repeatedExpense->targetdate->format('Y-m-d'), - 'rep_length' => 'month', - 'rep_every' => 0, - 'rep_times' => 0, - 'remind_me' => 1, - 'reminder' => 'month', - 'post_submit_action' => 'validate_only', - ] - ); - $I->see($repeatedExpense->name . 'ABCD'); - $I->see('OK'); - $I->seeInSession('successes'); - } - - /** - * @param FunctionalTester $I - */ - public function updateAndReturnToEdit(FunctionalTester $I) - { - $repeatedExpense = PiggyBank::where('repeats', 1)->first(); - $I->wantTo('update a repeated expense and return to edit screen'); - $I->amOnPage('/repeatedexpenses/edit/' . $repeatedExpense->id); - $I->submitForm( - '#update', [ - 'name' => $repeatedExpense->name . '!', - 'account_id' => 2, - 'targetamount' => 1000.00, - 'targetdate' => $repeatedExpense->targetdate->format('Y-m-d'), - 'rep_length' => 'month', - 'rep_every' => 0, - 'rep_times' => 0, - 'remind_me' => 1, - 'reminder' => 'month', - 'post_submit_action' => 'return_to_edit', - ] - ); - $I->see('Repeated expense "' . $repeatedExpense->name . '!" updated.'); - } - - /** - * @param FunctionalTester $I - */ - public function updateFail(FunctionalTester $I) - { - $repeatedExpense = PiggyBank::where('repeats', 1)->first(); - $I->wantTo('try to update a repeated expense and fail'); - $I->amOnPage('/repeatedexpenses/edit/' . $repeatedExpense->id); - $I->submitForm( - '#update', [ - 'name' => '', - 'account_id' => 2, - 'targetamount' => 1000.00, - 'targetdate' => '2014-12-30', - 'rep_length' => 'month', - 'rep_every' => 0, - 'rep_times' => 0, - 'remind_me' => 1, - 'reminder' => 'month', - 'post_submit_action' => 'update', - ] - ); - $I->see('The name field is required.'); - } -} diff --git a/tests/functional/ReportControllerCest.php b/tests/functional/ReportControllerCest.php deleted file mode 100644 index cf47b3ba6a..0000000000 --- a/tests/functional/ReportControllerCest.php +++ /dev/null @@ -1,100 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - /** - * @param FunctionalTester $I - */ - public function budget(FunctionalTester $I) - { - $I->wantTo('see a budget report'); - $I->amOnPage('/reports/budget/2014/9'); - $I->see('Budget report for September 2014'); - } - - /** - * @param FunctionalTester $I - */ - public function budgetInvalidDate(FunctionalTester $I) - { - $I->wantTo('see a budget report for an invalid date'); - $I->amOnPage('/reports/budget/XXXX/XX'); - $I->see('Invalid date'); - } - - /** - * @param FunctionalTester $I - */ - public function index(FunctionalTester $I) - { - $I->wantTo('see all possible reports'); - $I->amOnPage('/reports'); - $I->see('Reports'); - $I->see('Monthly reports'); - $I->see('Budget reports'); - } - - /** - * @param FunctionalTester $I - */ - public function month(FunctionalTester $I) - { - $I->wantTo('see a monthly report'); - $I->amOnPage('/reports/2014/9'); - $I->see('Report for September 2014'); - } - - /** - * @param FunctionalTester $I - */ - public function monthInvalidDate(FunctionalTester $I) - { - $I->wantTo('see a monthly report for an invalid month'); - $I->amOnPage('/reports/XXXX/XX'); - $I->see('Invalid date'); - } - - /** - * @param FunctionalTester $I - */ - public function year(FunctionalTester $I) - { - $I->wantTo('see a yearly report'); - $I->amOnPage('/reports/2014'); - $I->see('Income vs. expenses'); - $I->see('Account balance'); - } - - /** - * @param FunctionalTester $I - */ - public function yearInvalidDate(FunctionalTester $I) - { - $I->wantTo('see a yearly report for an invalid year'); - $I->amOnPage('/reports/XXXX'); - $I->see('Invalid date'); - } - -} diff --git a/tests/functional/SearchControllerCest.php b/tests/functional/SearchControllerCest.php deleted file mode 100644 index 038d5bcd05..0000000000 --- a/tests/functional/SearchControllerCest.php +++ /dev/null @@ -1,45 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - /** - * @param FunctionalTester $I - */ - public function index(FunctionalTester $I) - { - $I->wantTo('search for "salary"'); - $I->amOnPage('/search?q=salary'); - $I->see('Transactions'); - $I->see('Results for "salary"'); - - } - - /** - * @param FunctionalTester $I - */ - public function indexNoQuery(FunctionalTester $I) - { - $I->wantTo('Search for empty string'); - $I->amOnPage('/search?q='); - $I->see('Search for ""'); - - } -} diff --git a/tests/functional/TransactionControllerCest.php b/tests/functional/TransactionControllerCest.php deleted file mode 100644 index 0839032a12..0000000000 --- a/tests/functional/TransactionControllerCest.php +++ /dev/null @@ -1,416 +0,0 @@ -amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - } - - /** - * @param FunctionalTester $I - */ - public function create(FunctionalTester $I) - { - $I->wantTo('create a transaction'); - $I->amOnPage('/transactions/create/withdrawal?account_id=1'); - $I->see('Add a new withdrawal'); - } - - /** - * @param FunctionalTester $I - */ - public function deleteWithdrawal(FunctionalTester $I) - { - // get withdrawal transaction type id: - $type = TransactionType::whereType('Withdrawal')->first(); - - // get a journal - $journal = TransactionJournal::where('transaction_type_id', $type->id)->first(); - $I->wantTo('delete a transaction'); - $I->amOnPage('/transaction/delete/' . $journal->id); - $I->see('Delete withdrawal "' . $journal->description . '"'); - } - - /** - * @param FunctionalTester $I - */ - public function destroyDeposit(FunctionalTester $I) - { - // get withdrawal transaction type id: - $type = TransactionType::whereType('Deposit')->first(); - - // get a journal - $journal = TransactionJournal::where('transaction_type_id', $type->id)->first(); - $I->wantTo('destroy a deposit'); - $I->amOnPage('/transaction/delete/' . $journal->id); - $I->submitForm('#destroy', []); - $I->see('Transaction "' . $journal->description . '" destroyed.'); - - } - - /** - * @param FunctionalTester $I - */ - public function destroyTransfer(FunctionalTester $I) - { - // get withdrawal transaction type id: - $type = TransactionType::whereType('Transfer')->first(); - - // get a journal - $journal = TransactionJournal::where('transaction_type_id', $type->id)->first(); - - $I->wantTo('destroy a transfer'); - - $I->amOnPage('/transaction/delete/' . $journal->id); - $I->submitForm('#destroy', []); - $I->see('Transaction "' . $journal->description . '" destroyed.'); - - } - - /** - * @param FunctionalTester $I - */ - public function destroyTransferWithEvent(FunctionalTester $I) - { - // get withdrawal transaction type id: - $row = DB::table('piggy_bank_events')->whereNotNull('transaction_journal_id')->first(); - $journalId = $row->transaction_journal_id; - $journal = TransactionJournal::find($journalId); - - $I->wantTo('destroy a transfer connected to a piggy bank'); - - $I->amOnPage('/transaction/delete/' . $journal->id); - $I->submitForm('#destroy', []); - $I->see('Transaction "' . $journal->description . '" destroyed.'); - - } - - /** - * @param FunctionalTester $I - */ - public function destroyWithdrawal(FunctionalTester $I) - { - // get withdrawal transaction type id: - $type = TransactionType::whereType('Withdrawal')->first(); - - // get a journal - $journal = TransactionJournal::where('transaction_type_id', $type->id)->first(); - - $I->wantTo('destroy a withdrawal'); - $I->amOnPage('/transaction/delete/' . $journal->id); - $I->submitForm('#destroy', []); - $I->see('Transaction "' . $journal->description . '" destroyed.'); - - } - - /** - * @param FunctionalTester $I - */ - public function edit(FunctionalTester $I) - { - // get withdrawal transaction type id: - $type = TransactionType::whereType('Transfer')->first(); - - // get a journal - $journal = TransactionJournal::where('transaction_type_id', $type->id)->first(); - - $I->wantTo('edit a transaction'); - $I->amOnPage('/transaction/edit/' . $journal->id); - $I->see('Edit transfer "' . $journal->description . '"'); - } - - /** - * @param FunctionalTester $I - */ - public function index(FunctionalTester $I) - { - $I->wantTo('see all withdrawals'); - $I->amOnPage('/transactions/withdrawal'); - $I->see('Expenses'); - } - - /** - * @param FunctionalTester $I - */ - public function indexExpenses(FunctionalTester $I) - { - $I->wantTo('see all expenses'); - $I->amOnPage('/transactions/deposit'); - $I->see('Revenue, income and deposits'); - } - - /** - * @param FunctionalTester $I - */ - public function indexTransfers(FunctionalTester $I) - { - $I->wantTo('see all transfers'); - $I->amOnPage('/transactions/transfers'); - $I->see('Transfers'); - } - - /** - * @param FunctionalTester $I - */ - public function show(FunctionalTester $I) - { - // get withdrawal transaction type id: - $type = TransactionType::whereType('Withdrawal')->first(); - - // get a journal - $journal = TransactionJournal::where('transaction_type_id', $type->id)->first(); - - $I->wantTo('see a transaction'); - $I->amOnPage('/transaction/show/' . $journal->id); - $I->see($journal->description); - $I->see(intval($journal->getAmount())); - } - - /** - * @param FunctionalTester $I - */ - public function showGroupedJournal(FunctionalTester $I) - { - $groupRow = DB::table('transaction_group_transaction_journal')->select('transaction_journal_id')->first(['transaction_journal_id']); - - $id = $groupRow->transaction_journal_id; - - // get a grouped journal: - $journal = TransactionJournal::find($id); - - - $I->wantTo('see a grouped transaction'); - $I->amOnPage('/transaction/show/' . $journal->id); - $I->see($journal->description); - } - - /** - * @param FunctionalTester $I - */ - public function store(FunctionalTester $I) - { - $I->wantTo('store a transaction'); - $I->amOnPage('/transactions/create/withdrawal'); - $I->submitForm( - '#store', [ - 'reminder' => '', - 'description' => 'Test', - 'account_id' => 1, - 'expense_account' => 'Zomaar', - 'amount' => 100, - 'date' => '2014-12-30', - 'budget_id' => 3, - 'category' => 'Categorrr', - 'post_submit_action' => 'store' - ] - ); - $I->see('Transaction "Test" stored.'); - } - - /** - * @param FunctionalTester $I - */ - public function storeAndFail(FunctionalTester $I) - { - $I->wantTo('store a transaction and fail'); - $I->amOnPage('/transactions/create/withdrawal'); - $I->submitForm( - '#store', [ - 'reminder' => '', - 'description' => '', - 'account_id' => 1, - 'expense_account' => 'Zomaar', - 'amount' => 100, - 'date' => '2014-12-30', - 'budget_id' => 3, - 'category' => 'Categorrr', - 'post_submit_action' => 'store' - ] - ); - $I->see('Could not store transaction: The description field is required.'); - } - - /** - * @param FunctionalTester $I - */ - public function storeAndReturn(FunctionalTester $I) - { - $I->wantTo('store a transaction'); - $I->amOnPage('/transactions/create/withdrawal'); - $I->submitForm( - '#store', [ - 'reminder' => '', - 'description' => 'Test', - 'account_id' => 1, - 'expense_account' => 'Zomaar', - 'amount' => 100, - 'date' => '2014-12-30', - 'budget_id' => 3, - 'category' => 'Categorrr', - 'post_submit_action' => 'create_another' - ] - ); - $I->see('Transaction "Test" stored.'); - } - - /** - * @param FunctionalTester $I - */ - public function storeValidate(FunctionalTester $I) - { - $I->wantTo('validate a transaction'); - $I->amOnPage('/transactions/create/withdrawal'); - $I->submitForm( - '#store', [ - 'reminder' => '', - 'description' => 'TestValidateMe', - 'account_id' => 1, - 'expense_account' => 'Zomaar', - 'amount' => 100, - 'date' => '2014-12-30', - 'budget_id' => 3, - 'category' => 'CategorrXXXXr', - 'post_submit_action' => 'validate_only' - ] - ); - $I->see('OK'); - $I->seeInSession('successes'); - $I->dontSeeRecord('transaction_journals', ['description' => 'TestValidateMe']); - } - - /** - * @param FunctionalTester $I - */ - public function update(FunctionalTester $I) - { - // get withdrawal transaction type id: - $type = TransactionType::whereType('Deposit')->first(); - - // get a journal - $journal = TransactionJournal::where('transaction_type_id', $type->id)->first(); - - $I->wantTo('update a transaction'); - $I->amOnPage('/transaction/edit/' . $journal->id); - $I->see($journal->description); - $I->submitForm( - '#update', [ - 'description' => $journal->description . '!', - 'account_id' => 1, - 'expense_account' => 'Portaal', - 'amount' => 500, - 'date' => $journal->date->format('Y-m-d'), - 'budget_id' => is_null($journal->budgets()->first()) ? 0 : $journal->budgets()->first()->id, - 'category' => is_null($journal->categories()->first()) ? '' : $journal->categories()->first()->id, - 'post_submit_action' => 'update' - ] - ); - $I->see($journal->description . '!'); - } - - /** - * @param FunctionalTester $I - */ - public function updateAndFail(FunctionalTester $I) - { - // get withdrawal transaction type id: - $type = TransactionType::whereType('Deposit')->first(); - - // get a journal - $journal = TransactionJournal::where('transaction_type_id', $type->id)->first(); - - $I->wantTo('update a transaction and fail'); - $I->amOnPage('/transaction/edit/' . $journal->id); - $I->see($journal->description); - $I->submitForm( - '#update', [ - 'description' => '', - 'account_id' => 1, - 'expense_account' => 'Portaal', - 'amount' => 500, - 'date' => '2014-01-01', - 'budget_id' => 2, - 'category' => 'House', - 'post_submit_action' => 'update' - ] - ); - $I->see('Could not update transaction: The description field is required.'); - } - - /** - * @param FunctionalTester $I - */ - public function updateAndReturn(FunctionalTester $I) - { - // get withdrawal transaction type id: - $type = TransactionType::whereType('Deposit')->first(); - - // get a journal - $journal = TransactionJournal::where('transaction_type_id', $type->id)->first(); - $I->wantTo('update a transaction and return to the edit screen'); - $I->amOnPage('/transaction/edit/' . $journal->id); - $I->see($journal->description); - $I->submitForm( - '#update', [ - 'description' => $journal->description . '!', - 'account_id' => 1, - 'expense_account' => 'Portaal', - 'amount' => 500, - 'date' => $journal->date->format('Y-m-d'), - 'budget_id' => is_null($journal->budgets()->first()) ? 0 : $journal->budgets()->first()->id, - 'category' => is_null($journal->categories()->first()) ? '' : $journal->categories()->first()->id, - 'post_submit_action' => 'return_to_edit' - ] - ); - $I->see($journal->description . '!'); - } - - /** - * @param FunctionalTester $I - */ - public function updateValidate(FunctionalTester $I) - { - // get withdrawal transaction type id: - $type = TransactionType::whereType('Deposit')->first(); - - // get a journal - $journal = TransactionJournal::where('transaction_type_id', $type->id)->first(); - - $I->wantTo('validate an updated transaction'); - $I->amOnPage('/transaction/edit/' . $journal->id); - $I->see($journal->description); - $I->submitForm( - '#update', [ - 'description' => $journal->description . 'XYZ', - 'account_id' => 1, - 'expense_account' => 'Portaal', - 'amount' => 500, - 'date' => $journal->date->format('Y-m-d'), - 'budget_id' => is_null($journal->budgets()->first()) ? 0 : $journal->budgets()->first()->id, - 'category' => is_null($journal->categories()->first()) ? '' : $journal->categories()->first()->id, - 'post_submit_action' => 'validate_only' - ] - ); - $I->see($journal->description . 'XYZ'); - $I->see('OK'); - $I->seeInSession('successes'); - } - - -} diff --git a/tests/functional/UserControllerCest.php b/tests/functional/UserControllerCest.php deleted file mode 100644 index a9a5141632..0000000000 --- a/tests/functional/UserControllerCest.php +++ /dev/null @@ -1,150 +0,0 @@ -wantTo('login'); - $I->amOnPage('/login'); - $I->see('Sign In'); - $I->submitForm('#login', ['email' => 'functional@example.com', 'password' => 'functional']); - $I->see('functional@example.com'); - - } - - /** - * @param FunctionalTester $I - */ - public function loginFails(FunctionalTester $I) - { - $I->wantTo('fail the login'); - $I->amOnPage('/login'); - $I->see('Sign In'); - $I->submitForm('#login', ['email' => 'functional@example.com', 'password' => 'wrong']); - $I->see('No good'); - - } - - /** - * @param FunctionalTester $I - */ - public function logout(FunctionalTester $I) - { - $I->amLoggedAs(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james']); - $I->wantTo('logout'); - $I->amOnPage('/'); - $I->click('Logout'); - $I->see('Firefly III — Sign In'); - } - - /** - * @param FunctionalTester $I - */ - public function postRegister(FunctionalTester $I) - { - $I->wantTo('post-register a new account'); - $I->amOnPage('/register'); - $I->submitForm('#register', ['email' => 'noreply@gmail.com']); - $I->see('You\'re about to get an e-mail. Please follow its instructions.'); - $I->seeRecord('users', ['email' => 'noreply@gmail.com']); - } - - /** - * @param FunctionalTester $I - */ - public function postRegisterFail(FunctionalTester $I) - { - $I->wantTo('post-register a new account and fail'); - $I->amOnPage('/register'); - $I->submitForm('#register', ['email' => 'XXxxxxx']); - $I->see('Input invalid, please try again: The email must be a valid email address.'); - $I->dontseeRecord('users', ['email' => 'XXxxxxx']); - } - - /** - * @param FunctionalTester $I - */ - public function postRemindme(FunctionalTester $I) - { - $I->wantTo('get a password reminder'); - $I->amOnRoute('remindMe'); - $I->submitForm('#remindMe', ['email' => 'functional@example.com']); - $I->see('You\'re about to get an e-mail.'); - } - - /** - * @param FunctionalTester $I - */ - public function postRemindmeFail(FunctionalTester $I) - { - $I->wantTo('get a password reminder and fail'); - $I->amOnRoute('remindMe'); - $I->submitForm('#remindMe', ['email' => 'abcdee']); - $I->see('No good!'); - } - - /** - * @param FunctionalTester $I - */ - public function register(FunctionalTester $I) - { - $I->wantTo('register a new account'); - $I->amOnRoute('register'); - - - } - - /** - * @param FunctionalTester $I - */ - public function remindMe(FunctionalTester $I) - { - $I->wantTo('reminded of my password'); - $I->amOnRoute('remindMe'); - $I->see('Firefly III — Reset your password'); - } - - /** - * @param FunctionalTester $I - */ - public function resetFail(FunctionalTester $I) - { - $I->wantTo('reset my password and fail'); - $I->amOnPage('/reset/123'); - $I->see('No reset code found!'); - } - - /** - * @param FunctionalTester $I - */ - public function reset(FunctionalTester $I) - { - $I->wantTo('reset my password'); - $I->amOnPage('/reset/okokokokokokokokokokokokokokokok'); - $I->see('You\'re about to get an e-mail.'); - } - -} diff --git a/tests/functional/_bootstrap.php b/tests/functional/_bootstrap.php deleted file mode 100644 index e489e45b9e..0000000000 --- a/tests/functional/_bootstrap.php +++ /dev/null @@ -1,8 +0,0 @@ - tests/_data/dump.sql', $out); -} diff --git a/tests/unit.suite.yml b/tests/unit.suite.yml deleted file mode 100644 index 4ffbf160ec..0000000000 --- a/tests/unit.suite.yml +++ /dev/null @@ -1,6 +0,0 @@ -# Codeception Test Suite Configuration - -# suite for unit (internal) tests. -class_name: UnitTester -modules: - enabled: [Asserts, UnitHelper] diff --git a/tests/unit/AccountTest.php b/tests/unit/AccountTest.php deleted file mode 100644 index 16145d8932..0000000000 --- a/tests/unit/AccountTest.php +++ /dev/null @@ -1,40 +0,0 @@ -updateMeta('field', 'value'); - $this->assertInstanceOf('AccountMeta', $newMeta); - $secondMeta = $account->updateMeta('field', 'newValue'); - $this->assertEquals($newMeta->id, $secondMeta->id); - $this->assertEquals($newMeta->data, 'value'); - $this->assertEquals($secondMeta->data, 'newValue'); - } - - public function testAccountUser() - { - $account = f::create('Account'); - $this->assertInstanceOf('Account', $account); - $this->assertInstanceOf('User', $account->user); - } - -} diff --git a/tests/unit/AccountTypeTest.php b/tests/unit/AccountTypeTest.php deleted file mode 100644 index 94aede8b6a..0000000000 --- a/tests/unit/AccountTypeTest.php +++ /dev/null @@ -1,27 +0,0 @@ -assertCount(1, $account->accountType()->first()->accounts()->get()); - } - -} diff --git a/tests/unit/BudgetTest.php b/tests/unit/BudgetTest.php deleted file mode 100644 index 88321ee974..0000000000 --- a/tests/unit/BudgetTest.php +++ /dev/null @@ -1,26 +0,0 @@ -assertInstanceOf('User', $budget->user); - - } -} diff --git a/tests/unit/PiggyBankRepetitionTest.php b/tests/unit/PiggyBankRepetitionTest.php deleted file mode 100644 index 3bf35313e6..0000000000 --- a/tests/unit/PiggyBankRepetitionTest.php +++ /dev/null @@ -1,29 +0,0 @@ -startdate; - $target = clone $repetition->targetdate; - - $this->assertCount(1, PiggyBankRepetition::starts($start)->get()); - $this->assertCount(1, PiggyBankRepetition::targets($target)->get()); - } -} diff --git a/tests/unit/PiggyBankTest.php b/tests/unit/PiggyBankTest.php deleted file mode 100644 index efe7210cc0..0000000000 --- a/tests/unit/PiggyBankTest.php +++ /dev/null @@ -1,27 +0,0 @@ -reminders()->save($reminder); - $this->assertCount(1, $piggyBank->reminders()->get()); - } -} diff --git a/tests/unit/ReminderTest.php b/tests/unit/ReminderTest.php deleted file mode 100644 index 6a792ff9c4..0000000000 --- a/tests/unit/ReminderTest.php +++ /dev/null @@ -1,38 +0,0 @@ -startdate; - $end = clone $reminder->enddate; - $this->assertCount(1, Reminder::dateIs($start, $end)->get()); - - } - - public function testUser() - { - $user = f::create('User'); - $reminder = f::create('Reminder'); - $reminder->user_id = $user->id; - $reminder->save(); - - $this->assertEquals($reminder->user->id, $user->id); - } -} diff --git a/tests/unit/TransactionGroupTest.php b/tests/unit/TransactionGroupTest.php deleted file mode 100644 index 9c3b72272b..0000000000 --- a/tests/unit/TransactionGroupTest.php +++ /dev/null @@ -1,25 +0,0 @@ -assertEquals($group->user_id, $group->user->id); - } -} diff --git a/tests/unit/TransactionJournalTest.php b/tests/unit/TransactionJournalTest.php deleted file mode 100644 index 863c87cff8..0000000000 --- a/tests/unit/TransactionJournalTest.php +++ /dev/null @@ -1,33 +0,0 @@ -transactions()->save($transaction); - $journal->transactions()->save($other); - - $amount = floatval($transaction->amount); - $amount--; - - $this->assertCount(1, TransactionJournal::moreThan($amount)->get()); - } -} diff --git a/tests/unit/TransactionTest.php b/tests/unit/TransactionTest.php deleted file mode 100644 index f154d5130e..0000000000 --- a/tests/unit/TransactionTest.php +++ /dev/null @@ -1,67 +0,0 @@ -assertCount(1, Transaction::accountIs($transaction->account)->get()); - } - - public function testDateAfter() - { - $transaction = f::create('Transaction'); - $date = clone $transaction->transactionJournal->date; - $date->subDay(); - - $this->assertCount(1, Transaction::after($date)->get()); - } - - public function testDateBefore() - { - $transaction = f::create('Transaction'); - $date = clone $transaction->transactionJournal->date; - $date->addDay(); - - $this->assertCount(1, Transaction::before($date)->get()); - } - - public function testLessThan() - { - $transaction = f::create('Transaction'); - $amount = floatval($transaction->amount); - $amount++; - $this->assertCount(1, Transaction::lessThan($amount)->get()); - } - - public function testMoreThan() - { - $transaction = f::create('Transaction'); - $amount = floatval($transaction->amount); - $amount--; - $this->assertCount(1, Transaction::moreThan($amount)->get()); - } - - public function testTransactionTypes() - { - $transaction = f::create('Transaction'); - $type = $transaction->transactionJournal->transactionType->type; - $this->assertCount(1, Transaction::transactionTypes([$type])->get()); - } -} diff --git a/tests/unit/TransactionTypeTest.php b/tests/unit/TransactionTypeTest.php deleted file mode 100644 index d2b4033d69..0000000000 --- a/tests/unit/TransactionTypeTest.php +++ /dev/null @@ -1,30 +0,0 @@ -transactionType; - $this->assertCount(1, $type->transactionJournals()->get()); - } - - -} diff --git a/tests/unit/UserTest.php b/tests/unit/UserTest.php deleted file mode 100644 index 87b4c9d69e..0000000000 --- a/tests/unit/UserTest.php +++ /dev/null @@ -1,36 +0,0 @@ -assertEquals($pref->user_id, $pref->user->id); - $this->assertCount(1, $pref->user->preferences()->get()); - } - - public function testReminder() - { - $reminder = f::create('Reminder'); - $this->assertEquals($reminder->user_id, $reminder->user->id); - $this->assertCount(1, $reminder->user->reminders()->get()); - } - -} diff --git a/tests/unit/_bootstrap.php b/tests/unit/_bootstrap.php deleted file mode 100644 index 8a88555806..0000000000 --- a/tests/unit/_bootstrap.php +++ /dev/null @@ -1,2 +0,0 @@ - Date: Fri, 27 Feb 2015 20:46:39 +0100 Subject: [PATCH 02/87] Clean up test stuff. --- .travis.yml | 8 +------- composer.json | 7 ++----- tests/ExampleTest.php | 4 +--- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index e96ea998f8..a5d9249137 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,12 +15,6 @@ install: - mv -v .env.testing .env script: - - ./tests/_data/db.sh - - php vendor/bin/codecept build - - php vendor/bin/codecept run --coverage --coverage-xml --no-exit + - phpunit after_script: - - cp -v tests/_output/coverage.xml build/logs/clover.xml - - php vendor/bin/coveralls - - vendor/bin/test-reporter --stdout > codeclimate.json - - "curl -X POST -d @codeclimate.json -H 'Content-Type: application/json' -H 'User-Agent: Code Climate (PHP Test Reporter v0.1.1)' https://codeclimate.com/test_reports" \ No newline at end of file diff --git a/composer.json b/composer.json index 06b22adc7b..ba60b7c3be 100644 --- a/composer.json +++ b/composer.json @@ -51,14 +51,11 @@ "scripts": { "post-install-cmd": [ "php artisan clear-compiled", - "php artisan optimize", - "Codeception\\c3\\Installer::copyC3ToRoot" - + "php artisan optimize" ], "post-update-cmd": [ "php artisan clear-compiled", - "php artisan optimize", - "Codeception\\c3\\Installer::copyC3ToRoot" + "php artisan optimize" ], "post-create-project-cmd": [ "php -r \"copy('.env.example', '.env');\"", diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php index bba8e18db0..6a06d11115 100644 --- a/tests/ExampleTest.php +++ b/tests/ExampleTest.php @@ -13,9 +13,7 @@ class ExampleTest extends TestCase */ public function testBasicExample() { - $response = $this->call('GET', '/'); - - $this->assertEquals(200, $response->getStatusCode()); + $this->assertTrue(true); } } From 42378502999e059c4ad4ada79e81f5584ede3d0f Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 27 Feb 2015 20:52:49 +0100 Subject: [PATCH 03/87] Restoring code coverage --- .coveralls.yml | 3 +-- .travis.yml | 3 +++ phpunit.xml | 5 +++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.coveralls.yml b/.coveralls.yml index 8951ac7b73..51544bf56e 100644 --- a/.coveralls.yml +++ b/.coveralls.yml @@ -1,3 +1,2 @@ src_dir: . -coverage_clover: tests/_output/coverage.xml -json_path: tests/_output/coveralls-upload.json +coverage_clover: storage/coverage/clover.xml \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index a5d9249137..c91cbb81f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,3 +18,6 @@ script: - phpunit after_script: + - php vendor/bin/coveralls + - vendor/bin/test-reporter --stdout > codeclimate.json + - "curl -X POST -d @codeclimate.json -H 'Content-Type: application/json' -H 'User-Agent: Code Climate (PHP Test Reporter v0.1.1)' https://codeclimate.com/test_reports" diff --git a/phpunit.xml b/phpunit.xml index 910d6195f7..e7af1a2623 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -14,6 +14,11 @@ ./tests/ + + + ./app + + From cffe05e22ba192399a119fb7b27f066d151f8d94 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 27 Feb 2015 21:01:18 +0100 Subject: [PATCH 04/87] Add coveralls to composer.json --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ba60b7c3be..72ecc4fac1 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,8 @@ "barryvdh/laravel-debugbar": "@stable", "barryvdh/laravel-ide-helper": "~2.0", "phpunit/phpunit": "~4.0", - "phpspec/phpspec": "~2.1" + "phpspec/phpspec": "~2.1", + "satooshi/php-coveralls": "0.6.1" }, "autoload": { "classmap": [ From 4c5681478547dc1ba3b4d27b181aeb9a78296e4e Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 27 Feb 2015 21:15:21 +0100 Subject: [PATCH 05/87] Do code coverage from phpunit. --- .gitignore | 1 + phpunit.xml | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index ddec920a30..60d6836759 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ c3.php db.sqlite-journal tests/_output/* .env +clover.xml diff --git a/phpunit.xml b/phpunit.xml index e7af1a2623..a440863019 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -19,6 +19,12 @@ ./app + + + + + + From 21fb41545b9b5c502af33864aeec37177a43cd33 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 27 Feb 2015 21:24:14 +0100 Subject: [PATCH 06/87] Now with son_path variable. --- .coveralls.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.coveralls.yml b/.coveralls.yml index 51544bf56e..0c2d3ece9c 100644 --- a/.coveralls.yml +++ b/.coveralls.yml @@ -1,2 +1,3 @@ src_dir: . -coverage_clover: storage/coverage/clover.xml \ No newline at end of file +coverage_clover: storage/coverage/clover.xml +json_path: storage/coverage/coveralls-upload.json \ No newline at end of file From d099c33e5b15ba4d79bba909a7391d02516e5f89 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 27 Feb 2015 21:40:49 +0100 Subject: [PATCH 07/87] No more code climate for now. --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c91cbb81f8..702afba662 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,5 +19,3 @@ script: after_script: - php vendor/bin/coveralls - - vendor/bin/test-reporter --stdout > codeclimate.json - - "curl -X POST -d @codeclimate.json -H 'Content-Type: application/json' -H 'User-Agent: Code Climate (PHP Test Reporter v0.1.1)' https://codeclimate.com/test_reports" From d1cf683f579244392ccd87e4e4ffba5eec8f6a3a Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 1 Mar 2015 07:50:26 +0100 Subject: [PATCH 08/87] Some layout and content updates --- app/Http/Requests/BillFormRequest.php | 4 +- app/Models/Account.php | 20 +- composer.lock | 257 +++++++++++++++++- ...014_06_27_163259_create_accounts_table.php | 2 +- .../2015_02_27_210653_changes_for_v332.php | 45 +++ database/seeds/TestDataSeeder.php | 6 +- resources/views/layouts/guest.blade.php | 8 +- resources/views/transactions/show.blade.php | 4 - 8 files changed, 332 insertions(+), 14 deletions(-) create mode 100644 database/migrations/2015_02_27_210653_changes_for_v332.php diff --git a/app/Http/Requests/BillFormRequest.php b/app/Http/Requests/BillFormRequest.php index 2c9452cccb..f66c5db1b1 100644 --- a/app/Http/Requests/BillFormRequest.php +++ b/app/Http/Requests/BillFormRequest.php @@ -33,8 +33,8 @@ class BillFormRequest extends Request public function rules() { $nameRule = 'required|between:1,255|uniqueForUser:bills,name'; - if(intval(Input::get('id')) > 0) { - $nameRule .= ','.intval(Input::get('id')); + if (intval(Input::get('id')) > 0) { + $nameRule .= ',' . intval(Input::get('id')); } $rules = [ diff --git a/app/Models/Account.php b/app/Models/Account.php index 2c6c21002e..9c91fa403d 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -4,7 +4,7 @@ use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; use Watson\Validating\ValidatingTrait; - +use Crypt; /** * Class Account * @@ -18,7 +18,7 @@ class Account extends Model = [ 'user_id' => 'required|exists:users,id', 'account_type_id' => 'required|exists:account_types,id', - 'name' => 'required|between:1,100|uniqueForUser:accounts,name', + 'name' => 'required|between:1,1024|uniqueForUser:accounts,name', 'active' => 'required|boolean' ]; @@ -41,6 +41,22 @@ class Account extends Model } + /** + * @param $value + * + * @return string + */ + public function getNameAttribute($value) + { + if ($this->encrypted) { + return Crypt::decrypt($value); + } + + // @codeCoverageIgnoreStart + return $value; + // @codeCoverageIgnoreEnd + } + /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ diff --git a/composer.lock b/composer.lock index 535b49e4e9..ae11fb33b9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "16fc4f36aacc020097a22c4fe7ef7687", + "hash": "1aaed0055d07325d7f417f2a6a7739bd", "packages": [ { "name": "classpreloader/classpreloader", @@ -2553,6 +2553,98 @@ ], "time": "2014-10-13 12:58:55" }, + { + "name": "guzzle/guzzle", + "version": "v3.9.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle3.git", + "reference": "54991459675c1a2924122afbb0e5609ade581155" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/54991459675c1a2924122afbb0e5609ade581155", + "reference": "54991459675c1a2924122afbb0e5609ade581155", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.3", + "symfony/event-dispatcher": "~2.1" + }, + "replace": { + "guzzle/batch": "self.version", + "guzzle/cache": "self.version", + "guzzle/common": "self.version", + "guzzle/http": "self.version", + "guzzle/inflection": "self.version", + "guzzle/iterator": "self.version", + "guzzle/log": "self.version", + "guzzle/parser": "self.version", + "guzzle/plugin": "self.version", + "guzzle/plugin-async": "self.version", + "guzzle/plugin-backoff": "self.version", + "guzzle/plugin-cache": "self.version", + "guzzle/plugin-cookie": "self.version", + "guzzle/plugin-curlauth": "self.version", + "guzzle/plugin-error-response": "self.version", + "guzzle/plugin-history": "self.version", + "guzzle/plugin-log": "self.version", + "guzzle/plugin-md5": "self.version", + "guzzle/plugin-mock": "self.version", + "guzzle/plugin-oauth": "self.version", + "guzzle/service": "self.version", + "guzzle/stream": "self.version" + }, + "require-dev": { + "doctrine/cache": "~1.3", + "monolog/monolog": "~1.0", + "phpunit/phpunit": "3.7.*", + "psr/log": "~1.0", + "symfony/class-loader": "~2.1", + "zendframework/zend-cache": "2.*,<2.3", + "zendframework/zend-log": "2.*,<2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.9-dev" + } + }, + "autoload": { + "psr-0": { + "Guzzle": "src/", + "Guzzle\\Tests": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Guzzle Community", + "homepage": "https://github.com/guzzle/guzzle/contributors" + } + ], + "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2014-08-11 04:32:36" + }, { "name": "maximebf/debugbar", "version": "v1.10.4", @@ -3198,6 +3290,74 @@ ], "time": "2014-10-03 05:12:11" }, + { + "name": "satooshi/php-coveralls", + "version": "v0.6.1", + "source": { + "type": "git", + "url": "https://github.com/satooshi/php-coveralls.git", + "reference": "dd0df95bd37a7cf5c5c50304dfe260ffe4b50760" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/dd0df95bd37a7cf5c5c50304dfe260ffe4b50760", + "reference": "dd0df95bd37a7cf5c5c50304dfe260ffe4b50760", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-simplexml": "*", + "guzzle/guzzle": ">=3.0", + "php": ">=5.3", + "psr/log": "1.0.0", + "symfony/config": ">=2.0", + "symfony/console": ">=2.0", + "symfony/stopwatch": ">=2.2", + "symfony/yaml": ">=2.0" + }, + "require-dev": { + "apigen/apigen": "2.8.*@stable", + "pdepend/pdepend": "dev-master", + "phpmd/phpmd": "dev-master", + "phpunit/php-invoker": ">=1.1.0,<1.2.0", + "phpunit/phpunit": "3.7.*@stable", + "sebastian/finder-facade": "dev-master", + "sebastian/phpcpd": "1.4.*@stable", + "squizlabs/php_codesniffer": "1.4.*@stable", + "theseer/fdomdocument": "dev-master" + }, + "bin": [ + "composer/bin/coveralls" + ], + "type": "library", + "autoload": { + "psr-0": { + "Contrib\\Component": "src/", + "Contrib\\Bundle": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kitamura Satoshi", + "email": "with.no.parachute@gmail.com", + "homepage": "https://www.facebook.com/satooshi.jp" + } + ], + "description": "PHP client library for Coveralls API", + "homepage": "https://github.com/satooshi/php-coveralls", + "keywords": [ + "ci", + "coverage", + "github", + "test" + ], + "time": "2013-05-04 08:07:33" + }, { "name": "sebastian/comparator", "version": "1.1.1", @@ -3619,6 +3779,101 @@ "homepage": "http://symfony.com", "time": "2015-01-05 14:28:40" }, + { + "name": "symfony/config", + "version": "v2.6.4", + "target-dir": "Symfony/Component/Config", + "source": { + "type": "git", + "url": "https://github.com/symfony/Config.git", + "reference": "a9f781ba1221067d1f07c8cec0bc50f81b8d7408" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Config/zipball/a9f781ba1221067d1f07c8cec0bc50f81b8d7408", + "reference": "a9f781ba1221067d1f07c8cec0bc50f81b8d7408", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/filesystem": "~2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Config\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Config Component", + "homepage": "http://symfony.com", + "time": "2015-01-21 20:57:55" + }, + { + "name": "symfony/stopwatch", + "version": "v2.6.4", + "target-dir": "Symfony/Component/Stopwatch", + "source": { + "type": "git", + "url": "https://github.com/symfony/Stopwatch.git", + "reference": "e8da5286132ba75ce4b4275fbf0f4cd369bfd71c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/e8da5286132ba75ce4b4275fbf0f4cd369bfd71c", + "reference": "e8da5286132ba75ce4b4275fbf0f4cd369bfd71c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Stopwatch\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Stopwatch Component", + "homepage": "http://symfony.com", + "time": "2015-01-03 08:01:59" + }, { "name": "symfony/yaml", "version": "v2.6.4", diff --git a/database/migrations/2014_06_27_163259_create_accounts_table.php b/database/migrations/2014_06_27_163259_create_accounts_table.php index 59c3cd4682..afe4f52999 100644 --- a/database/migrations/2014_06_27_163259_create_accounts_table.php +++ b/database/migrations/2014_06_27_163259_create_accounts_table.php @@ -36,7 +36,7 @@ class CreateAccountsTable extends Migration $table->softDeletes(); $table->integer('user_id')->unsigned(); $table->integer('account_type_id')->unsigned(); - $table->string('name', 100); + $table->string('name', 1024); $table->boolean('active'); // connect accounts to users diff --git a/database/migrations/2015_02_27_210653_changes_for_v332.php b/database/migrations/2015_02_27_210653_changes_for_v332.php new file mode 100644 index 0000000000..f8f464a363 --- /dev/null +++ b/database/migrations/2015_02_27_210653_changes_for_v332.php @@ -0,0 +1,45 @@ +boolean('encrypted'); + + } + ); + + Schema::table( + 'accounts', function (Blueprint $table) { + $table->boolean('encrypted'); + + } + ); + + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } + +} diff --git a/database/seeds/TestDataSeeder.php b/database/seeds/TestDataSeeder.php index 35bd3d8d9f..dc749f7788 100644 --- a/database/seeds/TestDataSeeder.php +++ b/database/seeds/TestDataSeeder.php @@ -279,7 +279,7 @@ class TestDataSeeder extends Seeder ); // and some events! PiggyBankEvent::create(['piggy_bank_id' => $newCamera->id, 'date' => $this->som, 'amount' => 100]); - PiggyBankRepetition::create(['piggy_bank_id' => $newCamera->id, 'startdate' => $this->som, 'targetdate' => null, 'currentamount' => 100]); + //PiggyBankRepetition::create(['piggy_bank_id' => $newCamera->id, 'startdate' => $this->som, 'targetdate' => null, 'currentamount' => 100]); $newClothes = PiggyBank::create( @@ -301,7 +301,7 @@ class TestDataSeeder extends Seeder ); PiggyBankEvent::create(['piggy_bank_id' => $newClothes->id, 'date' => $this->som, 'amount' => 100]); - PiggyBankRepetition::create(['piggy_bank_id' => $newClothes->id, 'startdate' => $this->som, 'targetdate' => $end, 'currentamount' => 100]); + //PiggyBankRepetition::create(['piggy_bank_id' => $newClothes->id, 'startdate' => $this->som, 'targetdate' => $end, 'currentamount' => 100]); // weekly reminder piggy bank $weekly = PiggyBank::create( @@ -321,7 +321,7 @@ class TestDataSeeder extends Seeder 'order' => 0, ] ); - PiggyBankRepetition::create(['piggy_bank_id' => $weekly->id, 'startdate' => $this->som, 'targetdate' => $next, 'currentamount' => 0]); + //PiggyBankRepetition::create(['piggy_bank_id' => $weekly->id, 'startdate' => $this->som, 'targetdate' => $next, 'currentamount' => 0]); } /** diff --git a/resources/views/layouts/guest.blade.php b/resources/views/layouts/guest.blade.php index cdc201e0c4..38434b2a04 100644 --- a/resources/views/layouts/guest.blade.php +++ b/resources/views/layouts/guest.blade.php @@ -8,8 +8,10 @@ Firefly III + + - + @@ -44,5 +46,9 @@ + + + + diff --git a/resources/views/transactions/show.blade.php b/resources/views/transactions/show.blade.php index 345f9b8b0d..4007a037c3 100644 --- a/resources/views/transactions/show.blade.php +++ b/resources/views/transactions/show.blade.php @@ -7,7 +7,6 @@
Metadata
-
@@ -45,7 +44,6 @@ @endforeach
Date
-
@if(count($journal->piggyBankEvents) > 0) @@ -100,7 +98,6 @@
{{{$t->account->name}}}
{{{$t->account->accounttype->description}}}
-
@@ -117,7 +114,6 @@ @endif
Amount
-
@endforeach From 0d0df5f143f136365562643d29194b6b42608b2e Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 1 Mar 2015 08:15:24 +0100 Subject: [PATCH 09/87] Scan bills when editing and creating journals. --- app/Providers/EventServiceProvider.php | 29 +++++++++++++++---- ...014_06_27_163259_create_accounts_table.php | 2 +- .../2015_02_27_210653_changes_for_v332.php | 6 ---- database/seeds/TestDataSeeder.php | 11 +++---- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 2a98c7656e..cfd63570c2 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -1,18 +1,20 @@ user->bills()->where('active', 1)->where('automatch', 1)->get(); + /** @var Bill $bill */ + foreach ($list as $bill) { + $repository->scan($bill, $journal); + } + } + ); + + Account::deleted( function (Account $account) { @@ -68,14 +85,16 @@ class EventServiceProvider extends ServiceProvider } ); - PiggyBank::created(function(PiggyBank $piggyBank) { + PiggyBank::created( + function (PiggyBank $piggyBank) { $repetition = new PiggyBankRepetition; $repetition->piggyBank()->associate($piggyBank); $repetition->startdate = $piggyBank->startdate; $repetition->targetdate = $piggyBank->targetdate; $repetition->currentamount = 0; $repetition->save(); - }); + } + ); BudgetLimit::saved( function (BudgetLimit $budgetLimit) { diff --git a/database/migrations/2014_06_27_163259_create_accounts_table.php b/database/migrations/2014_06_27_163259_create_accounts_table.php index afe4f52999..59c3cd4682 100644 --- a/database/migrations/2014_06_27_163259_create_accounts_table.php +++ b/database/migrations/2014_06_27_163259_create_accounts_table.php @@ -36,7 +36,7 @@ class CreateAccountsTable extends Migration $table->softDeletes(); $table->integer('user_id')->unsigned(); $table->integer('account_type_id')->unsigned(); - $table->string('name', 1024); + $table->string('name', 100); $table->boolean('active'); // connect accounts to users diff --git a/database/migrations/2015_02_27_210653_changes_for_v332.php b/database/migrations/2015_02_27_210653_changes_for_v332.php index f8f464a363..f379cea4c2 100644 --- a/database/migrations/2015_02_27_210653_changes_for_v332.php +++ b/database/migrations/2015_02_27_210653_changes_for_v332.php @@ -15,12 +15,6 @@ class ChangesForV332 extends Migration { */ public function up() { - Schema::table( - 'transaction_journals', function (Blueprint $table) { - $table->boolean('encrypted'); - - } - ); Schema::table( 'accounts', function (Blueprint $table) { diff --git a/database/seeds/TestDataSeeder.php b/database/seeds/TestDataSeeder.php index dc749f7788..b38e7fa5db 100644 --- a/database/seeds/TestDataSeeder.php +++ b/database/seeds/TestDataSeeder.php @@ -279,7 +279,6 @@ class TestDataSeeder extends Seeder ); // and some events! PiggyBankEvent::create(['piggy_bank_id' => $newCamera->id, 'date' => $this->som, 'amount' => 100]); - //PiggyBankRepetition::create(['piggy_bank_id' => $newCamera->id, 'startdate' => $this->som, 'targetdate' => null, 'currentamount' => 100]); $newClothes = PiggyBank::create( @@ -301,7 +300,6 @@ class TestDataSeeder extends Seeder ); PiggyBankEvent::create(['piggy_bank_id' => $newClothes->id, 'date' => $this->som, 'amount' => 100]); - //PiggyBankRepetition::create(['piggy_bank_id' => $newClothes->id, 'startdate' => $this->som, 'targetdate' => $end, 'currentamount' => 100]); // weekly reminder piggy bank $weekly = PiggyBank::create( @@ -321,7 +319,6 @@ class TestDataSeeder extends Seeder 'order' => 0, ] ); - //PiggyBankRepetition::create(['piggy_bank_id' => $weekly->id, 'startdate' => $this->som, 'targetdate' => $next, 'currentamount' => 0]); } /** @@ -374,10 +371,10 @@ class TestDataSeeder extends Seeder 'order' => 0, ] ); - PiggyBankRepetition::create(['piggy_bank_id' => $recurring->id, 'startdate' => $this->som, 'targetdate' => $this->eom, 'currentamount' => 0]); - PiggyBankRepetition::create( - ['piggy_bank_id' => $recurring->id, 'startdate' => $this->nsom, 'targetdate' => $this->neom, 'currentamount' => 0] - ); +// PiggyBankRepetition::create(['piggy_bank_id' => $recurring->id, 'startdate' => $this->som, 'targetdate' => $this->eom, 'currentamount' => 0]); +// PiggyBankRepetition::create( +// ['piggy_bank_id' => $recurring->id, 'startdate' => $this->nsom, 'targetdate' => $this->neom, 'currentamount' => 0] +// ); Reminder::create( ['user_id' => $user->id, 'startdate' => $this->som, 'enddate' => $this->neom, 'active' => 1, 'notnow' => 0, 'remindersable_id' => $recurring->id, 'remindersable_type' => 'PiggyBank'] From dddb8cdbc0dd135e81fac569249d9de34b3af530 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 1 Mar 2015 08:25:12 +0100 Subject: [PATCH 10/87] This loops. --- app/Providers/EventServiceProvider.php | 35 +++++++++++++++----------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index cfd63570c2..3b3c957b5b 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -1,7 +1,6 @@ user->bills()->where('active', 1)->where('automatch', 1)->get(); - /** @var Bill $bill */ - foreach ($list as $bill) { - $repository->scan($bill, $journal); - } - } - ); +// TransactionJournal::saved( +// function (TransactionJournal $journal) { +// +// Log::debug('Triggered saved event for journal #' . $journal->id . ' (' . $journal->description . ')'); +// +// /** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */ +// $repository = App::make('FireflyIII\Repositories\Bill\BillRepositoryInterface'); +// $list = $journal->user->bills()->where('active', 1)->where('automatch', 1)->get(); +// +// Log::debug('Found ' . $list->count() . ' bills to check.'); +// +// /** @var Bill $bill */ +// foreach ($list as $bill) { +// Log::debug('Now calling bill #' . $bill->id . ' (' . $bill->name . ')'); +// $repository->scan($bill, $journal); +// } +// +// Log::debug('Done!'); +// } +// ); Account::deleted( From 19e34b460fc6a2233f9001863eadb3a8b8283d78 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 1 Mar 2015 08:34:59 +0100 Subject: [PATCH 11/87] Update event. --- app/Events/JournalSaved.php | 25 +++++++++ app/Handlers/Events/RescanJournal.php | 53 +++++++++++++++++++ .../Controllers/TransactionController.php | 6 +++ app/Providers/EventServiceProvider.php | 27 +--------- 4 files changed, 86 insertions(+), 25 deletions(-) create mode 100644 app/Events/JournalSaved.php create mode 100644 app/Handlers/Events/RescanJournal.php diff --git a/app/Events/JournalSaved.php b/app/Events/JournalSaved.php new file mode 100644 index 0000000000..e618861169 --- /dev/null +++ b/app/Events/JournalSaved.php @@ -0,0 +1,25 @@ +journal = $journal; + } + +} diff --git a/app/Handlers/Events/RescanJournal.php b/app/Handlers/Events/RescanJournal.php new file mode 100644 index 0000000000..9b74e3bb44 --- /dev/null +++ b/app/Handlers/Events/RescanJournal.php @@ -0,0 +1,53 @@ +journal; + + Log::debug('Triggered saved event for journal #' . $journal->id . ' (' . $journal->description . ')'); + + /** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */ + $repository = App::make('FireflyIII\Repositories\Bill\BillRepositoryInterface'); + $list = $journal->user->bills()->where('active', 1)->where('automatch', 1)->get(); + + Log::debug('Found ' . $list->count() . ' bills to check.'); + + /** @var Bill $bill */ + foreach ($list as $bill) { + Log::debug('Now calling bill #' . $bill->id . ' (' . $bill->name . ')'); + $repository->scan($bill, $journal); + } + + Log::debug('Done!'); + } + +} diff --git a/app/Http/Controllers/TransactionController.php b/app/Http/Controllers/TransactionController.php index 88a8e0f17f..26d24d611b 100644 --- a/app/Http/Controllers/TransactionController.php +++ b/app/Http/Controllers/TransactionController.php @@ -3,6 +3,7 @@ use Auth; use Carbon\Carbon; use ExpandedForm; +use FireflyIII\Events\JournalSaved; use FireflyIII\Http\Requests; use FireflyIII\Http\Requests\JournalFormRequest; use FireflyIII\Models\Transaction; @@ -264,6 +265,8 @@ class TransactionController extends Controller $journal = $repository->store($journalData); + event(new JournalSaved($journal)); + Session::flash('success', 'New transaction "' . $journal->description . '" stored!'); return Redirect::route('transactions.index', $request->input('what')); @@ -298,6 +301,9 @@ class TransactionController extends Controller ]; $repository->update($journal, $journalData); + + event(new JournalSaved($journal)); + Session::flash('success', 'Transaction "' . e($journalData['description']) . '" updated.'); return Redirect::route('transactions.index', $journalData['what']); diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 3b3c957b5b..b12e29e483 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -30,11 +30,8 @@ class EventServiceProvider extends ServiceProvider */ protected $listen = [ - 'event.name' => [ - 'EventListener', - ], - 'App\Events\JournalDeleted' => [ - 'App\Handlers\Events\JournalDeletedHandler@handle', + 'FireflyIII\Events\JournalSaved' => [ + 'FireflyIII\Handlers\Events\RescanJournal', ], ]; @@ -59,26 +56,6 @@ class EventServiceProvider extends ServiceProvider } ); -// TransactionJournal::saved( -// function (TransactionJournal $journal) { -// -// Log::debug('Triggered saved event for journal #' . $journal->id . ' (' . $journal->description . ')'); -// -// /** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */ -// $repository = App::make('FireflyIII\Repositories\Bill\BillRepositoryInterface'); -// $list = $journal->user->bills()->where('active', 1)->where('automatch', 1)->get(); -// -// Log::debug('Found ' . $list->count() . ' bills to check.'); -// -// /** @var Bill $bill */ -// foreach ($list as $bill) { -// Log::debug('Now calling bill #' . $bill->id . ' (' . $bill->name . ')'); -// $repository->scan($bill, $journal); -// } -// -// Log::debug('Done!'); -// } -// ); Account::deleted( From 675530458c57442b3bfb35142ac82bd2c062e6fe Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 1 Mar 2015 10:44:10 +0100 Subject: [PATCH 12/87] Account show didn't show anything. --- app/Http/Controllers/AccountController.php | 6 ++++++ app/Http/Controllers/TransactionController.php | 8 ++++++++ app/Repositories/Account/AccountRepository.php | 4 ++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index c3a79b49ca..eba8d2a3cd 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -74,6 +74,12 @@ class AccountController extends Controller return Redirect::route('accounts.index', $typeName); } + /** + * @param Account $account + * @param AccountRepositoryInterface $repository + * + * @return View + */ public function edit(Account $account, AccountRepositoryInterface $repository) { $what = Config::get('firefly.shortNamesByFullName')[$account->accountType->type]; diff --git a/app/Http/Controllers/TransactionController.php b/app/Http/Controllers/TransactionController.php index 26d24d611b..11ccb60bfd 100644 --- a/app/Http/Controllers/TransactionController.php +++ b/app/Http/Controllers/TransactionController.php @@ -268,6 +268,9 @@ class TransactionController extends Controller event(new JournalSaved($journal)); Session::flash('success', 'New transaction "' . $journal->description . '" stored!'); + if (intval(Input::get('create_another')) === 1) { + return Redirect::route('transactions.create', $request->input('what')); + } return Redirect::route('transactions.index', $request->input('what')); @@ -284,6 +287,7 @@ class TransactionController extends Controller public function update(TransactionJournal $journal, JournalFormRequest $request, JournalRepositoryInterface $repository) { + $journalData = [ 'what' => $request->get('what'), 'description' => $request->get('description'), @@ -306,6 +310,10 @@ class TransactionController extends Controller Session::flash('success', 'Transaction "' . e($journalData['description']) . '" updated.'); + if (intval(Input::get('return_to_edit')) === 1) { + return Redirect::route('transactions.edit', $journal->id); + } + return Redirect::route('transactions.index', $journalData['what']); } diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index aff7831674..e6607bd2f0 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -46,7 +46,7 @@ class AccountRepository implements AccountRepositoryInterface */ public function getJournals(Account $account, $page, $range = 'session') { - $offset = $page * 50; + $offset = ($page-1) * 50; $query = Auth::user() ->transactionJournals() ->withRelevantData() @@ -55,7 +55,7 @@ class AccountRepository implements AccountRepositoryInterface ->orderBy('date', 'DESC'); if ($range == 'session') { - $query->before(Session::get('end', Carbon::now()->startOfMonth())); + $query->before(Session::get('end', Carbon::now()->endOfMonth())); $query->after(Session::get('start', Carbon::now()->startOfMonth())); } $count = $query->count(); From 262d4f92d43ff5810f15a5fdd399575deb3eb79f Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 1 Mar 2015 10:55:20 +0100 Subject: [PATCH 13/87] Fixed a bug where consecutive payments from one source would not be summed up. --- app/Helpers/Report/ReportQuery.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/Helpers/Report/ReportQuery.php b/app/Helpers/Report/ReportQuery.php index fc26592564..3992719f89 100644 --- a/app/Helpers/Report/ReportQuery.php +++ b/app/Helpers/Report/ReportQuery.php @@ -230,7 +230,9 @@ class ReportQuery implements ReportQueryInterface 'transaction_journals.description', 'transaction_journals.encrypted', 'transaction_types.type', - 't_to.amount', 'transaction_journals.date', 't_from.account_id as account_id', + DB::Raw('SUM(`t_to`.`amount`) as `amount`'), + 'transaction_journals.date', + 't_from.account_id as account_id', 'ac_from.name as name'] ); } From bb36ad64a7764b7c76a3d62281ce9f7bb53ed10d Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 1 Mar 2015 13:39:16 +0100 Subject: [PATCH 14/87] Moved the form. --- resources/views/piggy-banks/remove.blade.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/resources/views/piggy-banks/remove.blade.php b/resources/views/piggy-banks/remove.blade.php index 3a06e99184..7de6bc0871 100644 --- a/resources/views/piggy-banks/remove.blade.php +++ b/resources/views/piggy-banks/remove.blade.php @@ -1,6 +1,7 @@ -
-{!! Form::token() !!} +
- + From e26d2376fc4c4417c186cf90baa04dec7e6748ed Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 1 Mar 2015 19:26:30 +0100 Subject: [PATCH 15/87] Fixed piggy bank delete routine. --- app/Http/Controllers/PiggyBankController.php | 6 +++--- resources/views/piggy-banks/delete.blade.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/Http/Controllers/PiggyBankController.php b/app/Http/Controllers/PiggyBankController.php index 9e2a7ef9f5..651a55be89 100644 --- a/app/Http/Controllers/PiggyBankController.php +++ b/app/Http/Controllers/PiggyBankController.php @@ -78,7 +78,7 @@ class PiggyBankController extends Controller { $subTitle = 'Delete "' . e($piggyBank->name) . '"'; - return view('piggy_banks.delete', compact('piggyBank', 'subTitle')); + return view('piggy-banks.delete', compact('piggyBank', 'subTitle')); } /** @@ -90,9 +90,9 @@ class PiggyBankController extends Controller { Session::flash('success', 'Piggy bank "' . e($piggyBank->name) . '" deleted.'); - $this->_repository->destroy($piggyBank); + $piggyBank->delete(); - return Redirect::route('piggy_banks.index'); + return Redirect::route('piggy-banks.index'); } /** diff --git a/resources/views/piggy-banks/delete.blade.php b/resources/views/piggy-banks/delete.blade.php index 27e5055dd5..47c761c9b0 100644 --- a/resources/views/piggy-banks/delete.blade.php +++ b/resources/views/piggy-banks/delete.blade.php @@ -1,7 +1,7 @@ @extends('layouts.default') @section('content') -{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $piggyBank) }} -{{Form::open(['class' => 'form-horizontal','id' => 'destroy','url' => route('piggy-banks.destroy',$piggyBank->id)])}} +{!! Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $piggyBank) !!} +{!! Form::open(['class' => 'form-horizontal','id' => 'destroy','url' => route('piggy-banks.destroy',$piggyBank->id)]) !!}
@@ -33,5 +33,5 @@
-{{Form::close()}} +{!! Form::close() !!} @stop From ae1245abec17d688178fa2c84f2e4ad602f5cd08 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 1 Mar 2015 19:31:00 +0100 Subject: [PATCH 16/87] Fixed update transactions. --- app/Repositories/Journal/JournalRepository.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/Repositories/Journal/JournalRepository.php b/app/Repositories/Journal/JournalRepository.php index 1f9930519c..8bf49ad731 100644 --- a/app/Repositories/Journal/JournalRepository.php +++ b/app/Repositories/Journal/JournalRepository.php @@ -267,13 +267,15 @@ class JournalRepository implements JournalRepositoryInterface // update the from and to transaction. /** @var Transaction $transaction */ foreach ($journal->transactions()->get() as $transaction) { - if ($transaction->account_id === $from->id) { + if (floatval($transaction->amount) < 0) { // this is the from transaction, negative amount: - $transaction->amount = $data['amount'] * -1; + $transaction->amount = $data['amount'] * -1; + $transaction->account_id = $from->id; $transaction->save(); } - if ($transaction->account_id === $to->id) { + if (floatval($transaction->amount) > 0) { $transaction->amount = $data['amount']; + $transaction->account_id = $to->id; $transaction->save(); } } From c6042a905374d453539cd171c92f787bcefad453 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 1 Mar 2015 19:47:42 +0100 Subject: [PATCH 17/87] Try to fix modal dialog for piggy banks. --- app/Http/routes.php | 4 ++-- public/js/piggy-banks.js | 4 ++-- resources/views/piggy-banks/add.blade.php | 9 ++++++--- resources/views/piggy-banks/index.blade.php | 7 +++++-- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/app/Http/routes.php b/app/Http/routes.php index 84ee9dd19c..f05ad4625e 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -255,8 +255,8 @@ Route::group( * Piggy Bank Controller */ Route::get('/piggy-banks', ['uses' => 'PiggyBankController@index', 'as' => 'piggy-banks.index']); - Route::get('/piggy-banks/add/{piggyBank}', ['uses' => 'PiggyBankController@add']); # add money - Route::get('/piggy-banks/remove/{piggyBank}', ['uses' => 'PiggyBankController@remove']); #remove money + Route::get('/piggy-banks/add/{piggyBank}', ['uses' => 'PiggyBankController@add','as' => 'piggy-banks.addMoney']); # add money + Route::get('/piggy-banks/remove/{piggyBank}', ['uses' => 'PiggyBankController@remove','as' => 'piggy-banks.removeMoney']); #remove money Route::get('/piggy-banks/create', ['uses' => 'PiggyBankController@create', 'as' => 'piggy-banks.create']); Route::get('/piggy-banks/edit/{piggyBank}', ['uses' => 'PiggyBankController@edit', 'as' => 'piggy-banks.edit']); Route::get('/piggy-banks/delete/{piggyBank}', ['uses' => 'PiggyBankController@delete', 'as' => 'piggy-banks.delete']); diff --git a/public/js/piggy-banks.js b/public/js/piggy-banks.js index 0b603306cd..c6cdac3c94 100644 --- a/public/js/piggy-banks.js +++ b/public/js/piggy-banks.js @@ -9,14 +9,14 @@ $(function () { function addMoney(e) { var pigID = parseInt($(e.target).data('id')); - $('#moneyManagementModal').empty().load('piggy-banks/add/' + pigID).modal('show'); + $('#moneyManagementModal').empty().load('piggy-banks/add/' + pigID, function() {$('#moneyManagementModal').modal('show');}); return false; } function removeMoney(e) { var pigID = parseInt($(e.target).data('id')); - $('#moneyManagementModal').empty().load('piggy-banks/remove/' + pigID).modal('show'); + $('#moneyManagementModal').empty().load('piggy-banks/remove/' + pigID, function() {$('#moneyManagementModal').modal('show');}); return false; } \ No newline at end of file diff --git a/resources/views/piggy-banks/add.blade.php b/resources/views/piggy-banks/add.blade.php index 94c46696b3..37ae0ff02e 100644 --- a/resources/views/piggy-banks/add.blade.php +++ b/resources/views/piggy-banks/add.blade.php @@ -1,17 +1,19 @@ -
-{!! Form::token() !!} +
- + diff --git a/resources/views/piggy-banks/index.blade.php b/resources/views/piggy-banks/index.blade.php index aaba316735..6457513596 100644 --- a/resources/views/piggy-banks/index.blade.php +++ b/resources/views/piggy-banks/index.blade.php @@ -36,9 +36,9 @@
@if($piggyBank->leftToSave > 0) - + @endif - +
@@ -124,6 +124,9 @@ @stop From b261b0b447137428e29b4d09060953f7f170fb7c Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 2 Mar 2015 11:27:46 +0100 Subject: [PATCH 18/87] Shared expense should of course be shared asset. --- app/Helpers/Report/ReportHelper.php | 4 ++-- app/Helpers/Report/ReportQuery.php | 24 ++++++++++++------------ config/firefly.php | 4 ++-- resources/views/list/accounts.blade.php | 4 ++++ 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/app/Helpers/Report/ReportHelper.php b/app/Helpers/Report/ReportHelper.php index 210b67c991..e8677d01d0 100644 --- a/app/Helpers/Report/ReportHelper.php +++ b/app/Helpers/Report/ReportHelper.php @@ -141,7 +141,7 @@ class ReportHelper implements ReportHelperInterface $sharedCollection = \Auth::user()->accounts() ->leftJoin('account_meta', 'account_meta.account_id', '=', 'accounts.id') ->where('account_meta.name', '=', 'accountRole') - ->where('account_meta.data', '=', json_encode('sharedExpense')) + ->where('account_meta.data', '=', json_encode('sharedAsset')) ->get(['accounts.id']); foreach ($sharedCollection as $account) { @@ -166,7 +166,7 @@ class ReportHelper implements ReportHelperInterface 'start' => \Steam::balance($account, $start), 'end' => \Steam::balance($account, $end), 'account' => $account, - 'shared' => $account->accountRole == 'sharedExpense' + 'shared' => $account->accountRole == 'sharedAsset' ]; } diff --git a/app/Helpers/Report/ReportQuery.php b/app/Helpers/Report/ReportQuery.php index 3992719f89..d0067b25bd 100644 --- a/app/Helpers/Report/ReportQuery.php +++ b/app/Helpers/Report/ReportQuery.php @@ -44,7 +44,7 @@ class ReportQuery implements ReportQueryInterface ->where('active', 1) ->where( function (Builder $query) { - $query->where('account_meta.data', '!=', '"sharedExpense"'); + $query->where('account_meta.data', '!=', '"sharedAsset"'); $query->orWhereNull('account_meta.data'); } ) @@ -119,7 +119,7 @@ class ReportQuery implements ReportQueryInterface ) ->where( function (Builder $query) { - $query->where('account_meta.data', '!=', '"sharedExpense"'); + $query->where('account_meta.data', '!=', '"sharedAsset"'); $query->orWhereNull('account_meta.data'); } ) @@ -211,13 +211,13 @@ class ReportQuery implements ReportQueryInterface $query->where( function ($q) { $q->where('transaction_types.type', 'Deposit'); - $q->where('acm_to.data', '!=', '"sharedExpense"'); + $q->where('acm_to.data', '!=', '"sharedAsset"'); } ); $query->orWhere( function ($q) { $q->where('transaction_types.type', 'Transfer'); - $q->where('acm_from.data', '=', '"sharedExpense"'); + $q->where('acm_from.data', '=', '"sharedAsset"'); } ); } @@ -264,7 +264,7 @@ class ReportQuery implements ReportQueryInterface ->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id') ->where('transaction_journals.date', '>=', $start->format('Y-m-d')) ->where('transaction_journals.date', '<=', $end->format('Y-m-d')) - ->where('account_meta.data', '!=', '"sharedExpense"') + ->where('account_meta.data', '!=', '"sharedAsset"') ->where('transaction_types.type', 'Withdrawal') ->groupBy('budgets.id') ->orderBy('budgets.name', 'ASC') @@ -301,7 +301,7 @@ class ReportQuery implements ReportQueryInterface ->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id') ->where('transaction_journals.date', '>=', $start->format('Y-m-d')) ->where('transaction_journals.date', '<=', $end->format('Y-m-d')) - ->where('account_meta.data', '!=', '"sharedExpense"') + ->where('account_meta.data', '!=', '"sharedAsset"') ->where('transaction_types.type', 'Withdrawal') ->groupBy('categories.id') ->orderBy('amount') @@ -351,13 +351,13 @@ class ReportQuery implements ReportQueryInterface $query->where( function ($q) { $q->where('transaction_types.type', 'Withdrawal'); - $q->where('acm_from.data', '!=', '"sharedExpense"'); + $q->where('acm_from.data', '!=', '"sharedAsset"'); } ); $query->orWhere( function ($q) { $q->where('transaction_types.type', 'Transfer'); - $q->where('acm_to.data', '=', '"sharedExpense"'); + $q->where('acm_to.data', '=', '"sharedAsset"'); } ); } @@ -409,13 +409,13 @@ class ReportQuery implements ReportQueryInterface $query->where( function ($q) { $q->where('transaction_types.type', 'Deposit'); - $q->where('acm_to.data', '!=', '"sharedExpense"'); + $q->where('acm_to.data', '!=', '"sharedAsset"'); } ); $query->orWhere( function ($q) { $q->where('transaction_types.type', 'Transfer'); - $q->where('acm_from.data', '=', '"sharedExpense"'); + $q->where('acm_from.data', '=', '"sharedAsset"'); } ); } @@ -452,7 +452,7 @@ class ReportQuery implements ReportQueryInterface $join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole'); } ) - ->where('account_meta.data', '"sharedExpense"') + ->where('account_meta.data', '"sharedAsset"') ->after($start) ->before($end) ->where('transaction_types.type', 'Transfer') @@ -494,7 +494,7 @@ class ReportQuery implements ReportQueryInterface 'category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id' ) ->leftJoin('categories', 'category_transaction_journal.category_id', '=', 'categories.id') - ->where('account_meta.data', '"sharedExpense"') + ->where('account_meta.data', '"sharedAsset"') ->after($start) ->before($end) ->where('transaction_types.type', 'Transfer') diff --git a/config/firefly.php b/config/firefly.php index 004b9803bf..a52e464077 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -18,8 +18,8 @@ return [ ], 'accountRoles' => [ - 'defaultExpense' => 'Default expense account', - 'sharedExpense' => 'Shared expense account' + 'defaultAsset' => 'Default asset account', + 'sharedAsset' => 'Shared asset account' ], 'range_to_text' => [ diff --git a/resources/views/list/accounts.blade.php b/resources/views/list/accounts.blade.php index d367bc5b18..d1258ec14b 100644 --- a/resources/views/list/accounts.blade.php +++ b/resources/views/list/accounts.blade.php @@ -2,7 +2,9 @@   Name + @if(isset($what) && $what == 'asset') Role + @endif Current balance Active Last activity @@ -16,7 +18,9 @@
{{{$account->name}}} + @if(isset($what) && $what == 'asset') {{{$account->accountRole}}} + @endif {!! Amount::format(Steam::balance($account)) !!} @if($account->active) From d98d366eea372724d12d406a1f65e2e33c8c3cab Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 2 Mar 2015 11:42:27 +0100 Subject: [PATCH 19/87] Some small bug fixes in the account views. --- app/Http/Controllers/AccountController.php | 9 ++- .../Account/AccountRepository.php | 60 ++++++++++++++----- resources/views/list/accounts.blade.php | 8 ++- 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index eba8d2a3cd..f128d61bdd 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -116,7 +116,14 @@ class AccountController extends Controller $subTitle = Config::get('firefly.subTitlesByIdentifier.' . $what); $subTitleIcon = Config::get('firefly.subIconsByIdentifier.' . $what); $types = Config::get('firefly.accountTypesByIdentifier.' . $what); - $accounts = Auth::user()->accounts()->accountTypeIn($types)->get(['accounts.*']); + + // move to repository: + $accounts = Auth::user()->accounts()->with( + ['accountmeta' => function ($query) { + $query->where('name', 'accountRole'); + }] + )->accountTypeIn($types)->get(['accounts.*']); + return view('accounts.index', compact('what', 'subTitleIcon', 'subTitle', 'accounts')); } diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index e6607bd2f0..2faee4c964 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -46,7 +46,7 @@ class AccountRepository implements AccountRepositoryInterface */ public function getJournals(Account $account, $page, $range = 'session') { - $offset = ($page-1) * 50; + $offset = ($page - 1) * 50; $query = Auth::user() ->transactionJournals() ->withRelevantData() @@ -69,6 +69,23 @@ class AccountRepository implements AccountRepositoryInterface } + /** + * @param Account $account + * + * @return float + */ + public function leftOnAccount(Account $account) + { + $balance = \Steam::balance($account); + /** @var PiggyBank $p */ + foreach ($account->piggybanks()->get() as $p) { + $balance -= $p->currentRelevantRep()->currentamount; + } + + return $balance; + + } + /** * @param Account $account * @@ -123,13 +140,7 @@ class AccountRepository implements AccountRepositoryInterface $account->save(); // update meta data: - /** @var AccountMeta $meta */ - foreach ($account->accountMeta()->get() as $meta) { - if ($meta->name == 'accountRole') { - $meta->data = $data['accountRole']; - $meta->save(); - } - } + $this->_updateMetadata($account, $data); $openingBalance = $this->openingBalanceTransaction($account); @@ -313,18 +324,35 @@ class AccountRepository implements AccountRepositoryInterface /** * @param Account $account - * - * @return float + * @param array $data */ - public function leftOnAccount(Account $account) + protected function _updateMetadata(Account $account, array $data) { - $balance = \Steam::balance($account); - /** @var PiggyBank $p */ - foreach ($account->piggybanks()->get() as $p) { - $balance -= $p->currentRelevantRep()->currentamount; + $metaEntries = $account->accountMeta()->get(); + $updated = false; + + /** @var AccountMeta $entry */ + foreach ($metaEntries as $entry) { + if ($entry->name == 'accountRole') { + $entry->data = $data['accountRole']; + $updated = true; + $entry->save(); + } } - return $balance; + if ($updated === false) { + $metaData = new AccountMeta( + [ + 'account_id' => $account->id, + 'name' => 'accountRole', + 'data' => $data['accountRole'] + ] + ); + if (!$metaData->isValid()) { + App::abort(500); + } + $metaData->save(); + } } } \ No newline at end of file diff --git a/resources/views/list/accounts.blade.php b/resources/views/list/accounts.blade.php index d1258ec14b..01013341a5 100644 --- a/resources/views/list/accounts.blade.php +++ b/resources/views/list/accounts.blade.php @@ -19,7 +19,13 @@ {{{$account->name}}} @if(isset($what) && $what == 'asset') - {{{$account->accountRole}}} + + @foreach($account->accountmeta as $entry) + @if($entry->name == 'accountRole') + {{Config::get('firefly.accountRoles.'.$entry->data)}} + @endif + @endforeach + @endif {!! Amount::format(Steam::balance($account)) !!} From fd57086ffd87902561b3996135d9b0bd56618d8f Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 2 Mar 2015 11:54:20 +0100 Subject: [PATCH 20/87] Better mostly report lists. --- app/Helpers/Report/ReportHelper.php | 3 ++- resources/views/reports/index.blade.php | 23 ++++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/app/Helpers/Report/ReportHelper.php b/app/Helpers/Report/ReportHelper.php index e8677d01d0..9c4a4c4ad7 100644 --- a/app/Helpers/Report/ReportHelper.php +++ b/app/Helpers/Report/ReportHelper.php @@ -99,7 +99,8 @@ class ReportHelper implements ReportHelperInterface $end = Carbon::now(); $months = []; while ($start <= $end) { - $months[] = [ + $year = $start->format('Y'); + $months[$year][] = [ 'formatted' => $start->format('F Y'), 'month' => intval($start->format('m')), 'year' => intval($start->format('Y')), diff --git a/resources/views/reports/index.blade.php b/resources/views/reports/index.blade.php index 13cc5236e3..4705417029 100644 --- a/resources/views/reports/index.blade.php +++ b/resources/views/reports/index.blade.php @@ -23,11 +23,16 @@ Monthly reports
- +
@@ -38,9 +43,13 @@ Budget reports
-
From 6dba916d02fb1880d6ea5a6bb50f160129b056a7 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 2 Mar 2015 12:04:40 +0100 Subject: [PATCH 21/87] New code & css for date range. --- public/css/daterangepicker-bs3.css | 319 +++++++ public/js/daterangepicker.js | 1280 ++++++++++++++++++++++++++++ public/js/moment.min.js | 7 + 3 files changed, 1606 insertions(+) create mode 100755 public/css/daterangepicker-bs3.css create mode 100755 public/js/daterangepicker.js create mode 100644 public/js/moment.min.js diff --git a/public/css/daterangepicker-bs3.css b/public/css/daterangepicker-bs3.css new file mode 100755 index 0000000000..c9c8fedf47 --- /dev/null +++ b/public/css/daterangepicker-bs3.css @@ -0,0 +1,319 @@ +/*! + * Stylesheet for the Date Range Picker, for use with Bootstrap 3.x + * + * Copyright 2013-2015 Dan Grossman ( http://www.dangrossman.info ) + * Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php + * + * Built for http://www.improvely.com + */ + + .daterangepicker.dropdown-menu { + max-width: none; + z-index: 3000; +} + +.daterangepicker.opensleft .ranges, .daterangepicker.opensleft .calendar { + float: left; + margin: 4px; +} + +.daterangepicker.opensright .ranges, .daterangepicker.opensright .calendar, +.daterangepicker.openscenter .ranges, .daterangepicker.openscenter .calendar { + float: right; + margin: 4px; +} + +.daterangepicker.single .ranges, .daterangepicker.single .calendar { + float: none; +} + +.daterangepicker .ranges { + width: 160px; + text-align: left; +} + +.daterangepicker .ranges .range_inputs>div { + float: left; +} + +.daterangepicker .ranges .range_inputs>div:nth-child(2) { + padding-left: 11px; +} + +.daterangepicker .calendar { + display: none; + max-width: 270px; +} + +.daterangepicker.show-calendar .calendar { + display: block; +} + +.daterangepicker .calendar.single .calendar-date { + border: none; +} + +.daterangepicker .calendar th, .daterangepicker .calendar td { + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + white-space: nowrap; + text-align: center; + min-width: 32px; +} + +.daterangepicker .daterangepicker_start_input label, +.daterangepicker .daterangepicker_end_input label { + color: #333; + display: block; + font-size: 11px; + font-weight: normal; + height: 20px; + line-height: 20px; + margin-bottom: 2px; + text-shadow: #fff 1px 1px 0px; + text-transform: uppercase; + width: 74px; +} + +.daterangepicker .ranges input { + font-size: 11px; +} + +.daterangepicker .ranges .input-mini { + border: 1px solid #ccc; + border-radius: 4px; + color: #555; + display: block; + font-size: 11px; + height: 30px; + line-height: 30px; + vertical-align: middle; + margin: 0 0 10px 0; + padding: 0 6px; + width: 74px; +} + +.daterangepicker .ranges ul { + list-style: none; + margin: 0; + padding: 0; +} + +.daterangepicker .ranges li { + font-size: 13px; + background: #f5f5f5; + border: 1px solid #f5f5f5; + color: #08c; + padding: 3px 12px; + margin-bottom: 8px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + cursor: pointer; +} + +.daterangepicker .ranges li.active, .daterangepicker .ranges li:hover { + background: #08c; + border: 1px solid #08c; + color: #fff; +} + +.daterangepicker .calendar-date { + border: 1px solid #ddd; + padding: 4px; + border-radius: 4px; + background: #fff; +} + +.daterangepicker .calendar-time { + text-align: center; + margin: 8px auto 0 auto; + line-height: 30px; +} + +.daterangepicker { + position: absolute; + background: #fff; + top: 100px; + left: 20px; + padding: 4px; + margin-top: 1px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.daterangepicker.opensleft:before { + position: absolute; + top: -7px; + right: 9px; + display: inline-block; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; +} + +.daterangepicker.opensleft:after { + position: absolute; + top: -6px; + right: 10px; + display: inline-block; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + border-left: 6px solid transparent; + content: ''; +} + +.daterangepicker.openscenter:before { + position: absolute; + top: -7px; + left: 0; + right: 0; + width: 0; + margin-left: auto; + margin-right: auto; + display: inline-block; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; +} + +.daterangepicker.openscenter:after { + position: absolute; + top: -6px; + left: 0; + right: 0; + width: 0; + margin-left: auto; + margin-right: auto; + display: inline-block; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + border-left: 6px solid transparent; + content: ''; +} + +.daterangepicker.opensright:before { + position: absolute; + top: -7px; + left: 9px; + display: inline-block; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; +} + +.daterangepicker.opensright:after { + position: absolute; + top: -6px; + left: 10px; + display: inline-block; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + border-left: 6px solid transparent; + content: ''; +} + +.daterangepicker table { + width: 100%; + margin: 0; +} + +.daterangepicker td, .daterangepicker th { + text-align: center; + width: 20px; + height: 20px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + cursor: pointer; + white-space: nowrap; +} + +.daterangepicker td.off { + color: #999; +} + +.daterangepicker td.disabled, .daterangepicker option.disabled { + color: #999; +} + +.daterangepicker td.available:hover, .daterangepicker th.available:hover { + background: #eee; +} + +.daterangepicker td.in-range { + background: #ebf4f8; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.daterangepicker td.start-date { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.daterangepicker td.end-date { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.daterangepicker td.start-date.end-date { + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.daterangepicker td.active, .daterangepicker td.active:hover { + background-color: #357ebd; + border-color: #3071a9; + color: #fff; +} + +.daterangepicker td.week, .daterangepicker th.week { + font-size: 80%; + color: #ccc; +} + +.daterangepicker select.monthselect, .daterangepicker select.yearselect { + font-size: 12px; + padding: 1px; + height: auto; + margin: 0; + cursor: default; +} + +.daterangepicker select.monthselect { + margin-right: 2%; + width: 56%; +} + +.daterangepicker select.yearselect { + width: 40%; +} + +.daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.secondselect, .daterangepicker select.ampmselect { + width: 50px; + margin-bottom: 0; +} + +.daterangepicker_start_input { + float: left; +} + +.daterangepicker_end_input { + float: left; + padding-left: 11px +} + +.daterangepicker th.month { + width: auto; +} diff --git a/public/js/daterangepicker.js b/public/js/daterangepicker.js new file mode 100755 index 0000000000..e54fd5c9f7 --- /dev/null +++ b/public/js/daterangepicker.js @@ -0,0 +1,1280 @@ +/** +* @version: 1.3.18 +* @author: Dan Grossman http://www.dangrossman.info/ +* @copyright: Copyright (c) 2012-2015 Dan Grossman. All rights reserved. +* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php +* @website: https://www.improvely.com/ +*/ + +(function(root, factory) { + + if (typeof define === 'function' && define.amd) { + define(['moment', 'jquery', 'exports'], function(momentjs, $, exports) { + root.daterangepicker = factory(root, exports, momentjs, $); + }); + + } else if (typeof exports !== 'undefined') { + var momentjs = require('moment'); + var jQuery; + try { + jQuery = require('jquery'); + } catch (err) { + jQuery = window.jQuery; + if (!jQuery) throw new Error('jQuery dependency not found'); + } + + factory(root, exports, momentjs, jQuery); + + // Finally, as a browser global. + } else { + root.daterangepicker = factory(root, {}, root.moment, (root.jQuery || root.Zepto || root.ender || root.$)); + } + +}(this, function(root, daterangepicker, moment, $) { + + var DateRangePicker = function (element, options, cb) { + + // by default, the daterangepicker element is placed at the bottom of HTML body + this.parentEl = 'body'; + + //element that triggered the date range picker + this.element = $(element); + + //tracks visible state + this.isShowing = false; + + //create the picker HTML object + var DRPTemplate = ''; + + //custom options + if (typeof options !== 'object' || options === null) + options = {}; + + this.parentEl = (typeof options === 'object' && options.parentEl && $(options.parentEl).length) ? $(options.parentEl) : $(this.parentEl); + this.container = $(DRPTemplate).appendTo(this.parentEl); + + this.setOptions(options, cb); + + //apply CSS classes and labels to buttons + var c = this.container; + $.each(this.buttonClasses, function (idx, val) { + c.find('button').addClass(val); + }); + this.container.find('.daterangepicker_start_input label').html(this.locale.fromLabel); + this.container.find('.daterangepicker_end_input label').html(this.locale.toLabel); + if (this.applyClass.length) + this.container.find('.applyBtn').addClass(this.applyClass); + if (this.cancelClass.length) + this.container.find('.cancelBtn').addClass(this.cancelClass); + this.container.find('.applyBtn').html(this.locale.applyLabel); + this.container.find('.cancelBtn').html(this.locale.cancelLabel); + + //event listeners + + this.container.find('.calendar') + .on('click.daterangepicker', '.prev', $.proxy(this.clickPrev, this)) + .on('click.daterangepicker', '.next', $.proxy(this.clickNext, this)) + .on('click.daterangepicker', 'td.available', $.proxy(this.clickDate, this)) + .on('mouseenter.daterangepicker', 'td.available', $.proxy(this.hoverDate, this)) + .on('mouseleave.daterangepicker', 'td.available', $.proxy(this.updateFormInputs, this)) + .on('change.daterangepicker', 'select.yearselect', $.proxy(this.updateMonthYear, this)) + .on('change.daterangepicker', 'select.monthselect', $.proxy(this.updateMonthYear, this)) + .on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.secondselect,select.ampmselect', $.proxy(this.updateTime, this)); + + this.container.find('.ranges') + .on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this)) + .on('click.daterangepicker', 'button.cancelBtn', $.proxy(this.clickCancel, this)) + .on('click.daterangepicker', '.daterangepicker_start_input,.daterangepicker_end_input', $.proxy(this.showCalendars, this)) + .on('change.daterangepicker', '.daterangepicker_start_input,.daterangepicker_end_input', $.proxy(this.inputsChanged, this)) + .on('keydown.daterangepicker', '.daterangepicker_start_input,.daterangepicker_end_input', $.proxy(this.inputsKeydown, this)) + .on('click.daterangepicker', 'li', $.proxy(this.clickRange, this)) + .on('mouseenter.daterangepicker', 'li', $.proxy(this.enterRange, this)) + .on('mouseleave.daterangepicker', 'li', $.proxy(this.updateFormInputs, this)); + + if (this.element.is('input')) { + this.element.on({ + 'click.daterangepicker': $.proxy(this.show, this), + 'focus.daterangepicker': $.proxy(this.show, this), + 'keyup.daterangepicker': $.proxy(this.updateFromControl, this) + }); + } else { + this.element.on('click.daterangepicker', $.proxy(this.toggle, this)); + } + + }; + + DateRangePicker.prototype = { + + constructor: DateRangePicker, + + setOptions: function(options, callback) { + + this.startDate = moment().startOf('day'); + this.endDate = moment().endOf('day'); + this.timeZone = moment().utcOffset(); + this.minDate = false; + this.maxDate = false; + this.dateLimit = false; + + this.showDropdowns = false; + this.showWeekNumbers = false; + this.timePicker = false; + this.timePickerSeconds = false; + this.timePickerIncrement = 30; + this.timePicker12Hour = true; + this.singleDatePicker = false; + this.ranges = {}; + + this.opens = 'right'; + if (this.element.hasClass('pull-right')) + this.opens = 'left'; + + this.buttonClasses = ['btn', 'btn-small btn-sm']; + this.applyClass = 'btn-success'; + this.cancelClass = 'btn-default'; + + this.format = 'MM/DD/YYYY'; + this.separator = ' - '; + + this.locale = { + applyLabel: 'Apply', + cancelLabel: 'Cancel', + fromLabel: 'From', + toLabel: 'To', + weekLabel: 'W', + customRangeLabel: 'Custom Range', + daysOfWeek: moment.weekdaysMin(), + monthNames: moment.monthsShort(), + firstDay: moment.localeData()._week.dow + }; + + this.cb = function () { }; + + if (typeof options.format === 'string') + this.format = options.format; + + if (typeof options.separator === 'string') + this.separator = options.separator; + + if (typeof options.startDate === 'string') + this.startDate = moment(options.startDate, this.format); + + if (typeof options.endDate === 'string') + this.endDate = moment(options.endDate, this.format); + + if (typeof options.minDate === 'string') + this.minDate = moment(options.minDate, this.format); + + if (typeof options.maxDate === 'string') + this.maxDate = moment(options.maxDate, this.format); + + if (typeof options.startDate === 'object') + this.startDate = moment(options.startDate); + + if (typeof options.endDate === 'object') + this.endDate = moment(options.endDate); + + if (typeof options.minDate === 'object') + this.minDate = moment(options.minDate); + + if (typeof options.maxDate === 'object') + this.maxDate = moment(options.maxDate); + + if (typeof options.applyClass === 'string') + this.applyClass = options.applyClass; + + if (typeof options.cancelClass === 'string') + this.cancelClass = options.cancelClass; + + if (typeof options.dateLimit === 'object') + this.dateLimit = options.dateLimit; + + if (typeof options.locale === 'object') { + + if (typeof options.locale.daysOfWeek === 'object') { + // Create a copy of daysOfWeek to avoid modification of original + // options object for reusability in multiple daterangepicker instances + this.locale.daysOfWeek = options.locale.daysOfWeek.slice(); + } + + if (typeof options.locale.monthNames === 'object') { + this.locale.monthNames = options.locale.monthNames.slice(); + } + + if (typeof options.locale.firstDay === 'number') { + this.locale.firstDay = options.locale.firstDay; + } + + if (typeof options.locale.applyLabel === 'string') { + this.locale.applyLabel = options.locale.applyLabel; + } + + if (typeof options.locale.cancelLabel === 'string') { + this.locale.cancelLabel = options.locale.cancelLabel; + } + + if (typeof options.locale.fromLabel === 'string') { + this.locale.fromLabel = options.locale.fromLabel; + } + + if (typeof options.locale.toLabel === 'string') { + this.locale.toLabel = options.locale.toLabel; + } + + if (typeof options.locale.weekLabel === 'string') { + this.locale.weekLabel = options.locale.weekLabel; + } + + if (typeof options.locale.customRangeLabel === 'string') { + this.locale.customRangeLabel = options.locale.customRangeLabel; + } + } + + if (typeof options.opens === 'string') + this.opens = options.opens; + + if (typeof options.showWeekNumbers === 'boolean') { + this.showWeekNumbers = options.showWeekNumbers; + } + + if (typeof options.buttonClasses === 'string') { + this.buttonClasses = [options.buttonClasses]; + } + + if (typeof options.buttonClasses === 'object') { + this.buttonClasses = options.buttonClasses; + } + + if (typeof options.showDropdowns === 'boolean') { + this.showDropdowns = options.showDropdowns; + } + + if (typeof options.singleDatePicker === 'boolean') { + this.singleDatePicker = options.singleDatePicker; + if (this.singleDatePicker) { + this.endDate = this.startDate.clone(); + } + } + + if (typeof options.timePicker === 'boolean') { + this.timePicker = options.timePicker; + } + + if (typeof options.timePickerSeconds === 'boolean') { + this.timePickerSeconds = options.timePickerSeconds; + } + + if (typeof options.timePickerIncrement === 'number') { + this.timePickerIncrement = options.timePickerIncrement; + } + + if (typeof options.timePicker12Hour === 'boolean') { + this.timePicker12Hour = options.timePicker12Hour; + } + + // update day names order to firstDay + if (this.locale.firstDay != 0) { + var iterator = this.locale.firstDay; + while (iterator > 0) { + this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift()); + iterator--; + } + } + + var start, end, range; + + //if no start/end dates set, check if an input element contains initial values + if (typeof options.startDate === 'undefined' && typeof options.endDate === 'undefined') { + if ($(this.element).is('input[type=text]')) { + var val = $(this.element).val(), + split = val.split(this.separator); + + start = end = null; + + if (split.length == 2) { + start = moment(split[0], this.format); + end = moment(split[1], this.format); + } else if (this.singleDatePicker && val !== "") { + start = moment(val, this.format); + end = moment(val, this.format); + } + if (start !== null && end !== null) { + this.startDate = start; + this.endDate = end; + } + } + } + + // bind the time zone used to build the calendar to either the timeZone passed in through the options or the zone of the startDate (which will be the local time zone by default) + if (typeof options.timeZone === 'string' || typeof options.timeZone === 'number') { + this.timeZone = options.timeZone; + this.startDate.utcOffset(this.timeZone); + this.endDate.utcOffset(this.timeZone); + } else { + this.timeZone = moment(this.startDate).utcOffset(); + } + + if (typeof options.ranges === 'object') { + for (range in options.ranges) { + + if (typeof options.ranges[range][0] === 'string') + start = moment(options.ranges[range][0], this.format); + else + start = moment(options.ranges[range][0]); + + if (typeof options.ranges[range][1] === 'string') + end = moment(options.ranges[range][1], this.format); + else + end = moment(options.ranges[range][1]); + + // If we have a min/max date set, bound this range + // to it, but only if it would otherwise fall + // outside of the min/max. + if (this.minDate && start.isBefore(this.minDate)) + start = moment(this.minDate); + + if (this.maxDate && end.isAfter(this.maxDate)) + end = moment(this.maxDate); + + // If the end of the range is before the minimum (if min is set) OR + // the start of the range is after the max (also if set) don't display this + // range option. + if ((this.minDate && end.isBefore(this.minDate)) || (this.maxDate && start.isAfter(this.maxDate))) { + continue; + } + + this.ranges[range] = [start, end]; + } + + var list = '
    '; + for (range in this.ranges) { + list += '
  • ' + range + '
  • '; + } + list += '
  • ' + this.locale.customRangeLabel + '
  • '; + list += '
'; + this.container.find('.ranges ul').remove(); + this.container.find('.ranges').prepend(list); + } + + if (typeof callback === 'function') { + this.cb = callback; + } + + if (!this.timePicker) { + this.startDate = this.startDate.startOf('day'); + this.endDate = this.endDate.endOf('day'); + } + + if (this.singleDatePicker) { + this.opens = 'right'; + this.container.addClass('single'); + this.container.find('.calendar.right').show(); + this.container.find('.calendar.left').hide(); + if (!this.timePicker) { + this.container.find('.ranges').hide(); + } else { + this.container.find('.ranges .daterangepicker_start_input, .ranges .daterangepicker_end_input').hide(); + } + if (!this.container.find('.calendar.right').hasClass('single')) + this.container.find('.calendar.right').addClass('single'); + } else { + this.container.removeClass('single'); + this.container.find('.calendar.right').removeClass('single'); + this.container.find('.ranges').show(); + } + + this.oldStartDate = this.startDate.clone(); + this.oldEndDate = this.endDate.clone(); + this.oldChosenLabel = this.chosenLabel; + + this.leftCalendar = { + month: moment([this.startDate.year(), this.startDate.month(), 1, this.startDate.hour(), this.startDate.minute(), this.startDate.second()]), + calendar: [] + }; + + this.rightCalendar = { + month: moment([this.endDate.year(), this.endDate.month(), 1, this.endDate.hour(), this.endDate.minute(), this.endDate.second()]), + calendar: [] + }; + + if (this.opens == 'right' || this.opens == 'center') { + //swap calendar positions + var first = this.container.find('.calendar.first'); + var second = this.container.find('.calendar.second'); + + if (second.hasClass('single')) { + second.removeClass('single'); + first.addClass('single'); + } + + first.removeClass('left').addClass('right'); + second.removeClass('right').addClass('left'); + + if (this.singleDatePicker) { + first.show(); + second.hide(); + } + } + + if (typeof options.ranges === 'undefined' && !this.singleDatePicker) { + this.container.addClass('show-calendar'); + } + + this.container.addClass('opens' + this.opens); + + this.updateView(); + this.updateCalendars(); + + }, + + setStartDate: function(startDate) { + if (typeof startDate === 'string') + this.startDate = moment(startDate, this.format).utcOffset(this.timeZone); + + if (typeof startDate === 'object') + this.startDate = moment(startDate); + + if (!this.timePicker) + this.startDate = this.startDate.startOf('day'); + + this.oldStartDate = this.startDate.clone(); + + this.updateView(); + this.updateCalendars(); + this.updateInputText(); + }, + + setEndDate: function(endDate) { + if (typeof endDate === 'string') + this.endDate = moment(endDate, this.format).utcOffset(this.timeZone); + + if (typeof endDate === 'object') + this.endDate = moment(endDate); + + if (!this.timePicker) + this.endDate = this.endDate.endOf('day'); + + this.oldEndDate = this.endDate.clone(); + + this.updateView(); + this.updateCalendars(); + this.updateInputText(); + }, + + updateView: function () { + this.leftCalendar.month.month(this.startDate.month()).year(this.startDate.year()).hour(this.startDate.hour()).minute(this.startDate.minute()); + this.rightCalendar.month.month(this.endDate.month()).year(this.endDate.year()).hour(this.endDate.hour()).minute(this.endDate.minute()); + this.updateFormInputs(); + }, + + updateFormInputs: function () { + this.container.find('input[name=daterangepicker_start]').val(this.startDate.format(this.format)); + this.container.find('input[name=daterangepicker_end]').val(this.endDate.format(this.format)); + + if (this.startDate.isSame(this.endDate) || this.startDate.isBefore(this.endDate)) { + this.container.find('button.applyBtn').removeAttr('disabled'); + } else { + this.container.find('button.applyBtn').attr('disabled', 'disabled'); + } + }, + + updateFromControl: function () { + if (!this.element.is('input')) return; + if (!this.element.val().length) return; + + var dateString = this.element.val().split(this.separator), + start = null, + end = null; + + if(dateString.length === 2) { + start = moment(dateString[0], this.format).utcOffset(this.timeZone); + end = moment(dateString[1], this.format).utcOffset(this.timeZone); + } + + if (this.singleDatePicker || start === null || end === null) { + start = moment(this.element.val(), this.format).utcOffset(this.timeZone); + end = start; + } + + if (end.isBefore(start)) return; + + this.oldStartDate = this.startDate.clone(); + this.oldEndDate = this.endDate.clone(); + + this.startDate = start; + this.endDate = end; + + if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate)) + this.notify(); + + this.updateCalendars(); + }, + + notify: function () { + this.updateView(); + this.cb(this.startDate, this.endDate, this.chosenLabel); + }, + + move: function () { + var parentOffset = { top: 0, left: 0 }; + var parentRightEdge = $(window).width(); + if (!this.parentEl.is('body')) { + parentOffset = { + top: this.parentEl.offset().top - this.parentEl.scrollTop(), + left: this.parentEl.offset().left - this.parentEl.scrollLeft() + }; + parentRightEdge = this.parentEl[0].clientWidth + this.parentEl.offset().left; + } + + if (this.opens == 'left') { + this.container.css({ + top: this.element.offset().top + this.element.outerHeight() - parentOffset.top, + right: parentRightEdge - this.element.offset().left - this.element.outerWidth(), + left: 'auto' + }); + if (this.container.offset().left < 0) { + this.container.css({ + right: 'auto', + left: 9 + }); + } + } else if (this.opens == 'center') { + this.container.css({ + top: this.element.offset().top + this.element.outerHeight() - parentOffset.top, + left: this.element.offset().left - parentOffset.left + this.element.outerWidth() / 2 + - this.container.outerWidth() / 2, + right: 'auto' + }); + if (this.container.offset().left < 0) { + this.container.css({ + right: 'auto', + left: 9 + }); + } + } else { + this.container.css({ + top: this.element.offset().top + this.element.outerHeight() - parentOffset.top, + left: this.element.offset().left - parentOffset.left, + right: 'auto' + }); + if (this.container.offset().left + this.container.outerWidth() > $(window).width()) { + this.container.css({ + left: 'auto', + right: 0 + }); + } + } + }, + + toggle: function (e) { + if (this.element.hasClass('active')) { + this.hide(); + } else { + this.show(); + } + }, + + show: function (e) { + if (this.isShowing) return; + + this.element.addClass('active'); + this.container.show(); + this.move(); + + // Create a click proxy that is private to this instance of datepicker, for unbinding + this._outsideClickProxy = $.proxy(function (e) { this.outsideClick(e); }, this); + // Bind global datepicker mousedown for hiding and + $(document) + .on('mousedown.daterangepicker', this._outsideClickProxy) + // also support mobile devices + .on('touchend.daterangepicker', this._outsideClickProxy) + // also explicitly play nice with Bootstrap dropdowns, which stopPropagation when clicking them + .on('click.daterangepicker', '[data-toggle=dropdown]', this._outsideClickProxy) + // and also close when focus changes to outside the picker (eg. tabbing between controls) + .on('focusin.daterangepicker', this._outsideClickProxy); + + this.isShowing = true; + this.element.trigger('show.daterangepicker', this); + }, + + outsideClick: function (e) { + var target = $(e.target); + // if the page is clicked anywhere except within the daterangerpicker/button + // itself then call this.hide() + if ( + // ie modal dialog fix + e.type == "focusin" || + target.closest(this.element).length || + target.closest(this.container).length || + target.closest('.calendar-date').length + ) return; + this.hide(); + }, + + hide: function (e) { + if (!this.isShowing) return; + + $(document) + .off('.daterangepicker'); + + this.element.removeClass('active'); + this.container.hide(); + + if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate)) + this.notify(); + + this.oldStartDate = this.startDate.clone(); + this.oldEndDate = this.endDate.clone(); + + this.isShowing = false; + this.element.trigger('hide.daterangepicker', this); + }, + + enterRange: function (e) { + // mouse pointer has entered a range label + var label = e.target.innerHTML; + if (label == this.locale.customRangeLabel) { + this.updateView(); + } else { + var dates = this.ranges[label]; + this.container.find('input[name=daterangepicker_start]').val(dates[0].format(this.format)); + this.container.find('input[name=daterangepicker_end]').val(dates[1].format(this.format)); + } + }, + + showCalendars: function() { + this.container.addClass('show-calendar'); + this.move(); + this.element.trigger('showCalendar.daterangepicker', this); + }, + + hideCalendars: function() { + this.container.removeClass('show-calendar'); + this.element.trigger('hideCalendar.daterangepicker', this); + }, + + // when a date is typed into the start to end date textboxes + inputsChanged: function (e) { + var el = $(e.target); + var date = moment(el.val(), this.format); + if (!date.isValid()) return; + + var startDate, endDate; + if (el.attr('name') === 'daterangepicker_start') { + startDate = (false !== this.minDate && date.isBefore(this.minDate)) ? this.minDate : date; + endDate = this.endDate; + } else { + startDate = this.startDate; + endDate = (false !== this.maxDate && date.isAfter(this.maxDate)) ? this.maxDate : date; + } + this.setCustomDates(startDate, endDate); + }, + + inputsKeydown: function(e) { + if (e.keyCode === 13) { + this.inputsChanged(e); + this.notify(); + } + }, + + updateInputText: function() { + if (this.element.is('input') && !this.singleDatePicker) { + this.element.val(this.startDate.format(this.format) + this.separator + this.endDate.format(this.format)); + this.element.trigger('change'); + } else if (this.element.is('input')) { + this.element.val(this.endDate.format(this.format)); + this.element.trigger('change'); + } + }, + + clickRange: function (e) { + var label = e.target.innerHTML; + this.chosenLabel = label; + if (label == this.locale.customRangeLabel) { + this.showCalendars(); + } else { + var dates = this.ranges[label]; + + this.startDate = dates[0]; + this.endDate = dates[1]; + + if (!this.timePicker) { + this.startDate.startOf('day'); + this.endDate.endOf('day'); + } + + this.leftCalendar.month.month(this.startDate.month()).year(this.startDate.year()).hour(this.startDate.hour()).minute(this.startDate.minute()); + this.rightCalendar.month.month(this.endDate.month()).year(this.endDate.year()).hour(this.endDate.hour()).minute(this.endDate.minute()); + this.updateCalendars(); + + this.updateInputText(); + + this.hideCalendars(); + this.hide(); + this.element.trigger('apply.daterangepicker', this); + } + }, + + clickPrev: function (e) { + var cal = $(e.target).parents('.calendar'); + if (cal.hasClass('left')) { + this.leftCalendar.month.subtract(1, 'month'); + } else { + this.rightCalendar.month.subtract(1, 'month'); + } + this.updateCalendars(); + }, + + clickNext: function (e) { + var cal = $(e.target).parents('.calendar'); + if (cal.hasClass('left')) { + this.leftCalendar.month.add(1, 'month'); + } else { + this.rightCalendar.month.add(1, 'month'); + } + this.updateCalendars(); + }, + + hoverDate: function (e) { + var title = $(e.target).attr('data-title'); + var row = title.substr(1, 1); + var col = title.substr(3, 1); + var cal = $(e.target).parents('.calendar'); + + if (cal.hasClass('left')) { + this.container.find('input[name=daterangepicker_start]').val(this.leftCalendar.calendar[row][col].format(this.format)); + } else { + this.container.find('input[name=daterangepicker_end]').val(this.rightCalendar.calendar[row][col].format(this.format)); + } + }, + + setCustomDates: function(startDate, endDate) { + this.chosenLabel = this.locale.customRangeLabel; + if (startDate.isAfter(endDate)) { + var difference = this.endDate.diff(this.startDate); + endDate = moment(startDate).add(difference, 'ms'); + if (this.maxDate && endDate.isAfter(this.maxDate)) { + endDate = this.maxDate; + } + } + this.startDate = startDate; + this.endDate = endDate; + + this.updateView(); + this.updateCalendars(); + }, + + clickDate: function (e) { + var title = $(e.target).attr('data-title'); + var row = title.substr(1, 1); + var col = title.substr(3, 1); + var cal = $(e.target).parents('.calendar'); + + var startDate, endDate; + if (cal.hasClass('left')) { + startDate = this.leftCalendar.calendar[row][col]; + endDate = this.endDate; + if (typeof this.dateLimit === 'object') { + var maxDate = moment(startDate).add(this.dateLimit).startOf('day'); + if (endDate.isAfter(maxDate)) { + endDate = maxDate; + } + } + } else { + startDate = this.startDate; + endDate = this.rightCalendar.calendar[row][col]; + if (typeof this.dateLimit === 'object') { + var minDate = moment(endDate).subtract(this.dateLimit).startOf('day'); + if (startDate.isBefore(minDate)) { + startDate = minDate; + } + } + } + + if (this.singleDatePicker && cal.hasClass('left')) { + endDate = startDate.clone(); + } else if (this.singleDatePicker && cal.hasClass('right')) { + startDate = endDate.clone(); + } + + cal.find('td').removeClass('active'); + + $(e.target).addClass('active'); + + this.setCustomDates(startDate, endDate); + + if (!this.timePicker) + endDate.endOf('day'); + + if (this.singleDatePicker && !this.timePicker) + this.clickApply(); + }, + + clickApply: function (e) { + this.updateInputText(); + this.hide(); + this.element.trigger('apply.daterangepicker', this); + }, + + clickCancel: function (e) { + this.startDate = this.oldStartDate; + this.endDate = this.oldEndDate; + this.chosenLabel = this.oldChosenLabel; + this.updateView(); + this.updateCalendars(); + this.hide(); + this.element.trigger('cancel.daterangepicker', this); + }, + + updateMonthYear: function (e) { + var isLeft = $(e.target).closest('.calendar').hasClass('left'), + leftOrRight = isLeft ? 'left' : 'right', + cal = this.container.find('.calendar.'+leftOrRight); + + // Month must be Number for new moment versions + var month = parseInt(cal.find('.monthselect').val(), 10); + var year = cal.find('.yearselect').val(); + + if (!isLeft) { + if (year < this.startDate.year() || (year == this.startDate.year() && month < this.startDate.month())) { + month = this.startDate.month(); + year = this.startDate.year(); + } + } + + if (this.minDate) { + if (year < this.minDate.year() || (year == this.minDate.year() && month < this.minDate.month())) { + month = this.minDate.month(); + year = this.minDate.year(); + } + } + + if (this.maxDate) { + if (year > this.maxDate.year() || (year == this.maxDate.year() && month > this.maxDate.month())) { + month = this.maxDate.month(); + year = this.maxDate.year(); + } + } + + + this[leftOrRight+'Calendar'].month.month(month).year(year); + this.updateCalendars(); + }, + + updateTime: function(e) { + + var cal = $(e.target).closest('.calendar'), + isLeft = cal.hasClass('left'); + + var hour = parseInt(cal.find('.hourselect').val(), 10); + var minute = parseInt(cal.find('.minuteselect').val(), 10); + var second = 0; + + if (this.timePickerSeconds) { + second = parseInt(cal.find('.secondselect').val(), 10); + } + + if (this.timePicker12Hour) { + var ampm = cal.find('.ampmselect').val(); + if (ampm === 'PM' && hour < 12) + hour += 12; + if (ampm === 'AM' && hour === 12) + hour = 0; + } + + if (isLeft) { + var start = this.startDate.clone(); + start.hour(hour); + start.minute(minute); + start.second(second); + this.startDate = start; + this.leftCalendar.month.hour(hour).minute(minute).second(second); + if (this.singleDatePicker) + this.endDate = start.clone(); + } else { + var end = this.endDate.clone(); + end.hour(hour); + end.minute(minute); + end.second(second); + this.endDate = end; + if (this.singleDatePicker) + this.startDate = end.clone(); + this.rightCalendar.month.hour(hour).minute(minute).second(second); + } + + this.updateView(); + this.updateCalendars(); + }, + + updateCalendars: function () { + this.leftCalendar.calendar = this.buildCalendar(this.leftCalendar.month.month(), this.leftCalendar.month.year(), this.leftCalendar.month.hour(), this.leftCalendar.month.minute(), this.leftCalendar.month.second(), 'left'); + this.rightCalendar.calendar = this.buildCalendar(this.rightCalendar.month.month(), this.rightCalendar.month.year(), this.rightCalendar.month.hour(), this.rightCalendar.month.minute(), this.rightCalendar.month.second(), 'right'); + this.container.find('.calendar.left').empty().html(this.renderCalendar(this.leftCalendar.calendar, this.startDate, this.minDate, this.maxDate, 'left')); + this.container.find('.calendar.right').empty().html(this.renderCalendar(this.rightCalendar.calendar, this.endDate, this.singleDatePicker ? this.minDate : this.startDate, this.maxDate, 'right')); + + this.container.find('.ranges li').removeClass('active'); + var customRange = true; + var i = 0; + for (var range in this.ranges) { + if (this.timePicker) { + if (this.startDate.isSame(this.ranges[range][0]) && this.endDate.isSame(this.ranges[range][1])) { + customRange = false; + this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')') + .addClass('active').html(); + } + } else { + //ignore times when comparing dates if time picker is not enabled + if (this.startDate.format('YYYY-MM-DD') == this.ranges[range][0].format('YYYY-MM-DD') && this.endDate.format('YYYY-MM-DD') == this.ranges[range][1].format('YYYY-MM-DD')) { + customRange = false; + this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')') + .addClass('active').html(); + } + } + i++; + } + if (customRange) { + this.chosenLabel = this.container.find('.ranges li:last').addClass('active').html(); + this.showCalendars(); + } + }, + + buildCalendar: function (month, year, hour, minute, second, side) { + var daysInMonth = moment([year, month]).daysInMonth(); + var firstDay = moment([year, month, 1]); + var lastDay = moment([year, month, daysInMonth]); + var lastMonth = moment(firstDay).subtract(1, 'month').month(); + var lastYear = moment(firstDay).subtract(1, 'month').year(); + + var daysInLastMonth = moment([lastYear, lastMonth]).daysInMonth(); + + var dayOfWeek = firstDay.day(); + + var i; + + //initialize a 6 rows x 7 columns array for the calendar + var calendar = []; + calendar.firstDay = firstDay; + calendar.lastDay = lastDay; + + for (i = 0; i < 6; i++) { + calendar[i] = []; + } + + //populate the calendar with date objects + var startDay = daysInLastMonth - dayOfWeek + this.locale.firstDay + 1; + if (startDay > daysInLastMonth) + startDay -= 7; + + if (dayOfWeek == this.locale.firstDay) + startDay = daysInLastMonth - 6; + + var curDate = moment([lastYear, lastMonth, startDay, 12, minute, second]).utcOffset(this.timeZone); + + var col, row; + for (i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add(24, 'hour')) { + if (i > 0 && col % 7 === 0) { + col = 0; + row++; + } + calendar[row][col] = curDate.clone().hour(hour); + curDate.hour(12); + + if (this.minDate && calendar[row][col].format('YYYY-MM-DD') == this.minDate.format('YYYY-MM-DD') && calendar[row][col].isBefore(this.minDate) && side == 'left') { + calendar[row][col] = this.minDate.clone(); + } + + if (this.maxDate && calendar[row][col].format('YYYY-MM-DD') == this.maxDate.format('YYYY-MM-DD') && calendar[row][col].isAfter(this.maxDate) && side == 'right') { + calendar[row][col] = this.maxDate.clone(); + } + + } + + return calendar; + }, + + renderDropdowns: function (selected, minDate, maxDate) { + var currentMonth = selected.month(); + var currentYear = selected.year(); + var maxYear = (maxDate && maxDate.year()) || (currentYear + 5); + var minYear = (minDate && minDate.year()) || (currentYear - 50); + + var monthHtml = '"; + + var yearHtml = ''; + + return monthHtml + yearHtml; + }, + + renderCalendar: function (calendar, selected, minDate, maxDate, side) { + + var html = '
'; + html += ''; + html += ''; + html += ''; + + // add empty cell for week number + if (this.showWeekNumbers) + html += ''; + + if (!minDate || minDate.isBefore(calendar.firstDay)) { + html += ''; + } else { + html += ''; + } + + var dateHtml = this.locale.monthNames[calendar[1][1].month()] + calendar[1][1].format(" YYYY"); + + if (this.showDropdowns) { + dateHtml = this.renderDropdowns(calendar[1][1], minDate, maxDate); + } + + html += ''; + if (!maxDate || maxDate.isAfter(calendar.lastDay)) { + html += ''; + } else { + html += ''; + } + + html += ''; + html += ''; + + // add week number label + if (this.showWeekNumbers) + html += ''; + + $.each(this.locale.daysOfWeek, function (index, dayOfWeek) { + html += ''; + }); + + html += ''; + html += ''; + html += ''; + + for (var row = 0; row < 6; row++) { + html += ''; + + // add week number + if (this.showWeekNumbers) + html += ''; + + for (var col = 0; col < 7; col++) { + var cname = 'available '; + cname += (calendar[row][col].month() == calendar[1][1].month()) ? '' : 'off'; + + if ((minDate && calendar[row][col].isBefore(minDate, 'day')) || (maxDate && calendar[row][col].isAfter(maxDate, 'day'))) { + cname = ' off disabled '; + } else if (calendar[row][col].format('YYYY-MM-DD') == selected.format('YYYY-MM-DD')) { + cname += ' active '; + if (calendar[row][col].format('YYYY-MM-DD') == this.startDate.format('YYYY-MM-DD')) { + cname += ' start-date '; + } + if (calendar[row][col].format('YYYY-MM-DD') == this.endDate.format('YYYY-MM-DD')) { + cname += ' end-date '; + } + } else if (calendar[row][col] >= this.startDate && calendar[row][col] <= this.endDate) { + cname += ' in-range '; + if (calendar[row][col].isSame(this.startDate)) { cname += ' start-date '; } + if (calendar[row][col].isSame(this.endDate)) { cname += ' end-date '; } + } + + var title = 'r' + row + 'c' + col; + html += ''; + } + html += ''; + } + + html += ''; + html += '
' + dateHtml + '
' + this.locale.weekLabel + '' + dayOfWeek + '
' + calendar[row][0].week() + '' + calendar[row][col].date() + '
'; + html += '
'; + + var i; + if (this.timePicker) { + + html += '
'; + html += ' : '; + + html += ' '; + + if (this.timePickerSeconds) { + html += ': '; + } + + if (this.timePicker12Hour) { + html += ''; + } + + html += '
'; + + } + + return html; + + }, + + remove: function() { + + this.container.remove(); + this.element.off('.daterangepicker'); + this.element.removeData('daterangepicker'); + + } + + }; + + $.fn.daterangepicker = function (options, cb) { + this.each(function () { + var el = $(this); + if (el.data('daterangepicker')) + el.data('daterangepicker').remove(); + el.data('daterangepicker', new DateRangePicker(el, options, cb)); + }); + return this; + }; + +})); diff --git a/public/js/moment.min.js b/public/js/moment.min.js new file mode 100644 index 0000000000..024d488fbc --- /dev/null +++ b/public/js/moment.min.js @@ -0,0 +1,7 @@ +//! moment.js +//! version : 2.9.0 +//! authors : Tim Wood, Iskren Chernev, Moment.js contributors +//! license : MIT +//! momentjs.com +(function(a){function b(a,b,c){switch(arguments.length){case 2:return null!=a?a:b;case 3:return null!=a?a:null!=b?b:c;default:throw new Error("Implement me")}}function c(a,b){return Bb.call(a,b)}function d(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1}}function e(a){vb.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+a)}function f(a,b){var c=!0;return o(function(){return c&&(e(a),c=!1),b.apply(this,arguments)},b)}function g(a,b){sc[a]||(e(b),sc[a]=!0)}function h(a,b){return function(c){return r(a.call(this,c),b)}}function i(a,b){return function(c){return this.localeData().ordinal(a.call(this,c),b)}}function j(a,b){var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),f=a.clone().add(e,"months");return 0>b-f?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)}function k(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&12>b&&(b+=12),d||12!==b||(b=0),b):b}function l(){}function m(a,b){b!==!1&&H(a),p(this,a),this._d=new Date(+a._d),uc===!1&&(uc=!0,vb.updateOffset(this),uc=!1)}function n(a){var b=A(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;this._milliseconds=+k+1e3*j+6e4*i+36e5*h,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._locale=vb.localeData(),this._bubble()}function o(a,b){for(var d in b)c(b,d)&&(a[d]=b[d]);return c(b,"toString")&&(a.toString=b.toString),c(b,"valueOf")&&(a.valueOf=b.valueOf),a}function p(a,b){var c,d,e;if("undefined"!=typeof b._isAMomentObject&&(a._isAMomentObject=b._isAMomentObject),"undefined"!=typeof b._i&&(a._i=b._i),"undefined"!=typeof b._f&&(a._f=b._f),"undefined"!=typeof b._l&&(a._l=b._l),"undefined"!=typeof b._strict&&(a._strict=b._strict),"undefined"!=typeof b._tzm&&(a._tzm=b._tzm),"undefined"!=typeof b._isUTC&&(a._isUTC=b._isUTC),"undefined"!=typeof b._offset&&(a._offset=b._offset),"undefined"!=typeof b._pf&&(a._pf=b._pf),"undefined"!=typeof b._locale&&(a._locale=b._locale),Kb.length>0)for(c in Kb)d=Kb[c],e=b[d],"undefined"!=typeof e&&(a[d]=e);return a}function q(a){return 0>a?Math.ceil(a):Math.floor(a)}function r(a,b,c){for(var d=""+Math.abs(a),e=a>=0;d.lengthd;d++)(c&&a[d]!==b[d]||!c&&C(a[d])!==C(b[d]))&&g++;return g+f}function z(a){if(a){var b=a.toLowerCase().replace(/(.)s$/,"$1");a=lc[a]||mc[b]||b}return a}function A(a){var b,d,e={};for(d in a)c(a,d)&&(b=z(d),b&&(e[b]=a[d]));return e}function B(b){var c,d;if(0===b.indexOf("week"))c=7,d="day";else{if(0!==b.indexOf("month"))return;c=12,d="month"}vb[b]=function(e,f){var g,h,i=vb._locale[b],j=[];if("number"==typeof e&&(f=e,e=a),h=function(a){var b=vb().utc().set(d,a);return i.call(vb._locale,b,e||"")},null!=f)return h(f);for(g=0;c>g;g++)j.push(h(g));return j}}function C(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=b>=0?Math.floor(b):Math.ceil(b)),c}function D(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function E(a,b,c){return jb(vb([a,11,31+b-c]),b,c).week}function F(a){return G(a)?366:365}function G(a){return a%4===0&&a%100!==0||a%400===0}function H(a){var b;a._a&&-2===a._pf.overflow&&(b=a._a[Db]<0||a._a[Db]>11?Db:a._a[Eb]<1||a._a[Eb]>D(a._a[Cb],a._a[Db])?Eb:a._a[Fb]<0||a._a[Fb]>24||24===a._a[Fb]&&(0!==a._a[Gb]||0!==a._a[Hb]||0!==a._a[Ib])?Fb:a._a[Gb]<0||a._a[Gb]>59?Gb:a._a[Hb]<0||a._a[Hb]>59?Hb:a._a[Ib]<0||a._a[Ib]>999?Ib:-1,a._pf._overflowDayOfYear&&(Cb>b||b>Eb)&&(b=Eb),a._pf.overflow=b)}function I(b){return null==b._isValid&&(b._isValid=!isNaN(b._d.getTime())&&b._pf.overflow<0&&!b._pf.empty&&!b._pf.invalidMonth&&!b._pf.nullInput&&!b._pf.invalidFormat&&!b._pf.userInvalidated,b._strict&&(b._isValid=b._isValid&&0===b._pf.charsLeftOver&&0===b._pf.unusedTokens.length&&b._pf.bigHour===a)),b._isValid}function J(a){return a?a.toLowerCase().replace("_","-"):a}function K(a){for(var b,c,d,e,f=0;f0;){if(d=L(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&y(e,c,!0)>=b-1)break;b--}f++}return null}function L(a){var b=null;if(!Jb[a]&&Lb)try{b=vb.locale(),require("./locale/"+a),vb.locale(b)}catch(c){}return Jb[a]}function M(a,b){var c,d;return b._isUTC?(c=b.clone(),d=(vb.isMoment(a)||x(a)?+a:+vb(a))-+c,c._d.setTime(+c._d+d),vb.updateOffset(c,!1),c):vb(a).local()}function N(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function O(a){var b,c,d=a.match(Pb);for(b=0,c=d.length;c>b;b++)d[b]=rc[d[b]]?rc[d[b]]:N(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function P(a,b){return a.isValid()?(b=Q(b,a.localeData()),nc[b]||(nc[b]=O(b)),nc[b](a)):a.localeData().invalidDate()}function Q(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(Qb.lastIndex=0;d>=0&&Qb.test(a);)a=a.replace(Qb,c),Qb.lastIndex=0,d-=1;return a}function R(a,b){var c,d=b._strict;switch(a){case"Q":return _b;case"DDDD":return bc;case"YYYY":case"GGGG":case"gggg":return d?cc:Tb;case"Y":case"G":case"g":return ec;case"YYYYYY":case"YYYYY":case"GGGGG":case"ggggg":return d?dc:Ub;case"S":if(d)return _b;case"SS":if(d)return ac;case"SSS":if(d)return bc;case"DDD":return Sb;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":return Wb;case"a":case"A":return b._locale._meridiemParse;case"x":return Zb;case"X":return $b;case"Z":case"ZZ":return Xb;case"T":return Yb;case"SSSS":return Vb;case"MM":case"DD":case"YY":case"GG":case"gg":case"HH":case"hh":case"mm":case"ss":case"ww":case"WW":return d?ac:Rb;case"M":case"D":case"d":case"H":case"h":case"m":case"s":case"w":case"W":case"e":case"E":return Rb;case"Do":return d?b._locale._ordinalParse:b._locale._ordinalParseLenient;default:return c=new RegExp($(Z(a.replace("\\","")),"i"))}}function S(a){a=a||"";var b=a.match(Xb)||[],c=b[b.length-1]||[],d=(c+"").match(jc)||["-",0,0],e=+(60*d[1])+C(d[2]);return"+"===d[0]?e:-e}function T(a,b,c){var d,e=c._a;switch(a){case"Q":null!=b&&(e[Db]=3*(C(b)-1));break;case"M":case"MM":null!=b&&(e[Db]=C(b)-1);break;case"MMM":case"MMMM":d=c._locale.monthsParse(b,a,c._strict),null!=d?e[Db]=d:c._pf.invalidMonth=b;break;case"D":case"DD":null!=b&&(e[Eb]=C(b));break;case"Do":null!=b&&(e[Eb]=C(parseInt(b.match(/\d{1,2}/)[0],10)));break;case"DDD":case"DDDD":null!=b&&(c._dayOfYear=C(b));break;case"YY":e[Cb]=vb.parseTwoDigitYear(b);break;case"YYYY":case"YYYYY":case"YYYYYY":e[Cb]=C(b);break;case"a":case"A":c._meridiem=b;break;case"h":case"hh":c._pf.bigHour=!0;case"H":case"HH":e[Fb]=C(b);break;case"m":case"mm":e[Gb]=C(b);break;case"s":case"ss":e[Hb]=C(b);break;case"S":case"SS":case"SSS":case"SSSS":e[Ib]=C(1e3*("0."+b));break;case"x":c._d=new Date(C(b));break;case"X":c._d=new Date(1e3*parseFloat(b));break;case"Z":case"ZZ":c._useUTC=!0,c._tzm=S(b);break;case"dd":case"ddd":case"dddd":d=c._locale.weekdaysParse(b),null!=d?(c._w=c._w||{},c._w.d=d):c._pf.invalidWeekday=b;break;case"w":case"ww":case"W":case"WW":case"d":case"e":case"E":a=a.substr(0,1);case"gggg":case"GGGG":case"GGGGG":a=a.substr(0,2),b&&(c._w=c._w||{},c._w[a]=C(b));break;case"gg":case"GG":c._w=c._w||{},c._w[a]=vb.parseTwoDigitYear(b)}}function U(a){var c,d,e,f,g,h,i;c=a._w,null!=c.GG||null!=c.W||null!=c.E?(g=1,h=4,d=b(c.GG,a._a[Cb],jb(vb(),1,4).year),e=b(c.W,1),f=b(c.E,1)):(g=a._locale._week.dow,h=a._locale._week.doy,d=b(c.gg,a._a[Cb],jb(vb(),g,h).year),e=b(c.w,1),null!=c.d?(f=c.d,g>f&&++e):f=null!=c.e?c.e+g:g),i=kb(d,e,f,h,g),a._a[Cb]=i.year,a._dayOfYear=i.dayOfYear}function V(a){var c,d,e,f,g=[];if(!a._d){for(e=X(a),a._w&&null==a._a[Eb]&&null==a._a[Db]&&U(a),a._dayOfYear&&(f=b(a._a[Cb],e[Cb]),a._dayOfYear>F(f)&&(a._pf._overflowDayOfYear=!0),d=fb(f,0,a._dayOfYear),a._a[Db]=d.getUTCMonth(),a._a[Eb]=d.getUTCDate()),c=0;3>c&&null==a._a[c];++c)a._a[c]=g[c]=e[c];for(;7>c;c++)a._a[c]=g[c]=null==a._a[c]?2===c?1:0:a._a[c];24===a._a[Fb]&&0===a._a[Gb]&&0===a._a[Hb]&&0===a._a[Ib]&&(a._nextDay=!0,a._a[Fb]=0),a._d=(a._useUTC?fb:eb).apply(null,g),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[Fb]=24)}}function W(a){var b;a._d||(b=A(a._i),a._a=[b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],V(a))}function X(a){var b=new Date;return a._useUTC?[b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate()]:[b.getFullYear(),b.getMonth(),b.getDate()]}function Y(b){if(b._f===vb.ISO_8601)return void ab(b);b._a=[],b._pf.empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,j=0;for(e=Q(b._f,b._locale).match(Pb)||[],c=0;c0&&b._pf.unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),j+=d.length),rc[f]?(d?b._pf.empty=!1:b._pf.unusedTokens.push(f),T(f,d,b)):b._strict&&!d&&b._pf.unusedTokens.push(f);b._pf.charsLeftOver=i-j,h.length>0&&b._pf.unusedInput.push(h),b._pf.bigHour===!0&&b._a[Fb]<=12&&(b._pf.bigHour=a),b._a[Fb]=k(b._locale,b._a[Fb],b._meridiem),V(b),H(b)}function Z(a){return a.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e})}function $(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function _(a){var b,c,e,f,g;if(0===a._f.length)return a._pf.invalidFormat=!0,void(a._d=new Date(0/0));for(f=0;fg)&&(e=g,c=b));o(a,c||b)}function ab(a){var b,c,d=a._i,e=fc.exec(d);if(e){for(a._pf.iso=!0,b=0,c=hc.length;c>b;b++)if(hc[b][1].exec(d)){a._f=hc[b][0]+(e[6]||" ");break}for(b=0,c=ic.length;c>b;b++)if(ic[b][1].exec(d)){a._f+=ic[b][0];break}d.match(Xb)&&(a._f+="Z"),Y(a)}else a._isValid=!1}function bb(a){ab(a),a._isValid===!1&&(delete a._isValid,vb.createFromInputFallback(a))}function cb(a,b){var c,d=[];for(c=0;ca&&h.setFullYear(a),h}function fb(a){var b=new Date(Date.UTC.apply(null,arguments));return 1970>a&&b.setUTCFullYear(a),b}function gb(a,b){if("string"==typeof a)if(isNaN(a)){if(a=b.weekdaysParse(a),"number"!=typeof a)return null}else a=parseInt(a,10);return a}function hb(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function ib(a,b,c){var d=vb.duration(a).abs(),e=Ab(d.as("s")),f=Ab(d.as("m")),g=Ab(d.as("h")),h=Ab(d.as("d")),i=Ab(d.as("M")),j=Ab(d.as("y")),k=e0,k[4]=c,hb.apply({},k)}function jb(a,b,c){var d,e=c-b,f=c-a.day();return f>e&&(f-=7),e-7>f&&(f+=7),d=vb(a).add(f,"d"),{week:Math.ceil(d.dayOfYear()/7),year:d.year()}}function kb(a,b,c,d,e){var f,g,h=fb(a,0,1).getUTCDay();return h=0===h?7:h,c=null!=c?c:e,f=e-h+(h>d?7:0)-(e>h?7:0),g=7*(b-1)+(c-e)+f+1,{year:g>0?a:a-1,dayOfYear:g>0?g:F(a-1)+g}}function lb(b){var c,d=b._i,e=b._f;return b._locale=b._locale||vb.localeData(b._l),null===d||e===a&&""===d?vb.invalid({nullInput:!0}):("string"==typeof d&&(b._i=d=b._locale.preparse(d)),vb.isMoment(d)?new m(d,!0):(e?w(e)?_(b):Y(b):db(b),c=new m(b),c._nextDay&&(c.add(1,"d"),c._nextDay=a),c))}function mb(a,b){var c,d;if(1===b.length&&w(b[0])&&(b=b[0]),!b.length)return vb();for(c=b[0],d=1;d=0?"+":"-";return b+r(Math.abs(a),6)},gg:function(){return r(this.weekYear()%100,2)},gggg:function(){return r(this.weekYear(),4)},ggggg:function(){return r(this.weekYear(),5)},GG:function(){return r(this.isoWeekYear()%100,2)},GGGG:function(){return r(this.isoWeekYear(),4)},GGGGG:function(){return r(this.isoWeekYear(),5)},e:function(){return this.weekday()},E:function(){return this.isoWeekday()},a:function(){return this.localeData().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.localeData().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return C(this.milliseconds()/100)},SS:function(){return r(C(this.milliseconds()/10),2)},SSS:function(){return r(this.milliseconds(),3)},SSSS:function(){return r(this.milliseconds(),3)},Z:function(){var a=this.utcOffset(),b="+";return 0>a&&(a=-a,b="-"),b+r(C(a/60),2)+":"+r(C(a)%60,2)},ZZ:function(){var a=this.utcOffset(),b="+";return 0>a&&(a=-a,b="-"),b+r(C(a/60),2)+r(C(a)%60,2)},z:function(){return this.zoneAbbr()},zz:function(){return this.zoneName()},x:function(){return this.valueOf()},X:function(){return this.unix()},Q:function(){return this.quarter()}},sc={},tc=["months","monthsShort","weekdays","weekdaysShort","weekdaysMin"],uc=!1;pc.length;)xb=pc.pop(),rc[xb+"o"]=i(rc[xb],xb);for(;qc.length;)xb=qc.pop(),rc[xb+xb]=h(rc[xb],2);rc.DDDD=h(rc.DDD,3),o(l.prototype,{set:function(a){var b,c;for(c in a)b=a[c],"function"==typeof b?this[c]=b:this["_"+c]=b;this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(a){return this._months[a.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(a){return this._monthsShort[a.month()]},monthsParse:function(a,b,c){var d,e,f;for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),d=0;12>d;d++){if(e=vb.utc([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(a){return this._weekdays[a.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(a){return this._weekdaysShort[a.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(a){return this._weekdaysMin[a.day()]},weekdaysParse:function(a){var b,c,d;for(this._weekdaysParse||(this._weekdaysParse=[]),b=0;7>b;b++)if(this._weekdaysParse[b]||(c=vb([2e3,1]).day(b),d="^"+this.weekdays(c,"")+"|^"+this.weekdaysShort(c,"")+"|^"+this.weekdaysMin(c,""),this._weekdaysParse[b]=new RegExp(d.replace(".",""),"i")),this._weekdaysParse[b].test(a))return b},_longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY LT",LLLL:"dddd, MMMM D, YYYY LT"},longDateFormat:function(a){var b=this._longDateFormat[a];return!b&&this._longDateFormat[a.toUpperCase()]&&(b=this._longDateFormat[a.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a]=b),b},isPM:function(a){return"p"===(a+"").toLowerCase().charAt(0)},_meridiemParse:/[ap]\.?m?\.?/i,meridiem:function(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"},_calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},calendar:function(a,b,c){var d=this._calendar[a];return"function"==typeof d?d.apply(b,[c]):d},_relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},relativeTime:function(a,b,c,d){var e=this._relativeTime[c];return"function"==typeof e?e(a,b,c,d):e.replace(/%d/i,a)},pastFuture:function(a,b){var c=this._relativeTime[a>0?"future":"past"];return"function"==typeof c?c(b):c.replace(/%s/i,b)},ordinal:function(a){return this._ordinal.replace("%d",a)},_ordinal:"%d",_ordinalParse:/\d{1,2}/,preparse:function(a){return a},postformat:function(a){return a},week:function(a){return jb(a,this._week.dow,this._week.doy).week},_week:{dow:0,doy:6},firstDayOfWeek:function(){return this._week.dow},firstDayOfYear:function(){return this._week.doy},_invalidDate:"Invalid date",invalidDate:function(){return this._invalidDate}}),vb=function(b,c,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._i=b,g._f=c,g._l=e,g._strict=f,g._isUTC=!1,g._pf=d(),lb(g)},vb.suppressDeprecationWarnings=!1,vb.createFromInputFallback=f("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),vb.min=function(){var a=[].slice.call(arguments,0);return mb("isBefore",a)},vb.max=function(){var a=[].slice.call(arguments,0);return mb("isAfter",a)},vb.utc=function(b,c,e,f){var g;return"boolean"==typeof e&&(f=e,e=a),g={},g._isAMomentObject=!0,g._useUTC=!0,g._isUTC=!0,g._l=e,g._i=b,g._f=c,g._strict=f,g._pf=d(),lb(g).utc()},vb.unix=function(a){return vb(1e3*a)},vb.duration=function(a,b){var d,e,f,g,h=a,i=null;return vb.isDuration(a)?h={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(h={},b?h[b]=a:h.milliseconds=a):(i=Nb.exec(a))?(d="-"===i[1]?-1:1,h={y:0,d:C(i[Eb])*d,h:C(i[Fb])*d,m:C(i[Gb])*d,s:C(i[Hb])*d,ms:C(i[Ib])*d}):(i=Ob.exec(a))?(d="-"===i[1]?-1:1,f=function(a){var b=a&&parseFloat(a.replace(",","."));return(isNaN(b)?0:b)*d},h={y:f(i[2]),M:f(i[3]),d:f(i[4]),h:f(i[5]),m:f(i[6]),s:f(i[7]),w:f(i[8])}):null==h?h={}:"object"==typeof h&&("from"in h||"to"in h)&&(g=t(vb(h.from),vb(h.to)),h={},h.ms=g.milliseconds,h.M=g.months),e=new n(h),vb.isDuration(a)&&c(a,"_locale")&&(e._locale=a._locale),e},vb.version=yb,vb.defaultFormat=gc,vb.ISO_8601=function(){},vb.momentProperties=Kb,vb.updateOffset=function(){},vb.relativeTimeThreshold=function(b,c){return oc[b]===a?!1:c===a?oc[b]:(oc[b]=c,!0)},vb.lang=f("moment.lang is deprecated. Use moment.locale instead.",function(a,b){return vb.locale(a,b)}),vb.locale=function(a,b){var c;return a&&(c="undefined"!=typeof b?vb.defineLocale(a,b):vb.localeData(a),c&&(vb.duration._locale=vb._locale=c)),vb._locale._abbr},vb.defineLocale=function(a,b){return null!==b?(b.abbr=a,Jb[a]||(Jb[a]=new l),Jb[a].set(b),vb.locale(a),Jb[a]):(delete Jb[a],null)},vb.langData=f("moment.langData is deprecated. Use moment.localeData instead.",function(a){return vb.localeData(a)}),vb.localeData=function(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return vb._locale;if(!w(a)){if(b=L(a))return b;a=[a]}return K(a)},vb.isMoment=function(a){return a instanceof m||null!=a&&c(a,"_isAMomentObject")},vb.isDuration=function(a){return a instanceof n};for(xb=tc.length-1;xb>=0;--xb)B(tc[xb]);vb.normalizeUnits=function(a){return z(a)},vb.invalid=function(a){var b=vb.utc(0/0);return null!=a?o(b._pf,a):b._pf.userInvalidated=!0,b},vb.parseZone=function(){return vb.apply(null,arguments).parseZone()},vb.parseTwoDigitYear=function(a){return C(a)+(C(a)>68?1900:2e3)},vb.isDate=x,o(vb.fn=m.prototype,{clone:function(){return vb(this)},valueOf:function(){return+this._d-6e4*(this._offset||0)},unix:function(){return Math.floor(+this/1e3)},toString:function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._offset?new Date(+this):this._d},toISOString:function(){var a=vb(this).utc();return 00:!1},parsingFlags:function(){return o({},this._pf)},invalidAt:function(){return this._pf.overflow},utc:function(a){return this.utcOffset(0,a)},local:function(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(this._dateUtcOffset(),"m")),this},format:function(a){var b=P(this,a||vb.defaultFormat);return this.localeData().postformat(b)},add:u(1,"add"),subtract:u(-1,"subtract"),diff:function(a,b,c){var d,e,f=M(a,this),g=6e4*(f.utcOffset()-this.utcOffset());return b=z(b),"year"===b||"month"===b||"quarter"===b?(e=j(this,f),"quarter"===b?e/=3:"year"===b&&(e/=12)):(d=this-f,e="second"===b?d/1e3:"minute"===b?d/6e4:"hour"===b?d/36e5:"day"===b?(d-g)/864e5:"week"===b?(d-g)/6048e5:d),c?e:q(e)},from:function(a,b){return vb.duration({to:this,from:a}).locale(this.locale()).humanize(!b)},fromNow:function(a){return this.from(vb(),a)},calendar:function(a){var b=a||vb(),c=M(b,this).startOf("day"),d=this.diff(c,"days",!0),e=-6>d?"sameElse":-1>d?"lastWeek":0>d?"lastDay":1>d?"sameDay":2>d?"nextDay":7>d?"nextWeek":"sameElse";return this.format(this.localeData().calendar(e,this,vb(b)))},isLeapYear:function(){return G(this.year())},isDST:function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},day:function(a){var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=gb(a,this.localeData()),this.add(a-b,"d")):b},month:qb("Month",!0),startOf:function(a){switch(a=z(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===a?this.weekday(0):"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this},endOf:function(b){return b=z(b),b===a||"millisecond"===b?this:this.startOf(b).add(1,"isoWeek"===b?"week":b).subtract(1,"ms")},isAfter:function(a,b){var c;return b=z("undefined"!=typeof b?b:"millisecond"),"millisecond"===b?(a=vb.isMoment(a)?a:vb(a),+this>+a):(c=vb.isMoment(a)?+a:+vb(a),c<+this.clone().startOf(b))},isBefore:function(a,b){var c;return b=z("undefined"!=typeof b?b:"millisecond"),"millisecond"===b?(a=vb.isMoment(a)?a:vb(a),+a>+this):(c=vb.isMoment(a)?+a:+vb(a),+this.clone().endOf(b)a?this:a}),max:f("moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(a){return a=vb.apply(null,arguments),a>this?this:a}),zone:f("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",function(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}),utcOffset:function(a,b){var c,d=this._offset||0;return null!=a?("string"==typeof a&&(a=S(a)),Math.abs(a)<16&&(a=60*a),!this._isUTC&&b&&(c=this._dateUtcOffset()),this._offset=a,this._isUTC=!0,null!=c&&this.add(c,"m"),d!==a&&(!b||this._changeInProgress?v(this,vb.duration(a-d,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,vb.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?d:this._dateUtcOffset()},isLocal:function(){return!this._isUTC},isUtcOffset:function(){return this._isUTC},isUtc:function(){return this._isUTC&&0===this._offset},zoneAbbr:function(){return this._isUTC?"UTC":""},zoneName:function(){return this._isUTC?"Coordinated Universal Time":""},parseZone:function(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(S(this._i)),this},hasAlignedHourOffset:function(a){return a=a?vb(a).utcOffset():0,(this.utcOffset()-a)%60===0},daysInMonth:function(){return D(this.year(),this.month())},dayOfYear:function(a){var b=Ab((vb(this).startOf("day")-vb(this).startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")},quarter:function(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)},weekYear:function(a){var b=jb(this,this.localeData()._week.dow,this.localeData()._week.doy).year;return null==a?b:this.add(a-b,"y")},isoWeekYear:function(a){var b=jb(this,1,4).year;return null==a?b:this.add(a-b,"y")},week:function(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")},isoWeek:function(a){var b=jb(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")},weekday:function(a){var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")},isoWeekday:function(a){return null==a?this.day()||7:this.day(this.day()%7?a:a-7)},isoWeeksInYear:function(){return E(this.year(),1,4)},weeksInYear:function(){var a=this.localeData()._week;return E(this.year(),a.dow,a.doy)},get:function(a){return a=z(a),this[a]()},set:function(a,b){var c;if("object"==typeof a)for(c in a)this.set(c,a[c]);else a=z(a),"function"==typeof this[a]&&this[a](b);return this},locale:function(b){var c;return b===a?this._locale._abbr:(c=vb.localeData(b),null!=c&&(this._locale=c),this)},lang:f("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(b){return b===a?this.localeData():this.locale(b)}),localeData:function(){return this._locale},_dateUtcOffset:function(){return 15*-Math.round(this._d.getTimezoneOffset()/15)}}),vb.fn.millisecond=vb.fn.milliseconds=qb("Milliseconds",!1),vb.fn.second=vb.fn.seconds=qb("Seconds",!1),vb.fn.minute=vb.fn.minutes=qb("Minutes",!1),vb.fn.hour=vb.fn.hours=qb("Hours",!0),vb.fn.date=qb("Date",!0),vb.fn.dates=f("dates accessor is deprecated. Use date instead.",qb("Date",!0)),vb.fn.year=qb("FullYear",!0),vb.fn.years=f("years accessor is deprecated. Use year instead.",qb("FullYear",!0)),vb.fn.days=vb.fn.day,vb.fn.months=vb.fn.month,vb.fn.weeks=vb.fn.week,vb.fn.isoWeeks=vb.fn.isoWeek,vb.fn.quarters=vb.fn.quarter,vb.fn.toJSON=vb.fn.toISOString,vb.fn.isUTC=vb.fn.isUtc,o(vb.duration.fn=n.prototype,{_bubble:function(){var a,b,c,d=this._milliseconds,e=this._days,f=this._months,g=this._data,h=0;g.milliseconds=d%1e3,a=q(d/1e3),g.seconds=a%60,b=q(a/60),g.minutes=b%60,c=q(b/60),g.hours=c%24,e+=q(c/24),h=q(rb(e)),e-=q(sb(h)),f+=q(e/30),e%=30,h+=q(f/12),f%=12,g.days=e,g.months=f,g.years=h},abs:function(){return this._milliseconds=Math.abs(this._milliseconds),this._days=Math.abs(this._days),this._months=Math.abs(this._months),this._data.milliseconds=Math.abs(this._data.milliseconds),this._data.seconds=Math.abs(this._data.seconds),this._data.minutes=Math.abs(this._data.minutes),this._data.hours=Math.abs(this._data.hours),this._data.months=Math.abs(this._data.months),this._data.years=Math.abs(this._data.years),this},weeks:function(){return q(this.days()/7)},valueOf:function(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*C(this._months/12) +},humanize:function(a){var b=ib(this,!a,this.localeData());return a&&(b=this.localeData().pastFuture(+this,b)),this.localeData().postformat(b)},add:function(a,b){var c=vb.duration(a,b);return this._milliseconds+=c._milliseconds,this._days+=c._days,this._months+=c._months,this._bubble(),this},subtract:function(a,b){var c=vb.duration(a,b);return this._milliseconds-=c._milliseconds,this._days-=c._days,this._months-=c._months,this._bubble(),this},get:function(a){return a=z(a),this[a.toLowerCase()+"s"]()},as:function(a){var b,c;if(a=z(a),"month"===a||"year"===a)return b=this._days+this._milliseconds/864e5,c=this._months+12*rb(b),"month"===a?c:c/12;switch(b=this._days+Math.round(sb(this._months/12)),a){case"week":return b/7+this._milliseconds/6048e5;case"day":return b+this._milliseconds/864e5;case"hour":return 24*b+this._milliseconds/36e5;case"minute":return 24*b*60+this._milliseconds/6e4;case"second":return 24*b*60*60+this._milliseconds/1e3;case"millisecond":return Math.floor(24*b*60*60*1e3)+this._milliseconds;default:throw new Error("Unknown unit "+a)}},lang:vb.fn.lang,locale:vb.fn.locale,toIsoString:f("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",function(){return this.toISOString()}),toISOString:function(){var a=Math.abs(this.years()),b=Math.abs(this.months()),c=Math.abs(this.days()),d=Math.abs(this.hours()),e=Math.abs(this.minutes()),f=Math.abs(this.seconds()+this.milliseconds()/1e3);return this.asSeconds()?(this.asSeconds()<0?"-":"")+"P"+(a?a+"Y":"")+(b?b+"M":"")+(c?c+"D":"")+(d||e||f?"T":"")+(d?d+"H":"")+(e?e+"M":"")+(f?f+"S":""):"P0D"},localeData:function(){return this._locale},toJSON:function(){return this.toISOString()}}),vb.duration.fn.toString=vb.duration.fn.toISOString;for(xb in kc)c(kc,xb)&&tb(xb.toLowerCase());vb.duration.fn.asMilliseconds=function(){return this.as("ms")},vb.duration.fn.asSeconds=function(){return this.as("s")},vb.duration.fn.asMinutes=function(){return this.as("m")},vb.duration.fn.asHours=function(){return this.as("h")},vb.duration.fn.asDays=function(){return this.as("d")},vb.duration.fn.asWeeks=function(){return this.as("weeks")},vb.duration.fn.asMonths=function(){return this.as("M")},vb.duration.fn.asYears=function(){return this.as("y")},vb.locale("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===C(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),Lb?module.exports=vb:"function"==typeof define&&define.amd?(define(function(a,b,c){return c.config&&c.config()&&c.config().noGlobal===!0&&(zb.moment=wb),vb}),ub(!0)):ub()}).call(this); \ No newline at end of file From 56e36847a5e2a26ca79e6d0124358d24013dd621 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 2 Mar 2015 12:35:14 +0100 Subject: [PATCH 22/87] New code for new date range thing. --- app/Http/Controllers/HomeController.php | 54 ++++----------------- app/Http/Middleware/Range.php | 29 +++++------ app/Http/routes.php | 4 +- public/css/firefly.css | 1 + public/js/firefly.js | 37 +++++++++++++- resources/views/layouts/default.blade.php | 36 ++++++++------ resources/views/partials/date_nav.blade.php | 3 ++ resources/views/partials/menu.blade.php | 2 +- 8 files changed, 83 insertions(+), 83 deletions(-) create mode 100644 public/css/firefly.css diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 0d6056761f..cfd2f0ad70 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -8,7 +8,7 @@ use Preferences; use Redirect; use Session; use URL; - +use Input; /** * Class HomeController * @@ -24,6 +24,14 @@ class HomeController extends Controller { } + public function dateRange() { + $start = new Carbon(Input::get('start')); + $end = new Carbon(Input::get('end')); + + Session::put('start',$start); + Session::put('end',$end); + } + /** * @return \Illuminate\Http\RedirectResponse */ @@ -76,49 +84,5 @@ class HomeController extends Controller return view('index', compact('count', 'title', 'subTitle', 'mainTitleIcon', 'transactions')); } - /** - * @param string $range - * - * @return mixed - */ - public function rangeJump($range) - { - - $valid = ['1D', '1W', '1M', '3M', '6M', '1Y',]; - - if (in_array($range, $valid)) { - Preferences::set('viewRange', $range); - Session::forget('range'); - } - - return Redirect::to(URL::previous()); - } - - /** - * @return \Illuminate\Http\RedirectResponse - */ - public function sessionNext() - { - $range = Session::get('range'); - $start = Session::get('start'); - - Session::put('start', Navigation::jumpToNext($range, clone $start)); - - return Redirect::to(URL::previous()); - - } - - /** - * @return \Illuminate\Http\RedirectResponse - */ - public function sessionPrev() - { - $range = Session::get('range'); - $start = Session::get('start'); - - Session::put('start', Navigation::jumpToPrevious($range, clone $start)); - - return Redirect::to(URL::previous()); - } } diff --git a/app/Http/Middleware/Range.php b/app/Http/Middleware/Range.php index 49c3708b93..7ec8a5265e 100644 --- a/app/Http/Middleware/Range.php +++ b/app/Http/Middleware/Range.php @@ -6,9 +6,9 @@ namespace FireflyIII\Http\Middleware; use Carbon\Carbon; use Closure; use Illuminate\Contracts\Auth\Guard; -use Navigation; use Preferences; use Session; +use Navigation; /** * Class SessionFilter @@ -46,25 +46,20 @@ class Range public function handle($request, Closure $theNext) { if ($this->auth->check()) { - // user's view range comes from preferences, gets set in session: - /** @var \FireflyIII\Models\Preference $viewRange */ - $viewRange = Preferences::get('viewRange', '1M'); + // ignore preference. set the range to be the current month: + if (!Session::has('start') && !Session::has('end')) { - // the start and end date are checked and stored: - $start = Session::has('start') ? Session::get('start') : new Carbon; - $start = Navigation::updateStartDate($viewRange->data, $start); - $end = Navigation::updateEndDate($viewRange->data, $start); - $period = Navigation::periodName($viewRange->data, $start); - $prev = Navigation::jumpToPrevious($viewRange->data, clone $start); - $next = Navigation::jumpToNext($viewRange->data, clone $start); + /** @var \FireflyIII\Models\Preference $viewRange */ + $viewRange = Preferences::get('viewRange', '1M'); + $start = Session::has('start') ? Session::get('start') : new Carbon; + $start = Navigation::updateStartDate($viewRange->data, $start); + $end = Navigation::updateEndDate($viewRange->data, $start); + + Session::put('start', $start); + Session::put('end', $end); + } - Session::put('range', $viewRange->data); - Session::put('start', $start); - Session::put('end', $end); - Session::put('period', $period); - Session::put('prev', Navigation::periodName($viewRange->data, $prev)); - Session::put('next', Navigation::periodName($viewRange->data, $next)); } diff --git a/app/Http/routes.php b/app/Http/routes.php index f05ad4625e..c7e9478a67 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -148,9 +148,7 @@ Route::group( ['middleware' => ['auth', 'range']], function () { Route::get('/', ['uses' => 'HomeController@index', 'as' => 'index']); Route::get('/home', ['uses' => 'HomeController@index', 'as' => 'home']); - Route::get('/prev', ['uses' => 'HomeController@sessionPrev', 'as' => 'sessionPrev']); - Route::get('/next', ['uses' => 'HomeController@sessionNext', 'as' => 'sessionNext']); - Route::get('/jump/{range}', ['uses' => 'HomeController@rangeJump', 'as' => 'rangeJump']); + Route::post('/daterange',['uses' => 'HomeController@dateRange','as' => 'daterange']); Route::get('/flush', ['uses' => 'HomeController@flush', 'as' => 'flush']); /** * Account Controller diff --git a/public/css/firefly.css b/public/css/firefly.css new file mode 100644 index 0000000000..07544b7a03 --- /dev/null +++ b/public/css/firefly.css @@ -0,0 +1 @@ +#daterange {cursor:pointer;} \ No newline at end of file diff --git a/public/js/firefly.js b/public/js/firefly.js index 871eb221b4..958897974f 100644 --- a/public/js/firefly.js +++ b/public/js/firefly.js @@ -1,6 +1,38 @@ $(function () { - $('.currencySelect').click(currencySelect) + $('.currencySelect').click(currencySelect); + + $('#daterange').daterangepicker( + { + ranges: { + 'This Month': [moment().startOf('month'), moment().endOf('month')], + 'Last Month': [moment().subtract('month', 1).startOf('month'), moment().subtract('month', 1).endOf('month')], + 'Next Month': [moment().add('month', 1).startOf('month'), moment().add('month', 1).endOf('month')] + }, + opens: 'left', + + format: 'DD-MM-YYYY', + startDate: start, + endDate: end + }, + function(start, end, label) { + + // send post. + $.post(dateRangeURL, { + start: start.format('YYYY-MM-DD'), + end: end.format('YYYY-MM-DD'), + _token: token + }).success(function() { + window.location.reload(true); + }).fail(function() { + alert('Could not change date range'); + + }); + + //alert('A date range was chosen: ' + start.format('YYYY-MM-DD') + ' to ' + end.format('YYYY-MM-DD')); + } + + ); }); @@ -21,4 +53,5 @@ function currencySelect(e) { return false; -} \ No newline at end of file +} + diff --git a/resources/views/layouts/default.blade.php b/resources/views/layouts/default.blade.php index 8a5c78308e..53b51f95da 100644 --- a/resources/views/layouts/default.blade.php +++ b/resources/views/layouts/default.blade.php @@ -16,15 +16,17 @@ - - - - - + + + + + + + @yield('styles') - - - - - - - - - + + + + + + + @yield('scripts') diff --git a/resources/views/partials/date_nav.blade.php b/resources/views/partials/date_nav.blade.php index 71046d2a48..feeab074ea 100644 --- a/resources/views/partials/date_nav.blade.php +++ b/resources/views/partials/date_nav.blade.php @@ -1,3 +1,5 @@ +{{-- +
@@ -26,3 +28,4 @@
+--}} \ No newline at end of file diff --git a/resources/views/partials/menu.blade.php b/resources/views/partials/menu.blade.php index 6f5dd21a44..cbd0d0a1dd 100644 --- a/resources/views/partials/menu.blade.php +++ b/resources/views/partials/menu.blade.php @@ -36,7 +36,7 @@ - + From 7183d72e5cde7ab14afb62bf0ec9a9a5d2951a29 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 2 Mar 2015 12:50:51 +0100 Subject: [PATCH 23/87] Update chart to include other budget repetitions. --- .../Controllers/GoogleChartController.php | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/app/Http/Controllers/GoogleChartController.php b/app/Http/Controllers/GoogleChartController.php index 55e90b4979..82297f3b4d 100644 --- a/app/Http/Controllers/GoogleChartController.php +++ b/app/Http/Controllers/GoogleChartController.php @@ -4,6 +4,7 @@ use App; use Auth; use Carbon\Carbon; use Crypt; +use DB; use Exception; use FireflyIII\Helpers\Report\ReportQueryInterface; use FireflyIII\Http\Requests; @@ -19,11 +20,11 @@ use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use Grumpydictator\Gchart\GChart; use Illuminate\Database\Query\Builder as QueryBuilder; use Illuminate\Database\Query\JoinClause; +use Illuminate\Support\Collection; use Navigation; use Preferences; use Response; use Session; -use DB; use Steam; /** @@ -177,27 +178,35 @@ class GoogleChartController extends Controller /** @var Budget $budget */ foreach ($budgets as $budget) { - /** @var \LimitRepetition $repetition */ - $repetition = LimitRepetition:: + /** @var Collection $repetitions */ + $repetitions = LimitRepetition:: leftJoin('budget_limits', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id') - ->where('limit_repetitions.startdate', $start->format('Y-m-d 00:00:00')) - ->where('budget_limits.budget_id', $budget->id) - ->first(['limit_repetitions.*']); - if (is_null($repetition)) { // use the session start and end for our search query - $searchStart = $start; - $searchEnd = $end; - $limit = 0; // the limit is zero: + ->where('limit_repetitions.startdate', '<=', $end->format('Y-m-d 00:00:00')) + ->where('limit_repetitions.startdate', '>=', $start->format('Y-m-d 00:00:00')) + ->where('budget_limits.budget_id', $budget->id) + ->get(['limit_repetitions.*']); + + // no results? search entire range for expenses and list those. + if ($repetitions->count() == 0) { + $expenses = floatval($budget->transactionjournals()->before($end)->after($start)->lessThan(0)->sum('amount')) * -1; + if ($expenses > 0) { + $chart->addRow($budget->name, 0, $expenses); + } } else { - // use the limit's start and end for our search query - $searchStart = $repetition->startdate; - $searchEnd = $repetition->enddate; - $limit = floatval($repetition->amount); // the limit is the repetitions limit: + // add with foreach: + /** @var LimitRepetition $repetition */ + foreach ($repetitions as $repetition) { + + $expenses + = + floatval($budget->transactionjournals()->before($repetition->enddate)->after($repetition->startdate)->lessThan(0)->sum('amount')) * -1; + if ($expenses > 0) { + $chart->addRow($budget->name . ' (' . $repetition->startdate->format('j M Y') . ')', floatval($repetition->amount), $expenses); + } + } } - $expenses = floatval($budget->transactionjournals()->before($searchEnd)->after($searchStart)->lessThan(0)->sum('amount')) * -1; - if ($expenses > 0) { - $chart->addRow($budget->name, $limit, $expenses); - } + } $noBudgetSet = Auth::user() From edda470bf850d3f076a5e73939599f7e12b04138 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 2 Mar 2015 13:19:13 +0100 Subject: [PATCH 24/87] Add everything range --- app/Helpers/Report/ReportHelper.php | 8 ++------ app/Http/Controllers/HomeController.php | 20 +++++++++++++------- app/Http/Middleware/Range.php | 10 +++++++++- public/js/firefly.js | 4 +++- resources/views/layouts/default.blade.php | 1 + 5 files changed, 28 insertions(+), 15 deletions(-) diff --git a/app/Helpers/Report/ReportHelper.php b/app/Helpers/Report/ReportHelper.php index 9c4a4c4ad7..4ffd22f66f 100644 --- a/app/Helpers/Report/ReportHelper.php +++ b/app/Helpers/Report/ReportHelper.php @@ -7,6 +7,7 @@ use Carbon\Carbon; use FireflyIII\Models\Account; use Illuminate\Database\Query\JoinClause; use Illuminate\Support\Collection; +use Session; /** * Class ReportHelper @@ -40,12 +41,7 @@ class ReportHelper implements ReportHelperInterface */ public function firstDate() { - $journal = Auth::user()->transactionjournals()->orderBy('date', 'ASC')->first(); - if ($journal) { - return $journal->date; - } - - return Carbon::now(); + return Session::get('first'); } /** diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index cfd2f0ad70..25203d8f6f 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -3,12 +3,11 @@ use Auth; use Cache; use Carbon\Carbon; -use Navigation; +use Input; use Preferences; use Redirect; use Session; -use URL; -use Input; + /** * Class HomeController * @@ -24,12 +23,19 @@ class HomeController extends Controller { } - public function dateRange() { + public function dateRange() + { $start = new Carbon(Input::get('start')); - $end = new Carbon(Input::get('end')); + $end = new Carbon(Input::get('end')); - Session::put('start',$start); - Session::put('end',$end); + $diff = $start->diffInDays($end); + + if ($diff > 50) { + Session::flash('warning', $diff . ' days of data may take a while to load.'); + } + + Session::put('start', $start); + Session::put('end', $end); } /** diff --git a/app/Http/Middleware/Range.php b/app/Http/Middleware/Range.php index 7ec8a5265e..36c68e019a 100644 --- a/app/Http/Middleware/Range.php +++ b/app/Http/Middleware/Range.php @@ -6,9 +6,9 @@ namespace FireflyIII\Http\Middleware; use Carbon\Carbon; use Closure; use Illuminate\Contracts\Auth\Guard; +use Navigation; use Preferences; use Session; -use Navigation; /** * Class SessionFilter @@ -59,6 +59,14 @@ class Range Session::put('start', $start); Session::put('end', $end); } + if (!Session::has('first')) { + $journal = $this->auth->user()->transactionjournals()->orderBy('date', 'ASC')->first(['transaction_journals.*']); + if ($journal) { + Session::put('first', $journal->date); + } else { + Session::put('first', Carbon::now()); + } + } } diff --git a/public/js/firefly.js b/public/js/firefly.js index 958897974f..cf002bd366 100644 --- a/public/js/firefly.js +++ b/public/js/firefly.js @@ -7,7 +7,8 @@ $(function () { ranges: { 'This Month': [moment().startOf('month'), moment().endOf('month')], 'Last Month': [moment().subtract('month', 1).startOf('month'), moment().subtract('month', 1).endOf('month')], - 'Next Month': [moment().add('month', 1).startOf('month'), moment().add('month', 1).endOf('month')] + 'Next Month': [moment().add('month', 1).startOf('month'), moment().add('month', 1).endOf('month')], + 'Everything': [firstDate, moment()] }, opens: 'left', @@ -21,6 +22,7 @@ $(function () { $.post(dateRangeURL, { start: start.format('YYYY-MM-DD'), end: end.format('YYYY-MM-DD'), + label: label, _token: token }).success(function() { window.location.reload(true); diff --git a/resources/views/layouts/default.blade.php b/resources/views/layouts/default.blade.php index 53b51f95da..b02c5b9bf2 100644 --- a/resources/views/layouts/default.blade.php +++ b/resources/views/layouts/default.blade.php @@ -128,6 +128,7 @@ var titleString = "{{Session::get('start')->format('j M Y')}} - {{Session::get('end')->format('j M Y')}}"; var dateRangeURL = "{{route('daterange')}}"; var token = "{{csrf_token()}}"; + var firstDate = moment("{{Session::get('first')->format('Y-m-d')}}"); $('#daterange span').text(titleString); From 08ca3c89d322b59e6359fe1737c1b7f9b171d3d1 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 2 Mar 2015 15:27:36 +0100 Subject: [PATCH 25/87] Expanded account view. --- app/Helpers/Report/ReportHelper.php | 8 -------- app/Helpers/Report/ReportHelperInterface.php | 5 ----- app/Http/Controllers/AccountController.php | 17 +++++++++++++++++ app/Http/Controllers/ReportController.php | 4 ++-- resources/views/list/accounts.blade.php | 5 +++++ 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/app/Helpers/Report/ReportHelper.php b/app/Helpers/Report/ReportHelper.php index 4ffd22f66f..bdb05dc2bf 100644 --- a/app/Helpers/Report/ReportHelper.php +++ b/app/Helpers/Report/ReportHelper.php @@ -36,14 +36,6 @@ class ReportHelper implements ReportHelperInterface } - /** - * @return Carbon - */ - public function firstDate() - { - return Session::get('first'); - } - /** * This method gets some kind of list for a monthly overview. * diff --git a/app/Helpers/Report/ReportHelperInterface.php b/app/Helpers/Report/ReportHelperInterface.php index 99fbad8742..49b9b541ac 100644 --- a/app/Helpers/Report/ReportHelperInterface.php +++ b/app/Helpers/Report/ReportHelperInterface.php @@ -14,11 +14,6 @@ interface ReportHelperInterface { - /** - * @return Carbon - */ - public function firstDate(); - /** * @param Carbon $date * diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index f128d61bdd..e2ee97ce0f 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -12,6 +12,7 @@ use Input; use Redirect; use Session; use View; +use Steam; /** * Class AccountController @@ -124,6 +125,22 @@ class AccountController extends Controller }] )->accountTypeIn($types)->get(['accounts.*']); + // last activity: + $accounts->each( + function (Account $account) { + $lastTransaction = $account->transactions()->leftJoin( + 'transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id' + )->orderBy('transaction_journals.date', 'DESC')->first(['transactions.*', 'transaction_journals.date']); + if ($lastTransaction) { + $account->lastActivityDate = $lastTransaction->transactionjournal->date; + } else { + $account->lastActivityDate = null; + } + $account->startBalance = Steam::balance($account, Session::get('start')); + $account->endBalance = Steam::balance($account, Session::get('end')); + } + ); + return view('accounts.index', compact('what', 'subTitleIcon', 'subTitle', 'accounts')); } diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index 5349059c90..2afc7123bc 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -10,7 +10,7 @@ use FireflyIII\Models\Account; use Illuminate\Database\Query\JoinClause; use Steam; use View; - +use Session; /** * Class ReportController * @@ -115,7 +115,7 @@ class ReportController extends Controller */ public function index(ReportHelperInterface $helper) { - $start = $helper->firstDate(); + $start = Session::get('first'); $months = $helper->listOfMonths($start); $years = $helper->listOfYears($start); $title = 'Reports'; diff --git a/resources/views/list/accounts.blade.php b/resources/views/list/accounts.blade.php index 01013341a5..344585846c 100644 --- a/resources/views/list/accounts.blade.php +++ b/resources/views/list/accounts.blade.php @@ -8,6 +8,7 @@ Current balance Active Last activity + Balance difference between {{Session::get('start')->format('jS F Y')}} and {{Session::get('end')->format('jS F Y')}} @foreach($accounts as $account) @@ -42,6 +43,10 @@ Never @endif + + {!! Amount::format($account->endBalance - $account->startBalance) !!} + + @endforeach From 14c7ad201add2ea513776d888a793d7dcf0494a5 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 2 Mar 2015 15:44:06 +0100 Subject: [PATCH 26/87] Paginated the account list. --- app/Http/Controllers/AccountController.php | 19 ++++++++++++++----- resources/views/list/accounts.blade.php | 6 ++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index e2ee97ce0f..e7de232b2d 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -8,11 +8,12 @@ use FireflyIII\Http\Requests; use FireflyIII\Http\Requests\AccountFormRequest; use FireflyIII\Models\Account; use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use Illuminate\Pagination\LengthAwarePaginator; use Input; use Redirect; use Session; -use View; use Steam; +use View; /** * Class AccountController @@ -117,16 +118,21 @@ class AccountController extends Controller $subTitle = Config::get('firefly.subTitlesByIdentifier.' . $what); $subTitleIcon = Config::get('firefly.subIconsByIdentifier.' . $what); $types = Config::get('firefly.accountTypesByIdentifier.' . $what); + $size = 50; + $page = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page')); + $offset = ($page - 1) * $size; + // move to repository: - $accounts = Auth::user()->accounts()->with( + $set = Auth::user()->accounts()->with( ['accountmeta' => function ($query) { $query->where('name', 'accountRole'); }] - )->accountTypeIn($types)->get(['accounts.*']); + )->accountTypeIn($types)->take($size)->offset($offset)->get(['accounts.*']); + $total = Auth::user()->accounts()->accountTypeIn($types)->count(); // last activity: - $accounts->each( + $set->each( function (Account $account) { $lastTransaction = $account->transactions()->leftJoin( 'transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id' @@ -137,10 +143,13 @@ class AccountController extends Controller $account->lastActivityDate = null; } $account->startBalance = Steam::balance($account, Session::get('start')); - $account->endBalance = Steam::balance($account, Session::get('end')); + $account->endBalance = Steam::balance($account, Session::get('end')); } ); + $accounts = new LengthAwarePaginator($set, $total, $size, $page); + $accounts->setPath(route('accounts.index',$what)); + return view('accounts.index', compact('what', 'subTitleIcon', 'subTitle', 'accounts')); } diff --git a/resources/views/list/accounts.blade.php b/resources/views/list/accounts.blade.php index 344585846c..8fdc2ff082 100644 --- a/resources/views/list/accounts.blade.php +++ b/resources/views/list/accounts.blade.php @@ -1,3 +1,6 @@ +@if(is_object($accounts) && method_exists($accounts, 'render')) + {!! $accounts->render() !!} +@endif @@ -51,3 +54,6 @@ @endforeach
 
+@if(is_object($accounts) && method_exists($accounts, 'render')) + {!! $accounts->render() !!} +@endif \ No newline at end of file From f0a5756f2598e61e3051553644df745c391334ed Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 2 Mar 2015 15:45:00 +0100 Subject: [PATCH 27/87] Add a panel-body for the layout. --- resources/views/accounts/index.blade.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/views/accounts/index.blade.php b/resources/views/accounts/index.blade.php index c0f34287a8..09cdafce86 100644 --- a/resources/views/accounts/index.blade.php +++ b/resources/views/accounts/index.blade.php @@ -22,7 +22,9 @@ +
@include('list.accounts') +
From 23fc652092504768acd6fa51e1b0eade51393265 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 2 Mar 2015 15:45:24 +0100 Subject: [PATCH 28/87] Table border. --- resources/views/list/accounts.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/list/accounts.blade.php b/resources/views/list/accounts.blade.php index 8fdc2ff082..3c21e58f79 100644 --- a/resources/views/list/accounts.blade.php +++ b/resources/views/list/accounts.blade.php @@ -1,7 +1,7 @@ @if(is_object($accounts) && method_exists($accounts, 'render')) {!! $accounts->render() !!} @endif - +
From ad2aebb54d307b83d282d5ea40c7d0151417cfc0 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 2 Mar 2015 15:46:31 +0100 Subject: [PATCH 29/87] Sort account list. --- app/Http/Controllers/AccountController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index e7de232b2d..212b62f36a 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -128,7 +128,7 @@ class AccountController extends Controller ['accountmeta' => function ($query) { $query->where('name', 'accountRole'); }] - )->accountTypeIn($types)->take($size)->offset($offset)->get(['accounts.*']); + )->accountTypeIn($types)->take($size)->offset($offset)->orderBy('accounts.name','ASC')->get(['accounts.*']); $total = Auth::user()->accounts()->accountTypeIn($types)->count(); // last activity: From b1af6bab288b1dd5ea89a04b983a150847c148ea Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 2 Mar 2015 20:05:28 +0100 Subject: [PATCH 30/87] Cleaning up and bug fixing. --- app/Events/JournalCreated.php | 31 ++++++ .../Events/ConnectJournalToPiggyBank.php | 85 ++++++++++++++++ .../Events/UpdateJournalConnection.php | 64 +++++++++++++ app/Http/Controllers/AccountController.php | 24 +++-- app/Http/Controllers/CurrencyController.php | 13 ++- .../Controllers/GoogleChartController.php | 19 +--- app/Http/Controllers/PiggyBankController.php | 2 +- .../Controllers/TransactionController.php | 6 +- app/Models/PiggyBankEvent.php | 2 + app/Models/PiggyBankRepetition.php | 24 ++++- app/Providers/EventServiceProvider.php | 9 +- .../Account/AccountRepository.php | 61 ++++++------ .../Account/AccountRepositoryInterface.php | 3 +- app/Support/ExpandedForm.php | 96 ++++++++++--------- public/js/accounts.js | 4 +- resources/views/accounts/show.blade.php | 21 +--- resources/views/budgets/income.blade.php | 2 +- resources/views/budgets/index.blade.php | 2 +- resources/views/budgets/show.blade.php | 7 ++ resources/views/currency/index.blade.php | 31 ++++-- 20 files changed, 363 insertions(+), 143 deletions(-) create mode 100644 app/Events/JournalCreated.php create mode 100644 app/Handlers/Events/ConnectJournalToPiggyBank.php create mode 100644 app/Handlers/Events/UpdateJournalConnection.php diff --git a/app/Events/JournalCreated.php b/app/Events/JournalCreated.php new file mode 100644 index 0000000000..d7af994329 --- /dev/null +++ b/app/Events/JournalCreated.php @@ -0,0 +1,31 @@ +journal = $journal; + $this->piggyBankId = $piggyBankId; + + + + + } + +} diff --git a/app/Handlers/Events/ConnectJournalToPiggyBank.php b/app/Handlers/Events/ConnectJournalToPiggyBank.php new file mode 100644 index 0000000000..5747aeba49 --- /dev/null +++ b/app/Handlers/Events/ConnectJournalToPiggyBank.php @@ -0,0 +1,85 @@ +journal; + $piggyBankId = $event->piggyBankId; + + Log::debug('JournalCreated event: ' . $journal->id . ', ' . $piggyBankId); + + /** @var PiggyBank $piggyBank */ + $piggyBank = Auth::user()->piggybanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']); + + if (is_null($piggyBank) || $journal->transactionType->type != 'Transfer') { + return; + } + Log::debug('Found a piggy bank'); + $amount = 0; + /** @var Transaction $transaction */ + foreach ($journal->transactions()->get() as $transaction) { + if ($transaction->account_id === $piggyBank->account_id) { + // this transaction is the relevant one. + $amount = floatval($transaction->amount); + } + } + Log::debug('Amount: ' . $amount); + if ($amount == 0) { + return; + } + // update piggy bank rep for date of transaction journal. + $repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first(); + if (is_null($repetition)) { + return; + } + + Log::debug('Found rep! ' . $repetition->id); + $repetition->currentamount += $amount; + $repetition->save(); + + PiggyBankEvent::create( + [ + 'piggy_bank_id' => $piggyBank->id, + 'transaction_journal_id' => $journal->id, + 'date' => $journal->date, + 'amount' => $amount + ] + ); + + } + + +} diff --git a/app/Handlers/Events/UpdateJournalConnection.php b/app/Handlers/Events/UpdateJournalConnection.php new file mode 100644 index 0000000000..beeb58e42f --- /dev/null +++ b/app/Handlers/Events/UpdateJournalConnection.php @@ -0,0 +1,64 @@ +journal; + + // get the event connected to this journal: + /** @var PiggyBankEvent $event */ + $event = PiggyBankEvent::where('transaction_journal_id', $journal->id)->first(); + $piggyBank = $event->piggyBank()->first(); + $repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first(); + + if (is_null($repetition)) { + return; + } + $amount = 0; + /** @var Transaction $transaction */ + foreach ($journal->transactions()->get() as $transaction) { + if ($transaction->account_id === $piggyBank->account_id) { + // this transaction is the relevant one. + $amount = floatval($transaction->amount); + } + } + + // update current repetition: + $diff = $amount - $event->amount; + + $repetition->currentamount += $diff; + if($repetition->currentamount < 0) { + $repetition->currentamount = 0; + } + $repetition->save(); + + + $event->amount = $amount; + $event->save(); + } + +} diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 212b62f36a..0e05b3c65f 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -1,6 +1,5 @@ function ($query) { $query->where('name', 'accountRole'); }] - )->accountTypeIn($types)->take($size)->offset($offset)->orderBy('accounts.name','ASC')->get(['accounts.*']); + )->accountTypeIn($types)->take($size)->offset($offset)->orderBy('accounts.name', 'ASC')->get(['accounts.*']); $total = Auth::user()->accounts()->accountTypeIn($types)->count(); // last activity: @@ -148,7 +147,7 @@ class AccountController extends Controller ); $accounts = new LengthAwarePaginator($set, $total, $size, $page); - $accounts->setPath(route('accounts.index',$what)); + $accounts->setPath(route('accounts.index', $what)); return view('accounts.index', compact('what', 'subTitleIcon', 'subTitle', 'accounts')); @@ -156,22 +155,19 @@ class AccountController extends Controller /** * @param Account $account - * @param string $range * @param AccountRepositoryInterface $repository * - * @return \Illuminate\View\View + * @return View */ - public function show(Account $account, $range = 'session') + public function show(Account $account, AccountRepositoryInterface $repository) { - /** @var \FireflyIII\Repositories\Account\AccountRepositoryInterface $repository */ - $repository = App::make('FireflyIII\Repositories\Account\AccountRepositoryInterface'); $page = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page')); $subTitleIcon = Config::get('firefly.subTitlesByIdentifier.' . $account->accountType->type); $what = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type); - $journals = $repository->getJournals($account, $page, $range); + $journals = $repository->getJournals($account, $page); $subTitle = 'Details for ' . strtolower(e($account->accountType->type)) . ' "' . e($account->name) . '"'; - return view('accounts.show', compact('account', 'what', 'range', 'subTitleIcon', 'journals', 'subTitle')); + return view('accounts.show', compact('account', 'what', 'subTitleIcon', 'journals', 'subTitle')); } /** @@ -197,6 +193,10 @@ class AccountController extends Controller Session::flash('success', 'New account "' . $account->name . '" stored!'); + if (intval(Input::get('create_another')) === 1) { + return Redirect::route('accounts.create', $request->input('what')); + } + return Redirect::route('accounts.index', $request->input('what')); } @@ -225,6 +225,10 @@ class AccountController extends Controller Session::flash('success', 'Account "' . $account->name . '" updated.'); + if (intval(Input::get('return_to_edit')) === 1) { + return Redirect::route('accounts.edit', $account->id); + } + return Redirect::route('accounts.index', $what); } diff --git a/app/Http/Controllers/CurrencyController.php b/app/Http/Controllers/CurrencyController.php index 318e2736d3..87baafd9d2 100644 --- a/app/Http/Controllers/CurrencyController.php +++ b/app/Http/Controllers/CurrencyController.php @@ -9,6 +9,8 @@ use Redirect; use Session; use View; use Cache; +use Input; + /** * Class CurrencyController @@ -145,6 +147,10 @@ class CurrencyController extends Controller Session::flash('success', 'Currency "' . $currency->name . '" created'); + if (intval(Input::get('create_another')) === 1) { + return Redirect::route('currency.create'); + } + return Redirect::route('currency.index'); @@ -163,7 +169,12 @@ class CurrencyController extends Controller $currency->name = $request->get('name'); $currency->save(); - Session::flash('success', 'Currency "' . e($currency->namename) . '" updated.'); + Session::flash('success', 'Currency "' . e($currency->name) . '" updated.'); + + + if (intval(Input::get('return_to_edit')) === 1) { + return Redirect::route('currency.edit', $currency->id); + } return Redirect::route('currency.index'); diff --git a/app/Http/Controllers/GoogleChartController.php b/app/Http/Controllers/GoogleChartController.php index 82297f3b4d..e4ef277a58 100644 --- a/app/Http/Controllers/GoogleChartController.php +++ b/app/Http/Controllers/GoogleChartController.php @@ -42,27 +42,14 @@ class GoogleChartController extends Controller * * @return \Illuminate\Http\JsonResponse */ - public function accountBalanceChart(Account $account, $view = 'session', GChart $chart) + public function accountBalanceChart(Account $account, GChart $chart) { $chart->addColumn('Day of month', 'date'); $chart->addColumn('Balance for ' . $account->name, 'number'); $chart->addCertainty(1); - $start = Session::get('start', Carbon::now()->startOfMonth()); - $end = Session::get('end', Carbon::now()->endOfMonth()); - $count = $account->transactions()->count(); - - if ($view == 'all' && $count > 0) { - $first = $account->transactions()->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->orderBy( - 'date', 'ASC' - )->first(['transaction_journals.date']); - $last = $account->transactions()->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->orderBy( - 'date', 'DESC' - )->first(['transaction_journals.date']); - $start = new Carbon($first->date); - $end = new Carbon($last->date); - } - + $start = Session::get('start', Carbon::now()->startOfMonth()); + $end = Session::get('end', Carbon::now()->endOfMonth()); $current = clone $start; while ($end >= $current) { diff --git a/app/Http/Controllers/PiggyBankController.php b/app/Http/Controllers/PiggyBankController.php index 651a55be89..3042134a18 100644 --- a/app/Http/Controllers/PiggyBankController.php +++ b/app/Http/Controllers/PiggyBankController.php @@ -273,7 +273,7 @@ class PiggyBankController extends Controller $piggyBankData = [ 'repeats' => false, 'name' => $request->get('name'), - 'startdate' => new Carbon, + 'startdate' => null, 'account_id' => intval($request->get('account_id')), 'targetamount' => floatval($request->get('targetamount')), 'targetdate' => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null, diff --git a/app/Http/Controllers/TransactionController.php b/app/Http/Controllers/TransactionController.php index 11ccb60bfd..1954c77230 100644 --- a/app/Http/Controllers/TransactionController.php +++ b/app/Http/Controllers/TransactionController.php @@ -3,6 +3,7 @@ use Auth; use Carbon\Carbon; use ExpandedForm; +use FireflyIII\Events\JournalCreated; use FireflyIII\Events\JournalSaved; use FireflyIII\Http\Requests; use FireflyIII\Http\Requests\JournalFormRequest; @@ -144,7 +145,7 @@ class TransactionController extends Controller } if ($journal->piggyBankEvents()->count() > 0) { - $preFilled['piggy_bank_id'] = $journal->piggyBankEvents()->first()->piggy_bank_id; + $preFilled['piggy_bank_id'] = $journal->piggyBankEvents()->orderBy('date', 'DESC')->first()->piggy_bank_id; } $preFilled['amount'] = 0; @@ -266,8 +267,10 @@ class TransactionController extends Controller $journal = $repository->store($journalData); event(new JournalSaved($journal)); + event(new JournalCreated($journal, intval($request->get('piggy_bank_id')))); Session::flash('success', 'New transaction "' . $journal->description . '" stored!'); + if (intval(Input::get('create_another')) === 1) { return Redirect::route('transactions.create', $request->input('what')); } @@ -307,6 +310,7 @@ class TransactionController extends Controller $repository->update($journal, $journalData); event(new JournalSaved($journal)); + // update, get events by date and sort DESC Session::flash('success', 'Transaction "' . e($journalData['description']) . '" updated.'); diff --git a/app/Models/PiggyBankEvent.php b/app/Models/PiggyBankEvent.php index f9a94a0286..775a4e310d 100644 --- a/app/Models/PiggyBankEvent.php +++ b/app/Models/PiggyBankEvent.php @@ -10,6 +10,8 @@ use Illuminate\Database\Eloquent\Model; class PiggyBankEvent extends Model { + protected $fillable = ['piggy_bank_id', 'transaction_journal_id', 'date', 'amount']; + /** * @return array */ diff --git a/app/Models/PiggyBankRepetition.php b/app/Models/PiggyBankRepetition.php index fe4d72a6f2..6bb9d2d6e2 100644 --- a/app/Models/PiggyBankRepetition.php +++ b/app/Models/PiggyBankRepetition.php @@ -1,7 +1,8 @@ belongsTo('FireflyIII\Models\PiggyBank'); } + /** + * @param EloquentBuilder $query + * @param Carbon $date + * + * @return mixed + */ + public function scopeRelevantOnDate(EloquentBuilder $query, Carbon $date) + { + return $query->where( + function($q) use ($date) { + $q->where('startdate', '>=', $date->format('Y-m-d 00:00:00')); + $q->orWhereNull('startdate'); + }) + + ->where(function($q) use ($date) { + + $q->where('targetdate', '<=', $date->format('Y-m-d 00:00:00')); + $q->orWhereNull('targetdate'); + }); + } + } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index b12e29e483..043e9ad7e1 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -32,7 +32,12 @@ class EventServiceProvider extends ServiceProvider = [ 'FireflyIII\Events\JournalSaved' => [ 'FireflyIII\Handlers\Events\RescanJournal', + 'FireflyIII\Handlers\Events\UpdateJournalConnection', + ], + 'FireflyIII\Events\JournalCreated' => [ + 'FireflyIII\Handlers\Events\ConnectJournalToPiggyBank', + ] ]; /** @@ -73,8 +78,8 @@ class EventServiceProvider extends ServiceProvider function (PiggyBank $piggyBank) { $repetition = new PiggyBankRepetition; $repetition->piggyBank()->associate($piggyBank); - $repetition->startdate = $piggyBank->startdate; - $repetition->targetdate = $piggyBank->targetdate; + $repetition->startdate = is_null($piggyBank->startdate) ? null : $piggyBank->startdate; + $repetition->targetdate = is_null($piggyBank->targetdate) ? null : $piggyBank->targetdate; $repetition->currentamount = 0; $repetition->save(); } diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index 2faee4c964..7cb8e23608 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -40,11 +40,10 @@ class AccountRepository implements AccountRepositoryInterface /** * @param Account $account * @param int $page - * @param string $range * * @return mixed */ - public function getJournals(Account $account, $page, $range = 'session') + public function getJournals(Account $account, $page) { $offset = ($page - 1) * 50; $query = Auth::user() @@ -54,10 +53,8 @@ class AccountRepository implements AccountRepositoryInterface ->where('transactions.account_id', $account->id) ->orderBy('date', 'DESC'); - if ($range == 'session') { - $query->before(Session::get('end', Carbon::now()->endOfMonth())); - $query->after(Session::get('start', Carbon::now()->startOfMonth())); - } + $query->before(Session::get('end', Carbon::now()->endOfMonth())); + $query->after(Session::get('start', Carbon::now()->startOfMonth())); $count = $query->count(); $set = $query->take(50)->offset($offset)->get(['transaction_journals.*']); $paginator = new LengthAwarePaginator($set, $count, 50, $page); @@ -296,32 +293,6 @@ class AccountRepository implements AccountRepositoryInterface } - /** - * @param Account $account - * @param TransactionJournal $journal - * @param array $data - * - * @return TransactionJournal - */ - protected function _updateInitialBalance(Account $account, TransactionJournal $journal, array $data) - { - $journal->date = $data['openingBalanceDate']; - - /** @var Transaction $transaction */ - foreach ($journal->transactions()->get() as $transaction) { - if ($account->id == $transaction->account_id) { - $transaction->amount = $data['openingBalance']; - $transaction->save(); - } - if ($account->id != $transaction->account_id) { - $transaction->amount = $data['openingBalance'] * -1; - $transaction->save(); - } - } - - return $journal; - } - /** * @param Account $account * @param array $data @@ -355,4 +326,30 @@ class AccountRepository implements AccountRepositoryInterface } } + + /** + * @param Account $account + * @param TransactionJournal $journal + * @param array $data + * + * @return TransactionJournal + */ + protected function _updateInitialBalance(Account $account, TransactionJournal $journal, array $data) + { + $journal->date = $data['openingBalanceDate']; + + /** @var Transaction $transaction */ + foreach ($journal->transactions()->get() as $transaction) { + if ($account->id == $transaction->account_id) { + $transaction->amount = $data['openingBalance']; + $transaction->save(); + } + if ($account->id != $transaction->account_id) { + $transaction->amount = $data['openingBalance'] * -1; + $transaction->save(); + } + } + + return $journal; + } } \ No newline at end of file diff --git a/app/Repositories/Account/AccountRepositoryInterface.php b/app/Repositories/Account/AccountRepositoryInterface.php index 619309d762..644f67744d 100644 --- a/app/Repositories/Account/AccountRepositoryInterface.php +++ b/app/Repositories/Account/AccountRepositoryInterface.php @@ -21,12 +21,11 @@ interface AccountRepositoryInterface /** * @param Account $account - * @param int $page * @param string $range * * @return mixed */ - public function getJournals(Account $account, $page, $range = 'session'); + public function getJournals(Account $account, $page); /** * @param Account $account diff --git a/app/Support/ExpandedForm.php b/app/Support/ExpandedForm.php index 94f462e6fe..168357d439 100644 --- a/app/Support/ExpandedForm.php +++ b/app/Support/ExpandedForm.php @@ -8,6 +8,7 @@ use Illuminate\Support\MessageBag; use Input; use Session; use View; +use Amount; /** * Class ExpandedForm @@ -17,46 +18,6 @@ use View; class ExpandedForm { - /** - * @param $name - * @param null $value - * @param array $options - * - * @return string - */ - public function integer($name, $value = null, array $options = []) - { - $label = $this->label($name, $options); - $options = $this->expandOptionArray($name, $label, $options); - $classes = $this->getHolderClasses($name); - $value = $this->fillFieldValue($name, $value); - $options['step'] = '1'; - $html = \View::make('form.integer', compact('classes', 'name', 'label', 'value', 'options'))->render(); - - return $html; - - } - - - /** - * @param $name - * @param null $value - * @param array $options - * - * @return string - */ - public function tags($name, $value = null, array $options = []) - { - $label = $this->label($name, $options); - $options = $this->expandOptionArray($name, $label, $options); - $classes = $this->getHolderClasses($name); - $value = $this->fillFieldValue($name, $value); - $options['data-role'] = 'tagsinput'; - $html = \View::make('form.tags', compact('classes', 'name', 'label', 'value', 'options'))->render(); - - return $html; - } - /** * @param $name * @param null $value @@ -91,9 +52,19 @@ class ExpandedForm if (isset($options['label'])) { return $options['label']; } - $labels = ['amount_min' => 'Amount (min)', 'amount_max' => 'Amount (max)', 'match' => 'Matches on', 'repeat_freq' => 'Repetition', - 'account_from_id' => 'Account from', 'account_to_id' => 'Account to', 'account_id' => 'Asset account', 'budget_id' => 'Budget' - , 'piggy_bank_id' => 'Piggy bank']; + $labels = [ + 'amount_min' => 'Amount (min)', + 'amount_max' => 'Amount (max)', + 'match' => 'Matches on', + 'repeat_freq' => 'Repetition', + 'account_from_id' => 'Account from', + 'account_to_id' => 'Account to', + 'account_id' => 'Asset account', + 'budget_id' => 'Budget', + 'openingBalance' => 'Opening balance', + 'accountRole' => 'Account role', + 'openingBalanceDate' => 'Opening balance date', + 'piggy_bank_id' => 'Piggy bank']; return isset($labels[$name]) ? $labels[$name] : str_replace('_', ' ', ucfirst($name)); @@ -229,6 +200,26 @@ class ExpandedForm return $html; } + /** + * @param $name + * @param null $value + * @param array $options + * + * @return string + */ + public function integer($name, $value = null, array $options = []) + { + $label = $this->label($name, $options); + $options = $this->expandOptionArray($name, $label, $options); + $classes = $this->getHolderClasses($name); + $value = $this->fillFieldValue($name, $value); + $options['step'] = '1'; + $html = \View::make('form.integer', compact('classes', 'name', 'label', 'value', 'options'))->render(); + + return $html; + + } + /** * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. * @@ -296,6 +287,25 @@ class ExpandedForm return $html; } + /** + * @param $name + * @param null $value + * @param array $options + * + * @return string + */ + public function tags($name, $value = null, array $options = []) + { + $label = $this->label($name, $options); + $options = $this->expandOptionArray($name, $label, $options); + $classes = $this->getHolderClasses($name); + $value = $this->fillFieldValue($name, $value); + $options['data-role'] = 'tagsinput'; + $html = \View::make('form.tags', compact('classes', 'name', 'label', 'value', 'options'))->render(); + + return $html; + } + /** * @param $name * @param null $value diff --git a/public/js/accounts.js b/public/js/accounts.js index d0830eecef..9301f828e6 100644 --- a/public/js/accounts.js +++ b/public/js/accounts.js @@ -1,7 +1,7 @@ $(function () { - if (typeof(googleLineChart) === "function" && typeof accountID !== 'undefined' && typeof view !== 'undefined') { - googleLineChart('chart/account/' + accountID + '/' + view, 'overview-chart'); + if (typeof(googleLineChart) === "function" && typeof accountID !== 'undefined') { + googleLineChart('chart/account/' + accountID, 'overview-chart'); } }); \ No newline at end of file diff --git a/resources/views/accounts/show.blade.php b/resources/views/accounts/show.blade.php index 2fbd79614d..462cbe5a9e 100644 --- a/resources/views/accounts/show.blade.php +++ b/resources/views/accounts/show.blade.php @@ -2,7 +2,7 @@ @section('content') {!! Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $account) !!}
-
+
{{{$account->name}}} @@ -27,24 +27,6 @@
-
- - @include('partials.date_nav') -
-
- View options for {{{$account->name}}} -
-
-

- @if($range == 'all') - Stick to date-range - @else - Show all transactions - @endif -

-
-
-
@@ -66,7 +48,6 @@ @section('scripts') diff --git a/resources/views/budgets/income.blade.php b/resources/views/budgets/income.blade.php index d01fea7eea..f4573bda88 100644 --- a/resources/views/budgets/income.blade.php +++ b/resources/views/budgets/income.blade.php @@ -5,7 +5,7 @@
+ @if(count($limits) == 1) +

Show everything

+ @endif + @foreach($limits as $limit) @foreach($limit->limitrepetitions as $rep)
@@ -64,6 +68,9 @@ @endforeach @endforeach + @if(count($limits) == 1) +

Show everything

+ @endif
diff --git a/resources/views/currency/index.blade.php b/resources/views/currency/index.blade.php index b7c25e9e7d..0bb9a47136 100644 --- a/resources/views/currency/index.blade.php +++ b/resources/views/currency/index.blade.php @@ -3,7 +3,7 @@ {!! Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName()) !!}
-
+
Currencies @@ -14,23 +14,34 @@

    @if(count($currencies) > 0) +
  Name
+ + + + @foreach($currencies as $currency) -
  • - - - {{{$currency->name}}} ({{{$currency->code}}}) ({{{$currency->symbol}}}) +
  • + + + + @endforeach +
     Currency
    +
    + + +
    +
    {{{$currency->name}}} ({{{$currency->code}}}) ({{{$currency->symbol}}}) @if($currency->id == $defaultCurrency->id) default @else - make default - + make default @endif - +
    @endif -
  • Add another currency
  • - +

    Add another currency

    + From f0316f09ed0c50df5016b79c12b6bec52afc21ee Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 2 Mar 2015 20:29:10 +0100 Subject: [PATCH 31/87] Do not over / undercorrect --- app/Handlers/Events/UpdateJournalConnection.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/Handlers/Events/UpdateJournalConnection.php b/app/Handlers/Events/UpdateJournalConnection.php index beeb58e42f..6ae95a6c9d 100644 --- a/app/Handlers/Events/UpdateJournalConnection.php +++ b/app/Handlers/Events/UpdateJournalConnection.php @@ -51,9 +51,6 @@ class UpdateJournalConnection $diff = $amount - $event->amount; $repetition->currentamount += $diff; - if($repetition->currentamount < 0) { - $repetition->currentamount = 0; - } $repetition->save(); From fa344d530895717ae1a0dd4c31e43c23c7a783e8 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 3 Mar 2015 08:46:14 +0100 Subject: [PATCH 32/87] Do not update when no event connected. --- app/Handlers/Events/UpdateJournalConnection.php | 3 +++ app/Http/Controllers/PiggyBankController.php | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/app/Handlers/Events/UpdateJournalConnection.php b/app/Handlers/Events/UpdateJournalConnection.php index 6ae95a6c9d..346a806abc 100644 --- a/app/Handlers/Events/UpdateJournalConnection.php +++ b/app/Handlers/Events/UpdateJournalConnection.php @@ -32,6 +32,9 @@ class UpdateJournalConnection // get the event connected to this journal: /** @var PiggyBankEvent $event */ $event = PiggyBankEvent::where('transaction_journal_id', $journal->id)->first(); + if(is_null($event)) { + return; + } $piggyBank = $event->piggyBank()->first(); $repetition = $piggyBank->piggyBankRepetitions()->relevantOnDate($journal->date)->first(); diff --git a/app/Http/Controllers/PiggyBankController.php b/app/Http/Controllers/PiggyBankController.php index 3042134a18..e7bd0547bd 100644 --- a/app/Http/Controllers/PiggyBankController.php +++ b/app/Http/Controllers/PiggyBankController.php @@ -9,6 +9,7 @@ use FireflyIII\Http\Requests; use FireflyIII\Http\Requests\PiggyBankFormRequest; use FireflyIII\Models\Account; use FireflyIII\Models\PiggyBank; +use FireflyIII\Models\PiggyBankEvent; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; use Illuminate\Support\Collection; @@ -191,6 +192,9 @@ class PiggyBankController extends Controller $repetition->currentamount += $amount; $repetition->save(); + // create event. + PiggyBankEvent::create(['date' => Carbon::now(), 'amount' => $amount, 'piggy_bank_id' => $piggyBank->id]); + /* * Create event! */ @@ -220,6 +224,8 @@ class PiggyBankController extends Controller $repetition->currentamount -= $amount; $repetition->save(); + PiggyBankEvent::create(['date' => Carbon::now(), 'amount' => $amount * -1, 'piggy_bank_id' => $piggyBank->id]); + /* * Create event! */ From 04395999711cf7470ed074c8b8e1950fb1c2e43d Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 3 Mar 2015 09:15:28 +0100 Subject: [PATCH 33/87] Layout update. --- resources/views/piggy-banks/index.blade.php | 85 ++++++++++++--------- 1 file changed, 50 insertions(+), 35 deletions(-) diff --git a/resources/views/piggy-banks/index.blade.php b/resources/views/piggy-banks/index.blade.php index 6457513596..34a02bf2e2 100644 --- a/resources/views/piggy-banks/index.blade.php +++ b/resources/views/piggy-banks/index.blade.php @@ -8,9 +8,9 @@

    -@foreach($piggyBanks as $piggyBank)
    -
    +@foreach($piggyBanks as $piggyBank) +
    {{{$piggyBank->name}}} @@ -32,56 +32,73 @@
    - -
    -
    - @if($piggyBank->leftToSave > 0) - - @endif - -
    + +
    +
    - -
    -
    - - -
    -
    - -
    - {!! Amount::format($piggyBank->savedSoFar,true) !!} -
    - -
    + +
    percentage == 100) - class="progress-bar progress-bar-success" - @else - class="progress-bar progress-bar-info" - @endif - role="progressbar" aria-valuenow="{{$piggyBank->percentage}}" aria-valuemin="0" aria-valuemax="100" style="min-width: 40px;width: {{$piggyBank->percentage}}%;"> + class="progress-bar progress-bar-success" + @else + class="progress-bar progress-bar-info" + @endif + role="progressbar" aria-valuenow="{{$piggyBank->percentage}}" aria-valuemin="0" aria-valuemax="100" style="min-width: 40px;width: {{$piggyBank->percentage}}%;"> {{$piggyBank->percentage}}%
    - -
    - {!! Amount::format($piggyBank->targetamount,true) !!} + + + +
    + @if($piggyBank->leftToSave > 0) + + @endif +
    + + + + -
    + + + + + + + +
    +
    +
    + {!! Amount::format($piggyBank->savedSoFar,true) !!} +
    +
    + {!! Amount::format($piggyBank->targetamount,true) !!} +
    +
    + @if($piggyBank->leftToSave > 0) + {!! Amount::format($piggyBank->leftToSave) !!} + @endif
    -
    @endforeach +
    +

    @@ -96,7 +113,6 @@

    Account status
    -
    @@ -117,7 +133,6 @@ @endforeach
    Account
    -
    From 4b7f817475903f01772b17145ab409b0e444e57d Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 3 Mar 2015 09:19:16 +0100 Subject: [PATCH 34/87] Removed panel for table. --- resources/views/bills/index.blade.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/views/bills/index.blade.php b/resources/views/bills/index.blade.php index c9a465cc51..98f0e96cd3 100644 --- a/resources/views/bills/index.blade.php +++ b/resources/views/bills/index.blade.php @@ -20,10 +20,8 @@
    -
    @include('list.bills')
    - @stop From 0fcc1e252b6cd6bd3c362cad0c5fd259510f0030 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 3 Mar 2015 09:29:02 +0100 Subject: [PATCH 35/87] Mail user registration confirmation. --- app/Http/Controllers/Auth/AuthController.php | 39 ++++++++++++++++++++ resources/views/emails/registered.blade.php | 5 +++ 2 files changed, 44 insertions(+) create mode 100644 resources/views/emails/registered.blade.php diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php index d79cc2c56e..84c4740265 100644 --- a/app/Http/Controllers/Auth/AuthController.php +++ b/app/Http/Controllers/Auth/AuthController.php @@ -4,6 +4,9 @@ use FireflyIII\Http\Controllers\Controller; use Illuminate\Contracts\Auth\Guard; use Illuminate\Contracts\Auth\Registrar; use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers; +use Illuminate\Http\Request; +use Mail; +use Session; /** * Class AuthController @@ -43,4 +46,40 @@ class AuthController extends Controller $this->middleware('guest', ['except' => 'getLogout']); } + /** + * Handle a registration request for the application. + * + * @param Request $request + * + * @return \Illuminate\Http\Response + */ + public function postRegister(Request $request) + { + $validator = $this->registrar->validator($request->all()); + + if ($validator->fails()) { + $this->throwValidationException( + $request, $validator + ); + } + + $this->auth->login($this->registrar->create($request->all())); + + // get the email address + $email = $this->auth->user()->email; + + // send email. + Mail::send( + 'emails.registered', [], function ($message) use ($email) { + $message->to($email, $email)->subject('Welcome to Firefly III!'); + } + ); + + // set flash message + Session::flash('success','You have registered successfully!'); + + + return redirect($this->redirectPath()); + } + } diff --git a/resources/views/emails/registered.blade.php b/resources/views/emails/registered.blade.php new file mode 100644 index 0000000000..5a58f60f2d --- /dev/null +++ b/resources/views/emails/registered.blade.php @@ -0,0 +1,5 @@ +Hey there! + +Welkome to Firefly III. Your registration has made it, and this email is here to confirm it. + +Thanks for using Firefly! \ No newline at end of file From 65a510785411a2ed275b78e17035c6cfa9fc25ba Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 3 Mar 2015 09:35:06 +0100 Subject: [PATCH 36/87] Small layout updates. --- resources/views/piggy-banks/index.blade.php | 4 +++- resources/views/piggy-banks/show.blade.php | 4 ---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/resources/views/piggy-banks/index.blade.php b/resources/views/piggy-banks/index.blade.php index 34a02bf2e2..b7b3aed631 100644 --- a/resources/views/piggy-banks/index.blade.php +++ b/resources/views/piggy-banks/index.blade.php @@ -34,7 +34,9 @@
    - + @if($piggyBank->savedSoFar > 0) + + @endif
    diff --git a/resources/views/piggy-banks/show.blade.php b/resources/views/piggy-banks/show.blade.php index ae44f06629..c3c7c511cf 100644 --- a/resources/views/piggy-banks/show.blade.php +++ b/resources/views/piggy-banks/show.blade.php @@ -32,7 +32,6 @@
    -
    @@ -97,15 +96,12 @@
    Account(in progress...)
    -
    Table
    -
    @include('list.piggy-bank-events') -
    From 0619adb0cd83ab05d22823c21b0f7667abeb3781 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 3 Mar 2015 17:40:17 +0100 Subject: [PATCH 37/87] Support any bill in any range. --- app/Http/Controllers/BillController.php | 9 +++ .../Controllers/GoogleChartController.php | 64 +++++++++---------- app/Repositories/Bill/BillRepository.php | 59 ++++++++++++++--- .../Bill/BillRepositoryInterface.php | 20 ++++-- app/Support/Navigation.php | 18 +++--- 5 files changed, 113 insertions(+), 57 deletions(-) diff --git a/app/Http/Controllers/BillController.php b/app/Http/Controllers/BillController.php index 139fb63887..6d76aa8f85 100644 --- a/app/Http/Controllers/BillController.php +++ b/app/Http/Controllers/BillController.php @@ -12,6 +12,7 @@ use Redirect; use Session; use URL; use View; +use Input; /** * Class BillController @@ -168,6 +169,10 @@ class BillController extends Controller $bill = $repository->store($billData); Session::flash('success', 'Bill "' . e($bill->name) . '" stored.'); + if (intval(Input::get('create_another')) === 1) { + return Redirect::route('bills.create')->withInput(); + } + return Redirect::route('bills.index'); } @@ -195,6 +200,10 @@ class BillController extends Controller $bill = $repository->update($bill, $billData); + if (intval(Input::get('return_to_edit')) === 1) { + return Redirect::route('bills.edit', $bill->id); + } + Session::flash('success', 'Bill "' . e($bill->name) . '" updated.'); return Redirect::route('bills.index'); diff --git a/app/Http/Controllers/GoogleChartController.php b/app/Http/Controllers/GoogleChartController.php index e4ef277a58..110a0ddbeb 100644 --- a/app/Http/Controllers/GoogleChartController.php +++ b/app/Http/Controllers/GoogleChartController.php @@ -3,7 +3,6 @@ use App; use Auth; use Carbon\Carbon; -use Crypt; use DB; use Exception; use FireflyIII\Helpers\Report\ReportQueryInterface; @@ -16,6 +15,7 @@ use FireflyIII\Models\LimitRepetition; use FireflyIII\Models\PiggyBank; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; +use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use Grumpydictator\Gchart\GChart; use Illuminate\Database\Query\Builder as QueryBuilder; @@ -311,49 +311,45 @@ class GoogleChartController extends Controller * * @return \Symfony\Component\HttpFoundation\Response */ - public function billsOverview(GChart $chart) + public function billsOverview(GChart $chart, BillRepositoryInterface $repository) { + $chart->addColumn('Name', 'string'); + $chart->addColumn('Amount', 'number'); + + $paid = ['items' => [], 'amount' => 0]; $unpaid = ['items' => [], 'amount' => 0]; $start = Session::get('start', Carbon::now()->startOfMonth()); $end = Session::get('end', Carbon::now()->endOfMonth()); - $chart->addColumn('Name', 'string'); - $chart->addColumn('Amount', 'number'); + $bills = Auth::user()->bills()->where('active', 1)->get(); - $set = Bill:: - leftJoin( - 'transaction_journals', function (JoinClause $join) use ($start, $end) { - $join->on('bills.id', '=', 'transaction_journals.bill_id') - ->where('transaction_journals.date', '>=', $start->format('Y-m-d')) - ->where('transaction_journals.date', '<=', $end->format('Y-m-d')); - } - ) - ->leftJoin( - 'transactions', function (JoinClause $join) { - $join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transactions.amount', '>', 0); - } - ) - ->where('active', 1) - ->groupBy('bills.id') - ->get( - ['bills.id', 'bills.name', 'transaction_journals.description', - 'transaction_journals.encrypted', - 'transaction_journals.id as journalId', - \DB::Raw('SUM(`bills`.`amount_min` + `bills`.`amount_max`) / 2 as `averageAmount`'), - 'transactions.amount AS actualAmount'] - ); + /** @var Bill $bill */ + foreach ($bills as $bill) { + $ranges = $repository->getRanges($bill, $start, $end); + + foreach ($ranges as $range) { + // paid a bill in this range? + $count = $bill->transactionjournals()->before($range['end'])->after($range['start'])->count(); + if ($count == 0) { + $unpaid['items'][] = $bill->name . ' (' . $range['start']->format('jS M Y') . ')'; + $unpaid['amount'] += ($bill->amount_max + $bill->amount_min / 2); + + } else { + $journal = $bill->transactionjournals()->with('transactions')->before($range['end'])->after($range['start'])->first(); + $paid['items'][] = $journal->description; + $amount = 0; + foreach ($journal->transactions as $t) { + if (floatval($t->amount) > 0) { + $amount = floatval($t->amount); + } + } + $paid['amount'] += $amount; + } - foreach ($set as $entry) { - if (intval($entry->journalId) == 0) { - $unpaid['items'][] = $entry->name; - $unpaid['amount'] += floatval($entry->averageAmount); - } else { - $description = intval($entry->encrypted) == 1 ? Crypt::decrypt($entry->description) : $entry->description; - $paid['items'][] = $description; - $paid['amount'] += floatval($entry->actualAmount); } } + $chart->addRow('Unpaid: ' . join(', ', $unpaid['items']), $unpaid['amount']); $chart->addRow('Paid: ' . join(', ', $paid['items']), $paid['amount']); $chart->generate(); diff --git a/app/Repositories/Bill/BillRepository.php b/app/Repositories/Bill/BillRepository.php index 3a5a2abf67..5c12f99b0b 100644 --- a/app/Repositories/Bill/BillRepository.php +++ b/app/Repositories/Bill/BillRepository.php @@ -1,18 +1,12 @@ date; + $startOfBill = Navigation::startOfPeriod($startOfBill, $bill->repeat_freq); + + + // all periods of this bill up until the current period: + $billStarts = []; + while ($startOfBill < $end) { + + $endOfBill = Navigation::endOfPeriod($startOfBill, $bill->repeat_freq); + + $billStarts[] = [ + 'start' => clone $startOfBill, + 'end' => clone $endOfBill, + ]; + // actually the next one: + $startOfBill = Navigation::addPeriod($startOfBill, $bill->repeat_freq, $bill->skip); + + } + // for each + $validRanges = []; + foreach ($billStarts as $dateEntry) { + if ($dateEntry['end'] > $start && $dateEntry['start'] < $end) { + // count transactions for bill in this range (not relevant yet!): + // $count = $bill->transactionjournals()->before($dateEntry['end'])->after($dateEntry['start'])->count(); + // if ($count == 0) { + $validRanges[] = $dateEntry; + // } + } + } + + return $validRanges; + // echo $bill->name; + // var_dump($validRanges); + } + /** * @param Bill $bill * @@ -28,6 +70,7 @@ class BillRepository implements BillRepositoryInterface */ public function nextExpectedMatch(Bill $bill) { + $finalDate = null; if ($bill->active == 0) { return $finalDate; @@ -113,7 +156,7 @@ class BillRepository implements BillRepositoryInterface $wordMatch = true; Log::debug('word match is true'); } else { - Log::debug('Count: ' . $count.', count(matches): ' . count($matches)); + Log::debug('Count: ' . $count . ', count(matches): ' . count($matches)); } diff --git a/app/Repositories/Bill/BillRepositoryInterface.php b/app/Repositories/Bill/BillRepositoryInterface.php index ead38877b1..66ce00cf4a 100644 --- a/app/Repositories/Bill/BillRepositoryInterface.php +++ b/app/Repositories/Bill/BillRepositoryInterface.php @@ -1,13 +1,8 @@ 'startOfDay', - 'week' => 'startOfWeek', - 'weekly' => 'startOfWeek', - 'month' => 'startOfMonth', - 'monthly' => 'startOfMonth', - 'quarter' => 'firstOfQuarter', - 'quartly' => 'firstOfQuarter', - 'year' => 'startOfYear', - 'yearly' => 'startOfYear', + 'daily' => 'startOfDay', + 'week' => 'startOfWeek', + 'weekly' => 'startOfWeek', + 'month' => 'startOfMonth', + 'monthly' => 'startOfMonth', + 'quarter' => 'firstOfQuarter', + 'quarterly' => 'firstOfQuarter', + 'year' => 'startOfYear', + 'yearly' => 'startOfYear', ]; if (isset($functionMap[$repeatFreq])) { $function = $functionMap[$repeatFreq]; From 92af4e5c96d33ef0b52905f633e79943248d42a4 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 4 Mar 2015 05:12:05 +0100 Subject: [PATCH 38/87] Layout tweaks. --- resources/views/piggy-banks/index.blade.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/views/piggy-banks/index.blade.php b/resources/views/piggy-banks/index.blade.php index b7b3aed631..c9941e99d0 100644 --- a/resources/views/piggy-banks/index.blade.php +++ b/resources/views/piggy-banks/index.blade.php @@ -10,7 +10,7 @@
    @foreach($piggyBanks as $piggyBank) -
    +
    {{{$piggyBank->name}}} @@ -83,13 +83,13 @@
    -->
    -
    +
    {!! Amount::format($piggyBank->savedSoFar,true) !!}
    -
    +
    {!! Amount::format($piggyBank->targetamount,true) !!}
    -
    +
    @if($piggyBank->leftToSave > 0) {!! Amount::format($piggyBank->leftToSave) !!} @endif From f5437a17f81903613eef6dff9a1e1f3394bdfd06 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 4 Mar 2015 09:42:47 +0100 Subject: [PATCH 39/87] Lots of changes. --- app/Http/Controllers/CategoryController.php | 91 +++++++++++-------- .../Controllers/GoogleChartController.php | 67 ++++++++++---- app/Http/Controllers/RelatedController.php | 44 ++++++--- .../Controllers/TransactionController.php | 13 +-- app/Http/routes.php | 6 +- app/Support/Navigation.php | 22 ++++- app/Validation/FireflyValidator.php | 2 +- public/css/firefly.css | 3 +- public/js/categories.js | 5 +- public/js/firefly.js | 55 ++++++----- public/js/related-manager.js | 17 +--- resources/views/categories/show.blade.php | 22 +++-- resources/views/layouts/default.blade.php | 1 - resources/views/list/categories.blade.php | 5 +- resources/views/preferences/index.blade.php | 4 +- resources/views/related/relate.blade.php | 9 +- .../views/related/searchResult.blade.php | 58 ++++++++++++ resources/views/transactions/show.blade.php | 54 +++++++---- 18 files changed, 316 insertions(+), 162 deletions(-) create mode 100644 resources/views/related/searchResult.blade.php diff --git a/app/Http/Controllers/CategoryController.php b/app/Http/Controllers/CategoryController.php index 8bc05e7bc8..2aeac51618 100644 --- a/app/Http/Controllers/CategoryController.php +++ b/app/Http/Controllers/CategoryController.php @@ -7,10 +7,10 @@ use FireflyIII\Http\Requests\CategoryFormRequest; use FireflyIII\Models\Category; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use Illuminate\Pagination\LengthAwarePaginator; +use Input; use Redirect; use Session; use View; -use Input; /** @@ -38,44 +38,6 @@ class CategoryController extends Controller return view('categories.create')->with('subTitle', 'Create a new category'); } - /** - * @param Category $category - * - * @return $this - */ - public function show(Category $category, CategoryRepositoryInterface $repository) - { - $hideCategory = true; // used in list. - $page = intval(Input::get('page')); - $offset = $page > 0 ? $page * 50 : 0; - $set = $category->transactionJournals()->withRelevantData()->take(50)->offset($offset)->orderBy('date', 'DESC')->get(['transaction_journals.*']); - $count = $category->transactionJournals()->count(); - - $journals = new LengthAwarePaginator($set, $count, 50, $page); - - return view('categories.show', compact('category', 'journals', 'hideCategory')); - } - - /** - * @return \Illuminate\View\View - */ - public function noCategory() - { - $start = Session::get('start', Carbon::now()->startOfMonth()); - $end = Session::get('end', Carbon::now()->startOfMonth()); - $list = Auth::user() - ->transactionjournals() - ->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') - ->whereNull('category_transaction_journal.id') - ->before($end) - ->after($start) - ->orderBy('transaction_journals.date') - ->get(['transaction_journals.*']); - $subTitle = 'Transactions without a category in ' . $start->format('F Y'); - - return view('categories.noCategory', compact('list', 'subTitle')); - } - /** * @param Category $category * @@ -122,11 +84,60 @@ class CategoryController extends Controller */ public function index() { - $categories = Auth::user()->categories()->get(); + $categories = Auth::user()->categories()->orderBy('name', 'ASC')->get(); + + $categories->each( + function (Category $category) { + $latest = $category->transactionjournals()->orderBy('date', 'DESC')->first(); + if ($latest) { + $category->lastActivity = $latest->date; + } + } + ); return view('categories.index', compact('categories')); } + /** + * @return \Illuminate\View\View + */ + public function noCategory() + { + $start = Session::get('start', Carbon::now()->startOfMonth()); + $end = Session::get('end', Carbon::now()->startOfMonth()); + $list = Auth::user() + ->transactionjournals() + ->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id') + ->whereNull('category_transaction_journal.id') + ->before($end) + ->after($start) + ->orderBy('transaction_journals.date') + ->get(['transaction_journals.*']); + $subTitle = 'Transactions without a category in ' . $start->format('F Y'); + + return view('categories.noCategory', compact('list', 'subTitle')); + } + + /** + * @param Category $category + * + * @return $this + */ + public function show(Category $category, CategoryRepositoryInterface $repository) + { + $hideCategory = true; // used in list. + $page = intval(Input::get('page')); + $offset = $page > 0 ? $page * 50 : 0; + $set = $category->transactionJournals()->withRelevantData()->take(50)->offset($offset)->orderBy('date', 'DESC')->get( + ['transaction_journals.*'] + ); + $count = $category->transactionJournals()->count(); + + $journals = new LengthAwarePaginator($set, $count, 50, $page); + + return view('categories.show', compact('category', 'journals', 'hideCategory')); + } + /** * @param CategoryFormRequest $request * @param CategoryRepositoryInterface $repository diff --git a/app/Http/Controllers/GoogleChartController.php b/app/Http/Controllers/GoogleChartController.php index 110a0ddbeb..171fde76d7 100644 --- a/app/Http/Controllers/GoogleChartController.php +++ b/app/Http/Controllers/GoogleChartController.php @@ -13,6 +13,7 @@ use FireflyIII\Models\Budget; use FireflyIII\Models\Category; use FireflyIII\Models\LimitRepetition; use FireflyIII\Models\PiggyBank; +use FireflyIII\Models\Preference; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\Bill\BillRepositoryInterface; @@ -455,36 +456,32 @@ class GoogleChartController extends Controller /** * - * @param Category $category - * @param $year + * @param Category $category * * @return \Illuminate\Http\JsonResponse */ - public function categoriesAndSpending(Category $category, $year, GChart $chart) + public function categoryOverviewChart(Category $category, GChart $chart) { - try { - new Carbon('01-01-' . $year); - } catch (Exception $e) { - return view('error')->with('message', 'Invalid year.'); - } + // oldest transaction in category: + /** @var TransactionJournal $first */ + $first = $category->transactionjournals()->orderBy('date', 'ASC')->first(); + $start = $first->date; + /** @var Preference $range */ + $range = Preferences::get('viewRange', '1M'); + // jump to start of week / month / year / etc (TODO). + $start = Navigation::startOfPeriod($start, $range->data); - $chart->addColumn('Month', 'date'); - $chart->addColumn('Budgeted', 'number'); + $chart->addColumn('Period', 'date'); $chart->addColumn('Spent', 'number'); - $start = new Carbon('01-01-' . $year); - $end = clone $start; - $end->endOfYear(); + $end = new Carbon; while ($start <= $end) { - $currentEnd = clone $start; - $currentEnd->endOfMonth(); - $spent = floatval($category->transactionjournals()->before($end)->after($start)->lessThan(0)->sum('amount')) * -1; - $budgeted = null; + $currentEnd = Navigation::endOfPeriod($start, $range->data); + $spent = floatval($category->transactionjournals()->before($currentEnd)->after($start)->lessThan(0)->sum('amount')) * -1; + $chart->addRow(clone $start, $spent); - $chart->addRow(clone $start, $budgeted, $spent); - - $start->addMonth(); + $start = Navigation::addPeriod($start, $range->data, 0); } @@ -495,6 +492,36 @@ class GoogleChartController extends Controller } + /** + * + * @param Category $category + * + * @return \Illuminate\Http\JsonResponse + */ + public function categoryPeriodChart(Category $category, GChart $chart) + { + // oldest transaction in category: + /** @var TransactionJournal $first */ + $start = Session::get('start'); + $chart->addColumn('Period', 'date'); + $chart->addColumn('Spent', 'number'); + + $end = Session::get('end'); + while ($start <= $end) { + $spent = floatval($category->transactionjournals()->onDate($start)->lessThan(0)->sum('amount')) * -1; + $chart->addRow(clone $start, $spent); + $start->addDay(); + } + + $chart->generate(); + + return Response::json($chart->getData()); + + + } + + + /** * @param PiggyBank $piggyBank * diff --git a/app/Http/Controllers/RelatedController.php b/app/Http/Controllers/RelatedController.php index 9ea88a1352..59f112b2d7 100644 --- a/app/Http/Controllers/RelatedController.php +++ b/app/Http/Controllers/RelatedController.php @@ -10,6 +10,8 @@ use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use Illuminate\Support\Collection; use Response; use Input; +use Redirect; +use URL; /** * Class RelatedController @@ -128,6 +130,34 @@ class RelatedController extends Controller return Response::json(true); } + /** + * @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind. + * + * @param TransactionJournal $parentJournal + * @param TransactionJournal $childJournal + * + * @return \Illuminate\Http\JsonResponse + * @throws Exception + */ + public function getRemoveRelation(TransactionJournal $parentJournal, TransactionJournal $childJournal) + { + $groups = $parentJournal->transactiongroups()->get(); + /** @var TransactionGroup $group */ + foreach ($groups as $group) { + foreach ($group->transactionjournals()->get() as $loopJournal) { + if ($loopJournal->id == $childJournal->id) { + // remove from group: + $group->transactionjournals()->detach($childJournal); + } + } + if ($group->transactionjournals()->count() == 1) { + $group->delete(); + } + } + + return Redirect::to(URL::previous()); + } + /** * @param TransactionJournal $journal * @@ -138,19 +168,9 @@ class RelatedController extends Controller $search = e(trim(Input::get('searchValue'))); - $result = $repository->searchRelated($search, $journal); - $result->each( - function (TransactionJournal $journal) { - /** @var Transaction $t */ - foreach ($journal->transactions()->get() as $t) { - if ($t->amount > 0) { - $journal->amount = $t->amount; - } - } - } - ); + $journals = $repository->searchRelated($search, $journal); + return view('related.searchResult',compact('journals')); - return Response::json($result->toArray()); } } diff --git a/app/Http/Controllers/TransactionController.php b/app/Http/Controllers/TransactionController.php index 1954c77230..49bd53d8b0 100644 --- a/app/Http/Controllers/TransactionController.php +++ b/app/Http/Controllers/TransactionController.php @@ -229,18 +229,9 @@ class TransactionController extends Controller $t->after = $t->before + $t->amount; } ); - $members = new Collection; - /** @var TransactionGroup $group */ - foreach ($journal->transactiongroups()->get() as $group) { - /** @var TransactionJournal $loopJournal */ - foreach ($group->transactionjournals()->get() as $loopJournal) { - if ($loopJournal->id != $journal->id) { - $members->push($loopJournal); - } - } - } - return view('transactions.show', compact('journal', 'members'))->with( + + return view('transactions.show', compact('journal'))->with( 'subTitle', e($journal->transactiontype->type) . ' "' . e($journal->description) . '"' ); } diff --git a/app/Http/routes.php b/app/Http/routes.php index c7e9478a67..664c1dd38b 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -230,12 +230,15 @@ Route::group( Route::get('/chart/budget/{budget}/spending/{year?}', ['uses' => 'GoogleChartController@budgetsAndSpending']); Route::get('/chart/budgets/spending/{year?}', ['uses' => 'GoogleChartController@allBudgetsAndSpending']); Route::get('/chart/budget/{budget}/{limitrepetition}', ['uses' => 'GoogleChartController@budgetLimitSpending']); - Route::get('/chart/category/{category}/spending/{year}', ['uses' => 'GoogleChartController@categoriesAndSpending']); + Route::get('/chart/reports/income-expenses/{year}', ['uses' => 'GoogleChartController@yearInExp']); Route::get('/chart/reports/income-expenses-sum/{year}', ['uses' => 'GoogleChartController@yearInExpSum']); Route::get('/chart/bills/{bill}', ['uses' => 'GoogleChartController@billOverview']); Route::get('/chart/piggy-history/{piggyBank}', ['uses' => 'GoogleChartController@piggyBankHistory']); + Route::get('/chart/category/{category}/period', ['uses' => 'GoogleChartController@categoryPeriodChart']); + Route::get('/chart/category/{category}/overview', ['uses' => 'GoogleChartController@categoryOverviewChart']); + /** * Help Controller */ @@ -284,6 +287,7 @@ Route::group( Route::get('/related/alreadyRelated/{tj}', ['uses' => 'RelatedController@alreadyRelated', 'as' => 'related.alreadyRelated']); Route::post('/related/relate/{tj}/{tjSecond}', ['uses' => 'RelatedController@relate', 'as' => 'related.relate']); Route::post('/related/removeRelation/{tj}/{tjSecond}', ['uses' => 'RelatedController@removeRelation', 'as' => 'related.removeRelation']); + Route::get('/related/remove/{tj}/{tjSecond}', ['uses' => 'RelatedController@getRemoveRelation', 'as' => 'related.getRemoveRelation']); Route::get('/related/related/{tj}', ['uses' => 'RelatedController@related', 'as' => 'related.related']); Route::post('/related/search/{tj}', ['uses' => 'RelatedController@search', 'as' => 'related.search']); diff --git a/app/Support/Navigation.php b/app/Support/Navigation.php index d4290ea33c..c2cfdfb436 100644 --- a/app/Support/Navigation.php +++ b/app/Support/Navigation.php @@ -28,20 +28,27 @@ class Navigation $add = ($skip + 1); $functionMap = [ + '1D' => 'addDays', 'daily' => 'addDays', + '1W' => 'addWeeks', 'weekly' => 'addWeeks', 'week' => 'addWeeks', + '1M' => 'addMonths', 'month' => 'addMonths', 'monthly' => 'addMonths', + '3M' => 'addMonths', 'quarter' => 'addMonths', 'quarterly' => 'addMonths', + '6M' => 'addMonths', 'half-year' => 'addMonths', 'year' => 'addYears', 'yearly' => 'addYears', ]; $modifierMap = [ 'quarter' => 3, + '3M' => 3, 'quarterly' => 3, + '6M' => 6, 'half-year' => 6, ]; if (!isset($functionMap[$repeatFreq])) { @@ -68,24 +75,31 @@ class Navigation $currentEnd = clone $theCurrentEnd; $functionMap = [ + '1D' => 'addDay', 'daily' => 'addDay', + '1W' => 'addWeek', 'week' => 'addWeek', 'weekly' => 'addWeek', + '1M' => 'addMonth', 'month' => 'addMonth', 'monthly' => 'addMonth', + '3M' => 'addMonths', 'quarter' => 'addMonths', 'quarterly' => 'addMonths', + '6M' => 'addMonths', 'half-year' => 'addMonths', 'year' => 'addYear', 'yearly' => 'addYear', ]; $modifierMap = [ 'quarter' => 3, + '3M' => 3, 'quarterly' => 3, 'half-year' => 6, + '6M' => 6, ]; - $subDay = ['week', 'weekly', 'month', 'monthly', 'quarter', 'quarterly', 'half-year', 'year', 'yearly']; + $subDay = ['week', 'weekly', '1W', 'month', 'monthly', '1M', '3M', 'quarter', 'quarterly', '6M', 'half-year', 'year', 'yearly']; if (!isset($functionMap[$repeatFreq])) { throw new FireflyException('Cannot do endOfPeriod for $repeat_freq ' . $repeatFreq); @@ -298,11 +312,15 @@ class Navigation $date = clone $theDate; $functionMap = [ + '1D' => 'startOfDay', 'daily' => 'startOfDay', + '1W' => 'startOfWeek', 'week' => 'startOfWeek', 'weekly' => 'startOfWeek', 'month' => 'startOfMonth', + '1M' => 'startOfMonth', 'monthly' => 'startOfMonth', + '3M' => 'firstOfQuarter', 'quarter' => 'firstOfQuarter', 'quarterly' => 'firstOfQuarter', 'year' => 'startOfYear', @@ -314,7 +332,7 @@ class Navigation return $date; } - if ($repeatFreq == 'half-year') { + if ($repeatFreq == 'half-year' || $repeatFreq == '6M') { $month = intval($date->format('m')); $date->startOfYear(); if ($month >= 7) { diff --git a/app/Validation/FireflyValidator.php b/app/Validation/FireflyValidator.php index 1d06ba7c38..f906c5cb6d 100644 --- a/app/Validation/FireflyValidator.php +++ b/app/Validation/FireflyValidator.php @@ -41,7 +41,7 @@ class FireflyValidator extends Validator */ public function validateUniqueForUser($attribute, $value, $parameters) { - $count = DB::table($parameters[0])->where($parameters[1], $value)->count(); + $count = DB::table($parameters[0])->where($parameters[1], $value)->where('id', '!=', $parameters[2])->count(); if ($count == 0) { return true; } diff --git a/public/css/firefly.css b/public/css/firefly.css index 07544b7a03..15f7ef3e7a 100644 --- a/public/css/firefly.css +++ b/public/css/firefly.css @@ -1 +1,2 @@ -#daterange {cursor:pointer;} \ No newline at end of file +#daterange {cursor:pointer;} +.google-chart-error {height:30px;background:url('/images/error.png') no-repeat center center;} \ No newline at end of file diff --git a/public/js/categories.js b/public/js/categories.js index 694754351b..01c72143d9 100644 --- a/public/js/categories.js +++ b/public/js/categories.js @@ -1,7 +1,8 @@ $(function () { - if (typeof componentID !== 'undefined' && typeof repetitionID === 'undefined') { - googleColumnChart('chart/category/' + componentID + '/spending/' + year, 'componentOverview'); + if (typeof categoryID !== 'undefined') { + googleColumnChart('chart/category/' + categoryID + '/overview', 'componentOverview'); + googleColumnChart('chart/category/' + categoryID + '/period', 'periodOverview'); } diff --git a/public/js/firefly.js b/public/js/firefly.js index cf002bd366..0bf2c43a4f 100644 --- a/public/js/firefly.js +++ b/public/js/firefly.js @@ -2,39 +2,38 @@ $(function () { $('.currencySelect').click(currencySelect); - $('#daterange').daterangepicker( - { - ranges: { - 'This Month': [moment().startOf('month'), moment().endOf('month')], - 'Last Month': [moment().subtract('month', 1).startOf('month'), moment().subtract('month', 1).endOf('month')], - 'Next Month': [moment().add('month', 1).startOf('month'), moment().add('month', 1).endOf('month')], - 'Everything': [firstDate, moment()] - }, - opens: 'left', - - format: 'DD-MM-YYYY', - startDate: start, - endDate: end + $('#daterange').daterangepicker( + { + ranges: { + 'This Month': [moment().startOf('month'), moment().endOf('month')], + 'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')], + 'Next Month': [moment().add(1, 'month').startOf('month'), moment().add(1, 'month').endOf('month')], + 'Everything': [firstDate, moment()] }, - function(start, end, label) { + opens: 'left', - // send post. - $.post(dateRangeURL, { - start: start.format('YYYY-MM-DD'), - end: end.format('YYYY-MM-DD'), - label: label, - _token: token - }).success(function() { - window.location.reload(true); - }).fail(function() { - alert('Could not change date range'); + format: 'DD-MM-YYYY', + startDate: start, + endDate: end + }, + function (start, end, label) { - }); + // send post. + $.post(dateRangeURL, { + start: start.format('YYYY-MM-DD'), + end: end.format('YYYY-MM-DD'), + label: label, + _token: token + }).success(function () { + window.location.reload(true); + }).fail(function () { + alert('Could not change date range'); - //alert('A date range was chosen: ' + start.format('YYYY-MM-DD') + ' to ' + end.format('YYYY-MM-DD')); - } + }); - ); + //alert('A date range was chosen: ' + start.format('YYYY-MM-DD') + ' to ' + end.format('YYYY-MM-DD')); + } + ); }); diff --git a/public/js/related-manager.js b/public/js/related-manager.js index 55cdd19431..77f9860402 100644 --- a/public/js/related-manager.js +++ b/public/js/related-manager.js @@ -42,20 +42,9 @@ function searchRelatedTransactions(e, ID) { var searchValue = $('#relatedSearchValue').val(); if (searchValue != '') { $.post('related/search/' + ID, {searchValue: searchValue,_token:token}).success(function (data) { - // post each result to some div. - $('#relatedSearchResults').empty(); - - $.each(data, function (i, row) { - var tr = $(''); - - var checkBox = $('').append($('').attr('type', 'checkbox').data('relateto', ID).data('id', row.id).click(doRelateNewTransaction)); - var description = $('').text(row.description); - var amount = $('').html(row.amount); - tr.append(checkBox).append(description).append(amount); - $('#relatedSearchResults').append(tr); - //$('#relatedSearchResults').append($('
    ').text(row.id)); - }); - + // post the results to some div. + $('#relatedSearchResultsTitle').show(); + $('#relatedSearchResults').empty().html(data); }).fail(function () { alert('Could not search. Sorry.'); diff --git a/resources/views/categories/show.blade.php b/resources/views/categories/show.blade.php index fd17e123e8..b99ffb9cc5 100644 --- a/resources/views/categories/show.blade.php +++ b/resources/views/categories/show.blade.php @@ -2,7 +2,17 @@ @section('content') {!! Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $category) !!}
    -
    +
    +
    +
    + Overview +
    +
    +
    +
    +
    +
    +
    Overview @@ -11,6 +21,10 @@
    +
    +
    +
    +
    @@ -21,16 +35,12 @@
    -
    - (TODO) -
    @stop @section('scripts') diff --git a/resources/views/layouts/default.blade.php b/resources/views/layouts/default.blade.php index b02c5b9bf2..cf12b29c91 100644 --- a/resources/views/layouts/default.blade.php +++ b/resources/views/layouts/default.blade.php @@ -109,7 +109,6 @@ diff --git a/resources/views/list/categories.blade.php b/resources/views/list/categories.blade.php index 789481e63e..e70c2788b7 100644 --- a/resources/views/list/categories.blade.php +++ b/resources/views/list/categories.blade.php @@ -21,8 +21,11 @@ {{{$category->name}}} - + @if($category->lastActivity) + {{$category->lastActivity->format('jS F Y')}} + @else Never + @endif @endforeach diff --git a/resources/views/preferences/index.blade.php b/resources/views/preferences/index.blade.php index 6f4c55e69d..828eb69402 100644 --- a/resources/views/preferences/index.blade.php +++ b/resources/views/preferences/index.blade.php @@ -45,10 +45,10 @@
    - Home view range + View range
    -

    By default, Firefly will show you one month of data.

    +

    Some charts are automatically grouped in periods. What period would you prefer?