mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-11-20 08:30:06 +00:00
Merge branch 'release/3.2.5'
This commit is contained in:
@@ -4,7 +4,12 @@ php:
|
||||
- 5.5
|
||||
- 5.6
|
||||
|
||||
addons:
|
||||
code_climate:
|
||||
repo_token: 26489f9e854fcdf7e7660ba29c1455694685465b1f90329a79f7d2bf448acb61
|
||||
|
||||
install:
|
||||
- rm composer.lock
|
||||
- composer install
|
||||
|
||||
script:
|
||||
@@ -13,4 +18,7 @@ script:
|
||||
- php vendor/bin/codecept run --coverage --coverage-xml
|
||||
|
||||
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"
|
||||
@@ -1,10 +1,12 @@
|
||||
Firefly III
|
||||
Firefly III (v3.2.5)
|
||||
===========
|
||||
|
||||
[](https://travis-ci.org/JC5/firefly-iii)
|
||||
[](http://stillmaintained.com/JC5/firefly-iii)
|
||||
[](https://coveralls.io/r/JC5/firefly-iii?branch=master)
|
||||
[](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102)
|
||||
[](https://codeclimate.com/github/JC5/firefly-iii)
|
||||
[](https://codeclimate.com/github/JC5/firefly-iii)
|
||||
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
[](https://packagist.org/packages/grumpydictator/firefly-iii)
|
||||
|
||||
607
_sql/firefly-iii-reference-3.2.5.sql
Normal file
607
_sql/firefly-iii-reference-3.2.5.sql
Normal file
@@ -0,0 +1,607 @@
|
||||
# ************************************************************
|
||||
# Sequel Pro SQL dump
|
||||
# Version 4096
|
||||
#
|
||||
# http://www.sequelpro.com/
|
||||
# http://code.google.com/p/sequel-pro/
|
||||
#
|
||||
# Host: 127.0.0.1 (MySQL 5.6.19-0ubuntu0.14.04.1)
|
||||
# Database: homestead
|
||||
# Generation Time: 2015-01-31 05:33:30 +0000
|
||||
# ************************************************************
|
||||
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
|
||||
# Dump of table account_meta
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `account_meta`;
|
||||
|
||||
CREATE TABLE `account_meta` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`account_id` int(10) unsigned NOT NULL,
|
||||
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`data` text COLLATE utf8_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `account_meta_account_id_name_unique` (`account_id`,`name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table account_types
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `account_types`;
|
||||
|
||||
CREATE TABLE `account_types` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`type` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`editable` tinyint(1) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `account_types_type_unique` (`type`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
LOCK TABLES `account_types` WRITE;
|
||||
/*!40000 ALTER TABLE `account_types` DISABLE KEYS */;
|
||||
|
||||
INSERT INTO `account_types` (`id`, `created_at`, `updated_at`, `type`, `editable`)
|
||||
VALUES
|
||||
(1,'2015-01-31 05:33:21','2015-01-31 05:33:21','Default account',1),
|
||||
(2,'2015-01-31 05:33:21','2015-01-31 05:33:21','Cash account',0),
|
||||
(3,'2015-01-31 05:33:21','2015-01-31 05:33:21','Asset account',1),
|
||||
(4,'2015-01-31 05:33:21','2015-01-31 05:33:21','Expense account',1),
|
||||
(5,'2015-01-31 05:33:21','2015-01-31 05:33:21','Revenue account',1),
|
||||
(6,'2015-01-31 05:33:21','2015-01-31 05:33:21','Initial balance account',0),
|
||||
(7,'2015-01-31 05:33:21','2015-01-31 05:33:21','Beneficiary account',1),
|
||||
(8,'2015-01-31 05:33:21','2015-01-31 05:33:21','Import account',0);
|
||||
|
||||
/*!40000 ALTER TABLE `account_types` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
||||
# Dump of table accounts
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `accounts`;
|
||||
|
||||
CREATE TABLE `accounts` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`user_id` int(10) unsigned NOT NULL,
|
||||
`account_type_id` int(10) unsigned NOT NULL,
|
||||
`name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`active` tinyint(1) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `accounts_user_id_account_type_id_name_unique` (`user_id`,`account_type_id`,`name`),
|
||||
KEY `accounts_account_type_id_foreign` (`account_type_id`),
|
||||
CONSTRAINT `accounts_account_type_id_foreign` FOREIGN KEY (`account_type_id`) REFERENCES `account_types` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `accounts_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table bills
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `bills`;
|
||||
|
||||
CREATE TABLE `bills` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`user_id` int(10) unsigned NOT NULL,
|
||||
`name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`match` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`amount_min` decimal(10,2) NOT NULL,
|
||||
`amount_max` decimal(10,2) NOT NULL,
|
||||
`date` date NOT NULL,
|
||||
`active` tinyint(1) NOT NULL,
|
||||
`automatch` tinyint(1) NOT NULL,
|
||||
`repeat_freq` enum('daily','weekly','monthly','quarterly','half-year','yearly') COLLATE utf8_unicode_ci NOT NULL,
|
||||
`skip` smallint(5) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uid_name_unique` (`user_id`,`name`),
|
||||
CONSTRAINT `bills_uid_for` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table budget_limits
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `budget_limits`;
|
||||
|
||||
CREATE TABLE `budget_limits` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`budget_id` int(10) unsigned DEFAULT NULL,
|
||||
`startdate` date NOT NULL,
|
||||
`amount` decimal(10,2) NOT NULL,
|
||||
`repeats` tinyint(1) NOT NULL,
|
||||
`repeat_freq` enum('daily','weekly','monthly','quarterly','half-year','yearly') COLLATE utf8_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `unique_bl_combi` (`budget_id`,`startdate`,`repeat_freq`),
|
||||
CONSTRAINT `bid_foreign` FOREIGN KEY (`budget_id`) REFERENCES `budgets` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table budget_transaction_journal
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `budget_transaction_journal`;
|
||||
|
||||
CREATE TABLE `budget_transaction_journal` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`budget_id` int(10) unsigned NOT NULL,
|
||||
`transaction_journal_id` int(10) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `budid_tjid_unique` (`budget_id`,`transaction_journal_id`),
|
||||
KEY `budget_transaction_journal_transaction_journal_id_foreign` (`transaction_journal_id`),
|
||||
CONSTRAINT `budget_transaction_journal_transaction_journal_id_foreign` FOREIGN KEY (`transaction_journal_id`) REFERENCES `transaction_journals` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `budget_transaction_journal_budget_id_foreign` FOREIGN KEY (`budget_id`) REFERENCES `budgets` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table budgets
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `budgets`;
|
||||
|
||||
CREATE TABLE `budgets` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`user_id` int(10) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `budgets_user_id_name_unique` (`user_id`,`name`),
|
||||
CONSTRAINT `budgets_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table categories
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `categories`;
|
||||
|
||||
CREATE TABLE `categories` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`user_id` int(10) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `categories_user_id_name_unique` (`user_id`,`name`),
|
||||
CONSTRAINT `categories_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table category_transaction_journal
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `category_transaction_journal`;
|
||||
|
||||
CREATE TABLE `category_transaction_journal` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`category_id` int(10) unsigned NOT NULL,
|
||||
`transaction_journal_id` int(10) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `catid_tjid_unique` (`category_id`,`transaction_journal_id`),
|
||||
KEY `category_transaction_journal_transaction_journal_id_foreign` (`transaction_journal_id`),
|
||||
CONSTRAINT `category_transaction_journal_transaction_journal_id_foreign` FOREIGN KEY (`transaction_journal_id`) REFERENCES `transaction_journals` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `category_transaction_journal_category_id_foreign` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table components
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `components`;
|
||||
|
||||
CREATE TABLE `components` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`user_id` int(10) unsigned NOT NULL,
|
||||
`class` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `components_user_id_class_name_unique` (`user_id`,`class`,`name`),
|
||||
CONSTRAINT `components_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table limit_repetitions
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `limit_repetitions`;
|
||||
|
||||
CREATE TABLE `limit_repetitions` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`budget_limit_id` int(10) unsigned NOT NULL,
|
||||
`startdate` date NOT NULL,
|
||||
`enddate` date NOT NULL,
|
||||
`amount` decimal(10,2) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `limit_repetitions_limit_id_startdate_enddate_unique` (`budget_limit_id`,`startdate`,`enddate`),
|
||||
CONSTRAINT `limit_repetitions_limit_id_foreign` FOREIGN KEY (`budget_limit_id`) REFERENCES `budget_limits` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table migrations
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `migrations`;
|
||||
|
||||
CREATE TABLE `migrations` (
|
||||
`migration` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`batch` int(11) NOT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
LOCK TABLES `migrations` WRITE;
|
||||
/*!40000 ALTER TABLE `migrations` DISABLE KEYS */;
|
||||
|
||||
INSERT INTO `migrations` (`migration`, `batch`)
|
||||
VALUES
|
||||
('2014_06_27_163032_create_users_table',1),
|
||||
('2014_06_27_163145_create_account_types_table',1),
|
||||
('2014_06_27_163259_create_accounts_table',1),
|
||||
('2014_06_27_163817_create_components_table',1),
|
||||
('2014_06_27_163818_create_piggybanks_table',1),
|
||||
('2014_06_27_164042_create_transaction_currencies_table',1),
|
||||
('2014_06_27_164512_create_transaction_types_table',1),
|
||||
('2014_06_27_164619_create_recurring_transactions_table',1),
|
||||
('2014_06_27_164620_create_transaction_journals_table',1),
|
||||
('2014_06_27_164836_create_transactions_table',1),
|
||||
('2014_06_27_165344_create_component_transaction_table',1),
|
||||
('2014_07_05_171326_create_component_transaction_journal_table',1),
|
||||
('2014_07_06_123842_create_preferences_table',1),
|
||||
('2014_07_09_204843_create_session_table',1),
|
||||
('2014_07_17_183717_create_limits_table',1),
|
||||
('2014_07_19_055011_create_limit_repeat_table',1),
|
||||
('2014_08_06_044416_create_component_recurring_transaction_table',1),
|
||||
('2014_08_12_173919_create_piggybank_repetitions_table',1),
|
||||
('2014_08_18_100330_create_piggybank_events_table',1),
|
||||
('2014_08_23_113221_create_reminders_table',1),
|
||||
('2014_11_10_172053_create_account_meta_table',1),
|
||||
('2014_11_29_135749_create_transaction_groups_table',1),
|
||||
('2014_11_29_140217_create_transaction_group_transaction_journal_table',1),
|
||||
('2014_12_13_190730_changes_for_v321',1),
|
||||
('2014_12_24_191544_changes_for_v322',1),
|
||||
('2015_01_18_082406_changes_for_v325',1);
|
||||
|
||||
/*!40000 ALTER TABLE `migrations` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
||||
# Dump of table piggy_bank_events
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `piggy_bank_events`;
|
||||
|
||||
CREATE TABLE `piggy_bank_events` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`piggy_bank_id` int(10) unsigned NOT NULL,
|
||||
`transaction_journal_id` int(10) unsigned DEFAULT NULL,
|
||||
`date` date NOT NULL,
|
||||
`amount` decimal(10,2) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `piggybank_events_piggybank_id_foreign` (`piggy_bank_id`),
|
||||
KEY `piggybank_events_transaction_journal_id_foreign` (`transaction_journal_id`),
|
||||
CONSTRAINT `piggybank_events_transaction_journal_id_foreign` FOREIGN KEY (`transaction_journal_id`) REFERENCES `transaction_journals` (`id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `piggybank_events_piggybank_id_foreign` FOREIGN KEY (`piggy_bank_id`) REFERENCES `piggy_banks` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table piggy_bank_repetitions
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `piggy_bank_repetitions`;
|
||||
|
||||
CREATE TABLE `piggy_bank_repetitions` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`piggy_bank_id` int(10) unsigned NOT NULL,
|
||||
`startdate` date DEFAULT NULL,
|
||||
`targetdate` date DEFAULT NULL,
|
||||
`currentamount` decimal(10,2) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `piggybank_repetitions_piggybank_id_startdate_targetdate_unique` (`piggy_bank_id`,`startdate`,`targetdate`),
|
||||
CONSTRAINT `piggybank_repetitions_piggybank_id_foreign` FOREIGN KEY (`piggy_bank_id`) REFERENCES `piggy_banks` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table piggy_banks
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `piggy_banks`;
|
||||
|
||||
CREATE TABLE `piggy_banks` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`account_id` int(10) unsigned NOT NULL,
|
||||
`name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`targetamount` decimal(10,2) NOT NULL,
|
||||
`startdate` date DEFAULT NULL,
|
||||
`targetdate` date DEFAULT NULL,
|
||||
`repeats` tinyint(1) NOT NULL,
|
||||
`rep_length` enum('day','week','quarter','month','year') COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
`rep_every` smallint(5) unsigned NOT NULL,
|
||||
`rep_times` smallint(5) unsigned DEFAULT NULL,
|
||||
`reminder` enum('day','week','quarter','month','year') COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
`reminder_skip` smallint(5) unsigned NOT NULL,
|
||||
`remind_me` tinyint(1) NOT NULL,
|
||||
`order` int(10) unsigned NOT NULL,
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `piggybanks_account_id_name_unique` (`account_id`,`name`),
|
||||
CONSTRAINT `piggybanks_account_id_foreign` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table preferences
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `preferences`;
|
||||
|
||||
CREATE TABLE `preferences` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`user_id` int(10) unsigned NOT NULL,
|
||||
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`data` text COLLATE utf8_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `preferences_user_id_name_unique` (`user_id`,`name`),
|
||||
CONSTRAINT `preferences_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table reminders
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `reminders`;
|
||||
|
||||
CREATE TABLE `reminders` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`user_id` int(10) unsigned NOT NULL,
|
||||
`startdate` date NOT NULL,
|
||||
`enddate` date DEFAULT NULL,
|
||||
`active` tinyint(1) NOT NULL,
|
||||
`notnow` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`remindersable_id` int(10) unsigned DEFAULT NULL,
|
||||
`remindersable_type` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `reminders_user_id_foreign` (`user_id`),
|
||||
CONSTRAINT `reminders_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table sessions
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `sessions`;
|
||||
|
||||
CREATE TABLE `sessions` (
|
||||
`id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`payload` text COLLATE utf8_unicode_ci NOT NULL,
|
||||
`last_activity` int(11) NOT NULL,
|
||||
UNIQUE KEY `sessions_id_unique` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table transaction_currencies
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `transaction_currencies`;
|
||||
|
||||
CREATE TABLE `transaction_currencies` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`code` varchar(3) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`name` varchar(48) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
`symbol` varchar(8) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `transaction_currencies_code_unique` (`code`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
LOCK TABLES `transaction_currencies` WRITE;
|
||||
/*!40000 ALTER TABLE `transaction_currencies` DISABLE KEYS */;
|
||||
|
||||
INSERT INTO `transaction_currencies` (`id`, `created_at`, `updated_at`, `deleted_at`, `code`, `name`, `symbol`)
|
||||
VALUES
|
||||
(1,'2015-01-31 05:33:21','2015-01-31 05:33:21',NULL,'EUR','Euro','€'),
|
||||
(2,'2015-01-31 05:33:21','2015-01-31 05:33:21',NULL,'USD','US Dollar','$'),
|
||||
(3,'2015-01-31 05:33:21','2015-01-31 05:33:21',NULL,'HUF','Hungarian forint','Ft');
|
||||
|
||||
/*!40000 ALTER TABLE `transaction_currencies` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
||||
# Dump of table transaction_group_transaction_journal
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `transaction_group_transaction_journal`;
|
||||
|
||||
CREATE TABLE `transaction_group_transaction_journal` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`transaction_group_id` int(10) unsigned NOT NULL,
|
||||
`transaction_journal_id` int(10) unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `tt_joined` (`transaction_group_id`,`transaction_journal_id`),
|
||||
KEY `tr_trj_id` (`transaction_journal_id`),
|
||||
CONSTRAINT `tr_trj_id` FOREIGN KEY (`transaction_journal_id`) REFERENCES `transaction_journals` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `tr_grp_id` FOREIGN KEY (`transaction_group_id`) REFERENCES `transaction_groups` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table transaction_groups
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `transaction_groups`;
|
||||
|
||||
CREATE TABLE `transaction_groups` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`user_id` int(10) unsigned NOT NULL,
|
||||
`relation` enum('balance') COLLATE utf8_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `transaction_groups_user_id_foreign` (`user_id`),
|
||||
CONSTRAINT `transaction_groups_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table transaction_journals
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `transaction_journals`;
|
||||
|
||||
CREATE TABLE `transaction_journals` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`user_id` int(10) unsigned NOT NULL,
|
||||
`transaction_type_id` int(10) unsigned NOT NULL,
|
||||
`bill_id` int(10) unsigned DEFAULT NULL,
|
||||
`transaction_currency_id` int(10) unsigned NOT NULL,
|
||||
`description` varchar(1024) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
`completed` tinyint(1) NOT NULL,
|
||||
`date` date NOT NULL,
|
||||
`encrypted` tinyint(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `transaction_journals_user_id_foreign` (`user_id`),
|
||||
KEY `transaction_journals_transaction_type_id_foreign` (`transaction_type_id`),
|
||||
KEY `transaction_journals_transaction_currency_id_foreign` (`transaction_currency_id`),
|
||||
KEY `bill_id_foreign` (`bill_id`),
|
||||
CONSTRAINT `bill_id_foreign` FOREIGN KEY (`bill_id`) REFERENCES `bills` (`id`) ON DELETE SET NULL,
|
||||
CONSTRAINT `transaction_journals_transaction_currency_id_foreign` FOREIGN KEY (`transaction_currency_id`) REFERENCES `transaction_currencies` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `transaction_journals_transaction_type_id_foreign` FOREIGN KEY (`transaction_type_id`) REFERENCES `transaction_types` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `transaction_journals_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table transaction_types
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `transaction_types`;
|
||||
|
||||
CREATE TABLE `transaction_types` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`type` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `transaction_types_type_unique` (`type`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
LOCK TABLES `transaction_types` WRITE;
|
||||
/*!40000 ALTER TABLE `transaction_types` DISABLE KEYS */;
|
||||
|
||||
INSERT INTO `transaction_types` (`id`, `created_at`, `updated_at`, `deleted_at`, `type`)
|
||||
VALUES
|
||||
(1,'2015-01-31 05:33:21','2015-01-31 05:33:21',NULL,'Withdrawal'),
|
||||
(2,'2015-01-31 05:33:21','2015-01-31 05:33:21',NULL,'Deposit'),
|
||||
(3,'2015-01-31 05:33:21','2015-01-31 05:33:21',NULL,'Transfer'),
|
||||
(4,'2015-01-31 05:33:21','2015-01-31 05:33:21',NULL,'Opening balance');
|
||||
|
||||
/*!40000 ALTER TABLE `transaction_types` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
||||
# Dump of table transactions
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `transactions`;
|
||||
|
||||
CREATE TABLE `transactions` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`deleted_at` timestamp NULL DEFAULT NULL,
|
||||
`account_id` int(10) unsigned NOT NULL,
|
||||
`transaction_journal_id` int(10) unsigned NOT NULL,
|
||||
`description` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
`amount` decimal(10,2) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `transactions_account_id_foreign` (`account_id`),
|
||||
KEY `transactions_transaction_journal_id_foreign` (`transaction_journal_id`),
|
||||
CONSTRAINT `transactions_account_id_foreign` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `transactions_transaction_journal_id_foreign` FOREIGN KEY (`transaction_journal_id`) REFERENCES `transaction_journals` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
# Dump of table users
|
||||
# ------------------------------------------------------------
|
||||
|
||||
DROP TABLE IF EXISTS `users`;
|
||||
|
||||
CREATE TABLE `users` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`email` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`password` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
|
||||
`reset` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
`remember_token` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `users_email_unique` (`email`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
|
||||
|
||||
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
@@ -5,8 +5,7 @@ use FireflyIII\Exception\FireflyException;
|
||||
/**
|
||||
*
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's all 5. So ok.
|
||||
* @SuppressWarnings("NPathComplexity")
|
||||
*
|
||||
* Class BillController
|
||||
*
|
||||
*/
|
||||
@@ -120,9 +119,9 @@ class BillController extends BaseController
|
||||
*/
|
||||
public function show(Bill $bill)
|
||||
{
|
||||
$journals = $bill->transactionjournals()->withRelevantData()->orderBy('date', 'DESC')->get();
|
||||
$journals = $bill->transactionjournals()->withRelevantData()->orderBy('date', 'DESC')->get();
|
||||
$bill->nextExpectedMatch = $this->_repository->nextExpectedMatch($bill);
|
||||
$hideBill = true;
|
||||
$hideBill = true;
|
||||
|
||||
|
||||
return View::make('bills.show', compact('journals', 'hideBill', 'bill'))->with(
|
||||
@@ -136,7 +135,7 @@ class BillController extends BaseController
|
||||
*/
|
||||
public function store()
|
||||
{
|
||||
$data = Input::all();
|
||||
$data = Input::except(['_token', 'post_submit_action']);
|
||||
$data['user_id'] = Auth::user()->id;
|
||||
|
||||
|
||||
@@ -149,17 +148,19 @@ class BillController extends BaseController
|
||||
Session::flash('errors', $messages['errors']);
|
||||
if ($messages['errors']->count() > 0) {
|
||||
Session::flash('error', 'Could not store bill: ' . $messages['errors']->first());
|
||||
|
||||
return Redirect::route('bills.create')->withInput();
|
||||
}
|
||||
|
||||
// return to create screen:
|
||||
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
|
||||
if (Input::get('post_submit_action') == 'validate_only') {
|
||||
return Redirect::route('bills.create')->withInput();
|
||||
}
|
||||
|
||||
// store
|
||||
$this->_repository->store($data);
|
||||
Session::flash('success', 'Bill "' . e($data['name']) . '" stored.');
|
||||
if ($data['post_submit_action'] == 'store') {
|
||||
if (Input::get('post_submit_action') == 'store') {
|
||||
return Redirect::route('bills.index');
|
||||
}
|
||||
|
||||
@@ -176,8 +177,8 @@ class BillController extends BaseController
|
||||
public function update(Bill $bill)
|
||||
{
|
||||
$data = Input::except('_token');
|
||||
$data['active'] = isset($data['active']) ? 1 : 0;
|
||||
$data['automatch'] = isset($data['automatch']) ? 1 : 0;
|
||||
$data['active'] = intval(Input::get('active'));
|
||||
$data['automatch'] = intval(Input::get('automatch'));
|
||||
$data['user_id'] = Auth::user()->id;
|
||||
|
||||
// always validate:
|
||||
@@ -189,10 +190,12 @@ class BillController extends BaseController
|
||||
Session::flash('errors', $messages['errors']);
|
||||
if ($messages['errors']->count() > 0) {
|
||||
Session::flash('error', 'Could not update bill: ' . $messages['errors']->first());
|
||||
|
||||
return Redirect::route('bills.edit', $bill->id)->withInput();
|
||||
}
|
||||
|
||||
// return to update screen:
|
||||
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
|
||||
if ($data['post_submit_action'] == 'validate_only') {
|
||||
return Redirect::route('bills.edit', $bill->id)->withInput();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@ use FireflyIII\Shared\Preferences\PreferencesInterface as Pref;
|
||||
* Class BudgetController
|
||||
*
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
* @SuppressWarnings("TooManyMethods") // I'm also fine with this.
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's all 5. So ok.
|
||||
* @SuppressWarnings("CouplingBetweenObjects") // There's only so much I can remove.
|
||||
*
|
||||
*/
|
||||
class BudgetController extends BaseController
|
||||
@@ -45,7 +42,7 @@ class BudgetController extends BaseController
|
||||
$date = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$limitRepetition = $this->_repository->updateLimitAmount($budget, $date, $amount);
|
||||
|
||||
return Response::json(['name' => $budget->name, 'repetition' => $limitRepetition->id]);
|
||||
return Response::json(['name' => $budget->name, 'repetition' => $limitRepetition ? $limitRepetition->id : 0]);
|
||||
|
||||
}
|
||||
|
||||
@@ -148,6 +145,8 @@ class BudgetController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @param LimitRepetition $repetition
|
||||
*
|
||||
@@ -184,10 +183,11 @@ class BudgetController extends BaseController
|
||||
Session::flash('errors', $messages['errors']);
|
||||
if ($messages['errors']->count() > 0) {
|
||||
Session::flash('error', 'Could not validate budget: ' . $messages['errors']->first());
|
||||
return Redirect::route('budgets.create')->withInput();
|
||||
}
|
||||
|
||||
// return to create screen:
|
||||
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
|
||||
if ($data['post_submit_action'] == 'validate_only') {
|
||||
return Redirect::route('budgets.create')->withInput();
|
||||
}
|
||||
|
||||
@@ -222,10 +222,11 @@ class BudgetController extends BaseController
|
||||
Session::flash('errors', $messages['errors']);
|
||||
if ($messages['errors']->count() > 0) {
|
||||
Session::flash('error', 'Could not update budget: ' . $messages['errors']->first());
|
||||
return Redirect::route('budgets.edit', $budget->id)->withInput();
|
||||
}
|
||||
|
||||
// return to update screen:
|
||||
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
|
||||
if ($data['post_submit_action'] == 'validate_only') {
|
||||
return Redirect::route('budgets.edit', $budget->id)->withInput();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ use FireflyIII\Exception\FireflyException;
|
||||
/**
|
||||
*
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's all 5. So ok.
|
||||
*
|
||||
* Class CategoryController
|
||||
*/
|
||||
@@ -106,6 +105,7 @@ class CategoryController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return $this
|
||||
* @throws FireflyException
|
||||
*/
|
||||
@@ -123,10 +123,11 @@ class CategoryController extends BaseController
|
||||
Session::flash('errors', $messages['errors']);
|
||||
if ($messages['errors']->count() > 0) {
|
||||
Session::flash('error', 'Could not store category: ' . $messages['errors']->first());
|
||||
return Redirect::route('categories.create')->withInput();
|
||||
}
|
||||
|
||||
// return to create screen:
|
||||
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
|
||||
if ($data['post_submit_action'] == 'validate_only') {
|
||||
return Redirect::route('categories.create')->withInput();
|
||||
}
|
||||
|
||||
@@ -141,6 +142,7 @@ class CategoryController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Category $category
|
||||
*
|
||||
* @return $this
|
||||
@@ -160,10 +162,11 @@ class CategoryController extends BaseController
|
||||
Session::flash('errors', $messages['errors']);
|
||||
if ($messages['errors']->count() > 0) {
|
||||
Session::flash('error', 'Could not update category: ' . $messages['errors']->first());
|
||||
return Redirect::route('categories.edit', $category->id)->withInput();
|
||||
}
|
||||
|
||||
// return to update screen:
|
||||
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
|
||||
if ($data['post_submit_action'] == 'validate_only') {
|
||||
return Redirect::route('categories.edit', $category->id)->withInput();
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ use FireflyIII\Database\TransactionCurrency\TransactionCurrency as Repository;
|
||||
/**
|
||||
*
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's all 5. So ok.
|
||||
*
|
||||
* Class CurrencyController
|
||||
*/
|
||||
@@ -123,6 +122,8 @@ class CurrencyController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @return $this|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store()
|
||||
@@ -174,10 +175,11 @@ class CurrencyController extends BaseController
|
||||
Session::flash('errors', $messages['errors']);
|
||||
if ($messages['errors']->count() > 0) {
|
||||
Session::flash('error', 'Could not update currency: ' . $messages['errors']->first());
|
||||
return Redirect::route('currency.edit', $currency->id)->withInput();
|
||||
}
|
||||
|
||||
// return to update screen:
|
||||
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
|
||||
if ($data['post_submit_action'] == 'validate_only') {
|
||||
return Redirect::route('currency.edit', $currency->id)->withInput();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,6 @@ use Grumpydictator\Gchart\GChart as GChart;
|
||||
/**
|
||||
* Class GoogleChartController
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
* @SuppressWarnings("TooManyMethods") // I'm also fine with this.
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's all 5. So ok.
|
||||
* @SuppressWarnings("MethodLength") // There is one with 45 lines and im gonna move it.
|
||||
* @SuppressWarnings("CouplingBetweenObjects") // There's only so much I can remove.
|
||||
*/
|
||||
class GoogleChartController extends BaseController
|
||||
{
|
||||
@@ -46,6 +42,7 @@ class GoogleChartController extends BaseController
|
||||
{
|
||||
$this->_chart->addColumn('Day of month', 'date');
|
||||
$this->_chart->addColumn('Balance for ' . $account->name, 'number');
|
||||
$this->_chart->addCertainty(1);
|
||||
|
||||
$start = $this->_start;
|
||||
$end = $this->_end;
|
||||
@@ -65,7 +62,7 @@ class GoogleChartController extends BaseController
|
||||
$current = clone $start;
|
||||
|
||||
while ($end >= $current) {
|
||||
$this->_chart->addRow(clone $current, Steam::balance($account, $current));
|
||||
$this->_chart->addRow(clone $current, Steam::balance($account, $current), false);
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
@@ -76,7 +73,7 @@ class GoogleChartController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* This method renders the b
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*/
|
||||
public function allAccountsBalanceChart()
|
||||
{
|
||||
@@ -88,19 +85,25 @@ class GoogleChartController extends BaseController
|
||||
|
||||
/** @var \FireflyIII\Database\Account\Account $acct */
|
||||
$acct = App::make('FireflyIII\Database\Account\Account');
|
||||
$accounts = count($pref->data) > 0 ? $acct->getByIds($pref->data) : $acct->getAssetAccounts();
|
||||
$accounts = count($pref->data) > 0 ? $acct->getByIds($pref->data) : $acct->getAccountsByType(['Default account', 'Asset account']);
|
||||
|
||||
$index = 1;
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$this->_chart->addColumn('Balance for ' . $account->name, 'number');
|
||||
$this->_chart->addCertainty($index);
|
||||
$index++;
|
||||
}
|
||||
$current = clone $this->_start;
|
||||
$current->subDay();
|
||||
|
||||
$today = Carbon::now();
|
||||
while ($this->_end >= $current) {
|
||||
$row = [clone $current];
|
||||
$row = [clone $current];
|
||||
$certain = $current < $today;
|
||||
foreach ($accounts as $account) {
|
||||
|
||||
$row[] = Steam::balance($account, $current);
|
||||
$row[] = $certain;
|
||||
}
|
||||
$this->_chart->addRowArray($row);
|
||||
$current->addDay();
|
||||
@@ -112,6 +115,49 @@ class GoogleChartController extends BaseController
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $year
|
||||
*
|
||||
* @return $this|\Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function allBudgetsAndSpending($year)
|
||||
{
|
||||
try {
|
||||
new Carbon('01-01-' . $year);
|
||||
} catch (Exception $e) {
|
||||
return View::make('error')->with('message', 'Invalid year.');
|
||||
}
|
||||
/** @var \FireflyIII\Database\Budget\Budget $budgetRepository */
|
||||
$budgetRepository = App::make('FireflyIII\Database\Budget\Budget');
|
||||
$budgets = $budgetRepository->get();
|
||||
$budgets->sortBy('name');
|
||||
$this->_chart->addColumn('Month', 'date');
|
||||
foreach ($budgets as $budget) {
|
||||
$this->_chart->addColumn($budget->name, 'number');
|
||||
}
|
||||
$start = Carbon::createFromDate(intval($year), 1, 1);
|
||||
$end = clone $start;
|
||||
$end->endOfYear();
|
||||
|
||||
|
||||
while ($start <= $end) {
|
||||
$row = [clone $start];
|
||||
foreach ($budgets as $budget) {
|
||||
$spent = $budgetRepository->spentInMonth($budget, $start);
|
||||
//$repetition = $budgetRepository->repetitionOnStartingOnDate($budget, $start);
|
||||
$row[] = $spent;
|
||||
}
|
||||
$this->_chart->addRowArray($row);
|
||||
$start->addMonth();
|
||||
}
|
||||
|
||||
|
||||
$this->_chart->generate();
|
||||
|
||||
return Response::json($this->_chart->getData());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
@@ -121,8 +167,6 @@ class GoogleChartController extends BaseController
|
||||
$this->_chart->addColumn('Budgeted', 'number');
|
||||
$this->_chart->addColumn('Spent', 'number');
|
||||
|
||||
Log::debug('Now in allBudgetsHomeChart()');
|
||||
|
||||
/** @var \FireflyIII\Database\Budget\Budget $bdt */
|
||||
$bdt = App::make('FireflyIII\Database\Budget\Budget');
|
||||
$budgets = $bdt->get();
|
||||
@@ -130,18 +174,13 @@ class GoogleChartController extends BaseController
|
||||
/** @var Budget $budget */
|
||||
foreach ($budgets as $budget) {
|
||||
|
||||
Log::debug('Now working budget #' . $budget->id . ', ' . $budget->name);
|
||||
|
||||
/** @var \LimitRepetition $repetition */
|
||||
$repetition = $bdt->repetitionOnStartingOnDate($budget, $this->_start);
|
||||
if (is_null($repetition)) {
|
||||
\Log::debug('Budget #' . $budget->id . ' has no repetition on ' . $this->_start->format('Y-m-d'));
|
||||
// use the session start and end for our search query
|
||||
if (is_null($repetition)) { // use the session start and end for our search query
|
||||
$searchStart = $this->_start;
|
||||
$searchEnd = $this->_end;
|
||||
$limit = 0; // the limit is zero:
|
||||
} else {
|
||||
\Log::debug('Budget #' . $budget->id . ' has a repetition on ' . $this->_start->format('Y-m-d') . '!');
|
||||
// use the limit's start and end for our search query
|
||||
$searchStart = $repetition->startdate;
|
||||
$searchEnd = $repetition->enddate;
|
||||
@@ -149,7 +188,6 @@ class GoogleChartController extends BaseController
|
||||
}
|
||||
|
||||
$expenses = floatval($budget->transactionjournals()->before($searchEnd)->after($searchStart)->lessThan(0)->sum('amount')) * -1;
|
||||
\Log::debug('Expenses in budget ' . $budget->name . ' before ' . $searchEnd->format('Y-m-d') . ' and after ' . $searchStart . ' are: ' . $expenses);
|
||||
if ($expenses > 0) {
|
||||
$this->_chart->addRow($budget->name, $limit, $expenses);
|
||||
}
|
||||
@@ -289,47 +327,56 @@ class GoogleChartController extends BaseController
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @param $year
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function budgetsAndSpending(Budget $budget, $year)
|
||||
public function budgetsAndSpending(Budget $budget, $year = 0)
|
||||
{
|
||||
try {
|
||||
new Carbon('01-01-' . $year);
|
||||
} catch (Exception $e) {
|
||||
return View::make('error')->with('message', 'Invalid year.');
|
||||
}
|
||||
|
||||
/** @var \FireflyIII\Database\Budget\Budget $budgetRepository */
|
||||
$budgetRepository = App::make('FireflyIII\Database\Budget\Budget');
|
||||
|
||||
$this->_chart->addColumn('Month', 'date');
|
||||
$this->_chart->addColumn('Budgeted', 'number');
|
||||
$this->_chart->addColumn('Spent', 'number');
|
||||
if ($year == 0) {
|
||||
// grab the first budgetlimit ever:
|
||||
$firstLimit = $budget->budgetlimits()->orderBy('startdate', 'ASC')->first();
|
||||
if ($firstLimit) {
|
||||
$start = new Carbon($firstLimit->startdate);
|
||||
} else {
|
||||
$start = Carbon::now()->startOfYear();
|
||||
}
|
||||
|
||||
// grab the last budget limit ever:
|
||||
$lastLimit = $budget->budgetlimits()->orderBy('startdate', 'DESC')->first();
|
||||
if ($lastLimit) {
|
||||
$end = new Carbon($lastLimit->startdate);
|
||||
} else {
|
||||
$end = Carbon::now()->endOfYear();
|
||||
}
|
||||
} else {
|
||||
$start = Carbon::createFromDate(intval($year), 1, 1);
|
||||
$end = clone $start;
|
||||
$end->endOfYear();
|
||||
}
|
||||
|
||||
|
||||
$start = new Carbon('01-01-' . $year);
|
||||
$end = clone $start;
|
||||
$end->endOfYear();
|
||||
while ($start <= $end) {
|
||||
$spent = $budgetRepository->spentInMonth($budget, $start);
|
||||
$repetition = $budgetRepository->repetitionOnStartingOnDate($budget, $start);
|
||||
|
||||
if ($repetition) {
|
||||
$budgeted = floatval($repetition->amount);
|
||||
\Log::debug('Found a repetition on ' . $start->format('Y-m-d'). ' for budget ' . $budget->name.'!');
|
||||
\Log::debug('Found a repetition on ' . $start->format('Y-m-d') . ' for budget ' . $budget->name . '!');
|
||||
} else {
|
||||
\Log::debug('No repetition on ' . $start->format('Y-m-d'). ' for budget ' . $budget->name);
|
||||
\Log::debug('No repetition on ' . $start->format('Y-m-d') . ' for budget ' . $budget->name);
|
||||
$budgeted = null;
|
||||
}
|
||||
|
||||
$this->_chart->addRow(clone $start, $budgeted, $spent);
|
||||
|
||||
$start->addMonth();
|
||||
}
|
||||
|
||||
|
||||
$this->_chart->generate();
|
||||
|
||||
return Response::json($this->_chart->getData());
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's all 5. So ok.
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
*
|
||||
* Class HelpController
|
||||
*
|
||||
*/
|
||||
class HelpController extends BaseController
|
||||
{
|
||||
@@ -14,41 +15,70 @@ class HelpController extends BaseController
|
||||
*/
|
||||
public function show($route)
|
||||
{
|
||||
$helpText = '<p>There is no help for this route!</p>';
|
||||
$helpTitle = 'Help';
|
||||
$content = [
|
||||
'text' => '<p>There is no help for this route!</p>',
|
||||
'title' => 'Help',
|
||||
];
|
||||
|
||||
if (!Route::has($route)) {
|
||||
\Log::error('No such route: ' . $route);
|
||||
|
||||
return Response::json(['title' => $helpTitle, 'text' => $helpText]);
|
||||
}
|
||||
if (Cache::has('help.' . $route . '.title') && Cache::has('help.' . $route . '.text')) {
|
||||
$helpText = Cache::get('help.' . $route . '.text');
|
||||
$helpTitle = Cache::get('help.' . $route . '.title');
|
||||
|
||||
return Response::json(['title' => $helpTitle, 'text' => $helpText]);
|
||||
return Response::json($content);
|
||||
}
|
||||
|
||||
$uri = 'https://raw.githubusercontent.com/JC5/firefly-iii-help/master/' . e($route) . '.md';
|
||||
\Log::debug('URL is: ' . $uri);
|
||||
if ($this->_inCache($route)) {
|
||||
$content = [
|
||||
'text' => Cache::get('help.' . $route . '.text'),
|
||||
'title' => Cache::get('help.' . $route . '.title'),
|
||||
];
|
||||
|
||||
return Response::json($content);
|
||||
}
|
||||
$content = $this->_getFromGithub($route);
|
||||
|
||||
|
||||
Cache::put('help.' . $route . '.text', $content['text'], 10080); // a week.
|
||||
Cache::put('help.' . $route . '.title', $content['title'], 10080);
|
||||
|
||||
return Response::json($content);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $route
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function _inCache($route)
|
||||
{
|
||||
return Cache::has('help.' . $route . '.title') && Cache::has('help.' . $route . '.text');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $route
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function _getFromGithub($route)
|
||||
{
|
||||
$uri = 'https://raw.githubusercontent.com/JC5/firefly-iii-help/master/' . e($route) . '.md';
|
||||
$content = [
|
||||
'text' => '<p>There is no help for this route!</p>',
|
||||
'title' => $route,
|
||||
];
|
||||
try {
|
||||
$helpText = file_get_contents($uri);
|
||||
$content['text'] = file_get_contents($uri);
|
||||
} catch (ErrorException $e) {
|
||||
\Log::error(trim($e->getMessage()));
|
||||
}
|
||||
\Log::debug('Found help for ' . $route);
|
||||
\Log::debug('Help text length for route ' . $route . ' is ' . strlen($helpText));
|
||||
\Log::debug('Help text IS: "' . $helpText . '".');
|
||||
if (strlen(trim($helpText)) == 0) {
|
||||
$helpText = '<p>There is no help for this route.</p>';
|
||||
if (strlen(trim($content['text'])) == 0) {
|
||||
$content['text'] = '<p>There is no help for this route.</p>';
|
||||
}
|
||||
$content['text'] = \Michelf\Markdown::defaultTransform($content['text']);
|
||||
|
||||
$helpText = \Michelf\Markdown::defaultTransform($helpText);
|
||||
$helpTitle = $route;
|
||||
return $content;
|
||||
|
||||
Cache::put('help.' . $route . '.text', $helpText, 10080); // a week.
|
||||
Cache::put('help.' . $route . '.title', $helpTitle, 10080);
|
||||
|
||||
return Response::json(['title' => $helpTitle, 'text' => $helpText]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ class HomeController extends BaseController
|
||||
/** @var \FireflyIII\Shared\Preferences\PreferencesInterface $preferences */
|
||||
$preferences = App::make('FireflyIII\Shared\Preferences\PreferencesInterface');
|
||||
|
||||
$count = $acct->countAssetAccounts();
|
||||
$count = $acct->countAccountsByType(['Default account', 'Asset account']);
|
||||
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
@@ -42,7 +42,7 @@ class HomeController extends BaseController
|
||||
// get the preference for the home accounts to show:
|
||||
$frontPage = $preferences->get('frontPageAccounts', []);
|
||||
if ($frontPage->data == []) {
|
||||
$accounts = $acct->getAssetAccounts();
|
||||
$accounts = $acct->getAccountsByType(['Default account', 'Asset account']);
|
||||
} else {
|
||||
$accounts = $acct->getByIds($frontPage->data);
|
||||
}
|
||||
@@ -77,8 +77,11 @@ class HomeController extends BaseController
|
||||
$preferences->set('viewRange', $range);
|
||||
Session::forget('range');
|
||||
}
|
||||
|
||||
return Redirect::intended('/');
|
||||
if (isset($_SERVER['HTTP_REFERER']) && (!strpos($_SERVER['HTTP_REFERER'], Config::get('app.url')) === false)) {
|
||||
return Redirect::back();
|
||||
} else {
|
||||
return Redirect::intended();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,7 +91,14 @@ class HomeController extends BaseController
|
||||
{
|
||||
Navigation::next();
|
||||
|
||||
return Redirect::intended('/');
|
||||
if (isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], Config::get('app.url')) === 0) {
|
||||
Log::debug('Redirect back');
|
||||
return Redirect::back();
|
||||
} else {
|
||||
Log::debug('Redirect intended');
|
||||
return Redirect::intended();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,6 +108,12 @@ class HomeController extends BaseController
|
||||
{
|
||||
Navigation::prev();
|
||||
|
||||
return Redirect::intended('/');
|
||||
if (isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], Config::get('app.url')) === 0) {
|
||||
Log::debug('Redirect back');
|
||||
return Redirect::back();
|
||||
} else {
|
||||
Log::debug('Redirect intended');
|
||||
return Redirect::intended();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ class JsonController extends BaseController
|
||||
{
|
||||
/** @var \FireflyIII\Database\Account\Account $accounts */
|
||||
$accounts = App::make('FireflyIII\Database\Account\Account');
|
||||
$list = $accounts->getExpenseAccounts();
|
||||
$list = $accounts->getAccountsByType(['Expense account', 'Beneficiary account']);
|
||||
$return = [];
|
||||
foreach ($list as $entry) {
|
||||
$return[] = $entry->name;
|
||||
@@ -53,7 +53,7 @@ class JsonController extends BaseController
|
||||
{
|
||||
/** @var \FireflyIII\Database\Account\Account $accounts */
|
||||
$accounts = App::make('FireflyIII\Database\Account\Account');
|
||||
$list = $accounts->getRevenueAccounts();
|
||||
$list = $accounts->getAccountsByType(['Revenue account']);
|
||||
$return = [];
|
||||
foreach ($list as $entry) {
|
||||
$return[] = $entry->name;
|
||||
|
||||
@@ -8,9 +8,6 @@ use Illuminate\Support\Collection;
|
||||
/**
|
||||
*
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's all 5. So ok.
|
||||
* @SuppressWarnings("TooManyMethods") // I'm also fine with this.
|
||||
* @SuppressWarnings("CouplingBetweenObjects") // There's only so much I can remove.
|
||||
*
|
||||
*
|
||||
* Class PiggyBankController
|
||||
@@ -62,7 +59,7 @@ class PiggyBankController extends BaseController
|
||||
$acct = App::make('FireflyIII\Database\Account\Account');
|
||||
|
||||
$periods = Config::get('firefly.piggy_bank_periods');
|
||||
$accounts = FFForm::makeSelectList($acct->getAssetAccounts());
|
||||
$accounts = FFForm::makeSelectList($acct->getAccountsByType(['Default account', 'Asset account']));
|
||||
$subTitle = 'Create new piggy bank';
|
||||
$subTitleIcon = 'fa-plus';
|
||||
|
||||
@@ -96,6 +93,8 @@ class PiggyBankController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return $this
|
||||
@@ -107,7 +106,7 @@ class PiggyBankController extends BaseController
|
||||
$acct = App::make('FireflyIII\Database\Account\Account');
|
||||
|
||||
$periods = Config::get('firefly.piggy_bank_periods');
|
||||
$accounts = FFForm::makeSelectList($acct->getAssetAccounts());
|
||||
$accounts = FFForm::makeSelectList($acct->getAccountsByType(['Default account', 'Asset account']));
|
||||
$subTitle = 'Edit piggy bank "' . e($piggyBank->name) . '"';
|
||||
$subTitleIcon = 'fa-pencil';
|
||||
|
||||
@@ -291,11 +290,12 @@ class PiggyBankController extends BaseController
|
||||
Session::flash('errors', $messages['errors']);
|
||||
if ($messages['errors']->count() > 0) {
|
||||
Session::flash('error', 'Could not store piggy bank: ' . $messages['errors']->first());
|
||||
return Redirect::route('piggy_banks.create')->withInput();
|
||||
}
|
||||
|
||||
|
||||
// return to create screen:
|
||||
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
|
||||
if ($data['post_submit_action'] == 'validate_only') {
|
||||
return Redirect::route('piggy_banks.create')->withInput();
|
||||
}
|
||||
|
||||
@@ -335,10 +335,11 @@ class PiggyBankController extends BaseController
|
||||
Session::flash('errors', $messages['errors']);
|
||||
if ($messages['errors']->count() > 0) {
|
||||
Session::flash('error', 'Could not update piggy bank: ' . $messages['errors']->first());
|
||||
return Redirect::route('piggy_banks.edit', $piggyBank->id)->withInput();
|
||||
}
|
||||
|
||||
// return to update screen:
|
||||
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
|
||||
if ($data['post_submit_action'] == 'validate_only') {
|
||||
return Redirect::route('piggy_banks.edit', $piggyBank->id)->withInput();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
/**
|
||||
* Class PreferencesController
|
||||
*
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's all 5. So ok.
|
||||
*
|
||||
*/
|
||||
class PreferencesController extends BaseController
|
||||
@@ -29,7 +28,7 @@ class PreferencesController extends BaseController
|
||||
/** @var \FireflyIII\Shared\Preferences\Preferences $preferences */
|
||||
$preferences = App::make('FireflyIII\Shared\Preferences\Preferences');
|
||||
|
||||
$accounts = $acct->getAssetAccounts();
|
||||
$accounts = $acct->getAccountsByType(['Default account', 'Asset account']);
|
||||
$viewRange = $preferences->get('viewRange', '1M');
|
||||
$viewRangeValue = $viewRange->data;
|
||||
$frontPage = $preferences->get('frontPageAccounts', []);
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's all 5. So ok.
|
||||
*
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
* Class ProfileController
|
||||
*/
|
||||
class ProfileController extends BaseController
|
||||
@@ -39,19 +38,9 @@ class ProfileController extends BaseController
|
||||
|
||||
return View::make('profile.change-password');
|
||||
}
|
||||
if (strlen(Input::get('new1')) == 0 || strlen(Input::get('new2')) == 0) {
|
||||
Session::flash('error', 'Do fill in a password!');
|
||||
|
||||
return View::make('profile.change-password');
|
||||
}
|
||||
if (Input::get('new1') == Input::get('old')) {
|
||||
Session::flash('error', 'The idea is to change your password.');
|
||||
|
||||
return View::make('profile.change-password');
|
||||
}
|
||||
|
||||
if (Input::get('new1') !== Input::get('new2')) {
|
||||
Session::flash('error', 'New passwords do not match!');
|
||||
$result = $this->_validatePassword(Input::get('old'), Input::get('new1'), Input::get('new2'));
|
||||
if (!($result === true)) {
|
||||
Session::flash('error', $result);
|
||||
|
||||
return View::make('profile.change-password');
|
||||
}
|
||||
@@ -66,4 +55,31 @@ class ProfileController extends BaseController
|
||||
return Redirect::route('profile');
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param string $old
|
||||
* @param string $new1
|
||||
* @param string $new2
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
protected function _validatePassword($old, $new1, $new2)
|
||||
{
|
||||
if (strlen($new1) == 0 || strlen($new2) == 0) {
|
||||
return 'Do fill in a password!';
|
||||
|
||||
}
|
||||
if ($new1 == $old) {
|
||||
return 'The idea is to change your password.';
|
||||
}
|
||||
|
||||
if ($new1 !== $new2) {
|
||||
return 'New passwords do not match!';
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ use FireflyIII\Helper\Related\RelatedInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
*
|
||||
* Class RelatedController
|
||||
*/
|
||||
class RelatedController extends BaseController
|
||||
@@ -10,6 +12,9 @@ class RelatedController extends BaseController
|
||||
|
||||
protected $_repository;
|
||||
|
||||
/**
|
||||
* @param RelatedInterface $repository
|
||||
*/
|
||||
public function __construct(RelatedInterface $repository)
|
||||
{
|
||||
$this->_repository = $repository;
|
||||
@@ -17,6 +22,8 @@ class RelatedController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
@@ -91,6 +98,8 @@ class RelatedController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param TransactionJournal $parentJournal
|
||||
* @param TransactionJournal $childJournal
|
||||
*
|
||||
|
||||
@@ -6,8 +6,6 @@ use FireflyIII\Exception\FireflyException;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's all 5. So ok.
|
||||
* @SuppressWarnings("CouplingBetweenObjects") // There's only so much I can remove.
|
||||
*
|
||||
* Class RepeatedExpenseController
|
||||
*/
|
||||
@@ -34,7 +32,7 @@ class RepeatedExpenseController extends BaseController
|
||||
/** @var \FireflyIII\Database\Account\Account $acct */
|
||||
$acct = App::make('FireflyIII\Database\Account\Account');
|
||||
$periods = Config::get('firefly.piggy_bank_periods');
|
||||
$accounts = FFForm::makeSelectList($acct->getAssetAccounts());
|
||||
$accounts = FFForm::makeSelectList($acct->getAccountsByType(['Default account', 'Asset account']));
|
||||
|
||||
return View::make('repeatedExpense.create', compact('accounts', 'periods'))->with('subTitle', 'Create new repeated expense')->with(
|
||||
'subTitleIcon', 'fa-plus'
|
||||
@@ -79,7 +77,7 @@ class RepeatedExpenseController extends BaseController
|
||||
$acct = App::make('FireflyIII\Database\Account\Account');
|
||||
|
||||
$periods = Config::get('firefly.piggy_bank_periods');
|
||||
$accounts = FFForm::makeSelectList($acct->getAssetAccounts());
|
||||
$accounts = FFForm::makeSelectList($acct->getAccountsByType(['Default account', 'Asset account']));
|
||||
$subTitle = 'Edit repeated expense "' . e($repeatedExpense->name) . '"';
|
||||
$subTitleIcon = 'fa-pencil';
|
||||
|
||||
@@ -137,7 +135,7 @@ class RepeatedExpenseController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*/
|
||||
public function store()
|
||||
{
|
||||
@@ -152,7 +150,6 @@ class RepeatedExpenseController extends BaseController
|
||||
$data['remind_me'] = isset($data['remind_me']) ? 1 : 0;
|
||||
$data['order'] = 0;
|
||||
|
||||
// always validate:
|
||||
$messages = $this->_repository->validate($data);
|
||||
|
||||
Session::flash('warnings', $messages['warnings']);
|
||||
@@ -160,11 +157,12 @@ class RepeatedExpenseController extends BaseController
|
||||
Session::flash('errors', $messages['errors']);
|
||||
if ($messages['errors']->count() > 0) {
|
||||
Session::flash('error', 'Could not store repeated expense: ' . $messages['errors']->first());
|
||||
return Redirect::route('repeated.create')->withInput();
|
||||
}
|
||||
|
||||
|
||||
// return to create screen:
|
||||
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
|
||||
if ($data['post_submit_action'] == 'validate_only') {
|
||||
return Redirect::route('repeated.create')->withInput();
|
||||
}
|
||||
|
||||
@@ -180,6 +178,8 @@ class RepeatedExpenseController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param PiggyBank $repeatedExpense
|
||||
*
|
||||
* @return $this
|
||||
@@ -196,7 +196,6 @@ class RepeatedExpenseController extends BaseController
|
||||
$data['remind_me'] = isset($data['remind_me']) ? 1 : 0;
|
||||
$data['user_id'] = Auth::user()->id;
|
||||
|
||||
// always validate:
|
||||
$messages = $this->_repository->validate($data);
|
||||
|
||||
Session::flash('warnings', $messages['warnings']);
|
||||
@@ -204,10 +203,11 @@ class RepeatedExpenseController extends BaseController
|
||||
Session::flash('errors', $messages['errors']);
|
||||
if ($messages['errors']->count() > 0) {
|
||||
Session::flash('error', 'Could not update repeated expense: ' . $messages['errors']->first());
|
||||
return Redirect::route('repeated.edit', $repeatedExpense->id)->withInput();
|
||||
}
|
||||
|
||||
// return to update screen:
|
||||
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
|
||||
if ($data['post_submit_action'] == 'validate_only') {
|
||||
return Redirect::route('repeated.edit', $repeatedExpense->id)->withInput();
|
||||
}
|
||||
|
||||
|
||||
@@ -48,13 +48,15 @@ class ReportController extends BaseController
|
||||
} catch (Exception $e) {
|
||||
return View::make('error')->with('message', 'Invalid date');
|
||||
}
|
||||
$date = new Carbon($year . '-' . $month . '-01');
|
||||
$dayEarly = clone $date;
|
||||
$dayEarly = $dayEarly->subDay();
|
||||
$accounts = $this->_repository->getAccountListBudgetOverview($date);
|
||||
$budgets = $this->_repository->getBudgetsForMonth($date);
|
||||
$date = new Carbon($year . '-' . $month . '-01');
|
||||
$dayEarly = clone $date;
|
||||
$subTitle = 'Budget report for ' . $date->format('F Y');
|
||||
$subTitleIcon = 'fa-calendar';
|
||||
$dayEarly = $dayEarly->subDay();
|
||||
$accounts = $this->_repository->getAccountListBudgetOverview($date);
|
||||
$budgets = $this->_repository->getBudgetsForMonth($date);
|
||||
|
||||
return View::make('reports.budget', compact('date', 'accounts', 'budgets', 'dayEarly'));
|
||||
return View::make('reports.budget', compact('subTitle', 'subTitleIcon', 'date', 'accounts', 'budgets', 'dayEarly'));
|
||||
|
||||
}
|
||||
|
||||
@@ -126,7 +128,8 @@ class ReportController extends BaseController
|
||||
$groupedExpenses = $this->_repository->expensesGroupedByAccount($date, $end, 15);
|
||||
|
||||
return View::make(
|
||||
'reports.year', compact('date', 'groupedIncomes', 'groupedExpenses', 'year', 'balances', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon')
|
||||
'reports.year',
|
||||
compact('date', 'groupedIncomes', 'groupedExpenses', 'year', 'balances', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,6 @@ use Illuminate\Support\Collection;
|
||||
/**
|
||||
*
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's all 5. So ok.
|
||||
* @SuppressWarnings("CouplingBetweenObjects") // There's only so much I can remove.
|
||||
* @SuppressWarnings("TooManyMethods") // I'm also fine with this.
|
||||
* @SuppressWarnings("ExcessiveClassComplexity")
|
||||
*
|
||||
* Class TransactionController
|
||||
*
|
||||
@@ -166,6 +162,8 @@ class TransactionController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's 7. More than 5 but alright.
|
||||
*
|
||||
* @param $what
|
||||
*
|
||||
* @return $this
|
||||
@@ -198,7 +196,6 @@ class TransactionController extends BaseController
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
@@ -235,6 +232,8 @@ class TransactionController extends BaseController
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param $what
|
||||
*
|
||||
* @return $this|\Illuminate\Http\RedirectResponse
|
||||
@@ -243,35 +242,31 @@ class TransactionController extends BaseController
|
||||
public function store($what)
|
||||
{
|
||||
$data = Input::except('_token');
|
||||
|
||||
$transactionType = $this->_repository->getJournalType($what);
|
||||
$transactionCurrency = $this->_repository->getJournalCurrency('EUR');
|
||||
$transactionCurrency = $this->_repository->getJournalCurrencyById(intval($data['amount_currency_id']));
|
||||
$data['transaction_type_id'] = $transactionType->id;
|
||||
$data['transaction_currency_id'] = $transactionCurrency->id;
|
||||
$data['completed'] = 0;
|
||||
$data['what'] = $what;
|
||||
$data['currency'] = 'EUR';
|
||||
|
||||
// always validate:
|
||||
$messages = $this->_repository->validate($data);
|
||||
$messages = $this->_repository->validate($data);
|
||||
|
||||
Session::flash('warnings', $messages['warnings']);
|
||||
Session::flash('successes', $messages['successes']);
|
||||
Session::flash('errors', $messages['errors']);
|
||||
if ($messages['errors']->count() > 0) {
|
||||
Session::flash('error', 'Could not store transaction: ' . $messages['errors']->first());
|
||||
}
|
||||
|
||||
// return to create screen:
|
||||
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
|
||||
return Redirect::route('transactions.create', $data['what'])->withInput();
|
||||
}
|
||||
|
||||
// store
|
||||
if ($data['post_submit_action'] == 'validate_only') {
|
||||
return Redirect::route('transactions.create', $data['what'])->withInput();
|
||||
}
|
||||
|
||||
$journal = $this->_repository->store($data);
|
||||
Event::fire('transactionJournal.store', [$journal, Input::get('piggy_bank_id')]); // new and used.
|
||||
/*
|
||||
* Also trigger on both transactions.
|
||||
*/
|
||||
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($journal->transactions as $transaction) {
|
||||
Event::fire('transaction.store', [$transaction]);
|
||||
@@ -295,10 +290,9 @@ class TransactionController extends BaseController
|
||||
public function update(TransactionJournal $journal)
|
||||
{
|
||||
$data = Input::except('_token');
|
||||
$data['currency'] = 'EUR';
|
||||
$data['what'] = strtolower($journal->transactionType->type);
|
||||
$data['transaction_type_id'] = $journal->transaction_type_id;
|
||||
$data['transaction_currency_id'] = $journal->transaction_currency_id;
|
||||
$data['transaction_currency_id'] = intval($data['amount_currency_id']);
|
||||
$data['completed'] = 1;
|
||||
$messages = $this->_repository->validate($data);
|
||||
|
||||
@@ -307,8 +301,10 @@ class TransactionController extends BaseController
|
||||
Session::flash('errors', $messages['errors']);
|
||||
if ($messages['errors']->count() > 0) {
|
||||
Session::flash('error', 'Could not update transaction: ' . $messages['errors']->first());
|
||||
|
||||
return Redirect::route('transactions.edit', $journal->id)->withInput();
|
||||
}
|
||||
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
|
||||
if ($data['post_submit_action'] == 'validate_only') {
|
||||
return Redirect::route('transactions.edit', $journal->id)->withInput();
|
||||
}
|
||||
$this->_repository->update($journal, $data);
|
||||
|
||||
@@ -77,7 +77,12 @@ class UserController extends BaseController
|
||||
$user = $repository->register(Input::all());
|
||||
|
||||
if ($user) {
|
||||
$email->sendVerificationMail($user);
|
||||
$result = $email->sendVerificationMail($user);
|
||||
if ($result === false && Config::get('mail.pretend') === false) {
|
||||
$user->delete();
|
||||
|
||||
return View::make('error')->with('message', 'The email message could not be send. See the log files.');
|
||||
}
|
||||
|
||||
return View::make('user.verification-pending');
|
||||
}
|
||||
@@ -121,6 +126,11 @@ class UserController extends BaseController
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
if ((Config::get('mail.from.address') == '@gmail.com' || Config::get('mail.from.address') == '')
|
||||
&& Config::get('mail.pretend') === false
|
||||
) {
|
||||
return View::make('error')->with('message', 'Configuration error in <code>app/config/' . App::environment() . '/mail.php</code>');
|
||||
}
|
||||
|
||||
return View::make('user.register');
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateUsersTable
|
||||
*/
|
||||
class CreateUsersTable extends Migration
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateAccountTypesTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateAccountsTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateComponentsTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreatePiggybanksTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateTransactionCurrenciesTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateTransactionTypesTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateRecurringTransactionsTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateTransactionJournalsTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateTransactionsTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateComponentTransactionTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateComponentTransactionJournalTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreatePreferencesTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateSessionTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,9 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)\
|
||||
*
|
||||
*
|
||||
* Class CreateLimitsTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateLimitRepeatTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateComponentRecurringTransactionTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreatePiggyInstance
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreatePiggybankEventsTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateRemindersTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateAccountMetaTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,8 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
*
|
||||
* Class CreateTransactionGroupsTable
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -5,6 +5,9 @@ use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName) // method names are mandated by laravel.
|
||||
* @SuppressWarnings("TooManyMethods") // I'm fine with this
|
||||
*
|
||||
* Down:
|
||||
* 1. Create new Components based on Budgets.
|
||||
* 2. Create new Components based on Categories
|
||||
|
||||
@@ -4,6 +4,10 @@ use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
* @SuppressWarnings("MethodLength") // I don't mind this in case of migrations.
|
||||
|
||||
*
|
||||
* Class ChangesForV322
|
||||
*/
|
||||
class ChangesForV322 extends Migration
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||
* @SuppressWarnings("MethodLength") // I don't mind this in case of migrations.
|
||||
*
|
||||
* Class ChangesForV325
|
||||
*/
|
||||
class ChangesForV325 extends Migration
|
||||
{
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
//
|
||||
|
||||
// delete an old index:
|
||||
try {
|
||||
Schema::table(
|
||||
'budget_limits', function (Blueprint $table) {
|
||||
//$table->dropIndex('unique_ci_combo');
|
||||
$table->dropUnique('unique_ci_combi');
|
||||
|
||||
}
|
||||
);
|
||||
} catch (QueryException $e) {
|
||||
// don't care.
|
||||
} catch (PDOException $e) {
|
||||
// don't care.
|
||||
} catch (\Exception $e) {
|
||||
// don't care either.
|
||||
}
|
||||
|
||||
// allow journal descriptions to be encrypted.
|
||||
Schema::table(
|
||||
'transaction_journals', function (Blueprint $table) {
|
||||
$table->boolean('encrypted')->default(0);
|
||||
|
||||
}
|
||||
);
|
||||
try {
|
||||
DB::update('ALTER TABLE `transaction_journals` MODIFY `description` VARCHAR(1024)');
|
||||
} catch (QueryException $e) {
|
||||
// don't care.
|
||||
} catch (PDOException $e) {
|
||||
// don't care.
|
||||
} catch (\Exception $e) {
|
||||
// don't care either.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,31 +10,14 @@ class AccountTypeSeeder extends Seeder
|
||||
{
|
||||
DB::table('account_types')->delete();
|
||||
|
||||
AccountType::create(
|
||||
['type' => 'Default account', 'editable' => true]
|
||||
);
|
||||
AccountType::create(
|
||||
['type' => 'Cash account', 'editable' => false]
|
||||
);
|
||||
AccountType::create(
|
||||
['type' => 'Asset account', 'editable' => true]
|
||||
);
|
||||
AccountType::create(
|
||||
['type' => 'Expense account', 'editable' => true]
|
||||
);
|
||||
AccountType::create(
|
||||
['type' => 'Revenue account', 'editable' => true]
|
||||
);
|
||||
AccountType::create(
|
||||
['type' => 'Initial balance account', 'editable' => false]
|
||||
);
|
||||
AccountType::create(
|
||||
['type' => 'Beneficiary account', 'editable' => true]
|
||||
);
|
||||
|
||||
AccountType::create(
|
||||
['type' => 'Import account', 'editable' => false]
|
||||
);
|
||||
AccountType::create(['type' => 'Default account', 'editable' => true]);
|
||||
AccountType::create(['type' => 'Cash account', 'editable' => false]);
|
||||
AccountType::create(['type' => 'Asset account', 'editable' => true]);
|
||||
AccountType::create(['type' => 'Expense account', 'editable' => true]);
|
||||
AccountType::create(['type' => 'Revenue account', 'editable' => true]);
|
||||
AccountType::create(['type' => 'Initial balance account', 'editable' => false]);
|
||||
AccountType::create(['type' => 'Beneficiary account', 'editable' => true]);
|
||||
AccountType::create(['type' => 'Import account', 'editable' => false]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,8 +18,10 @@ class DatabaseSeeder extends Seeder
|
||||
$this->call('AccountTypeSeeder');
|
||||
$this->call('TransactionCurrencySeeder');
|
||||
$this->call('TransactionTypeSeeder');
|
||||
$this->call('DefaultUserSeeder');
|
||||
$this->call('TestContentSeeder');
|
||||
|
||||
if (App::environment() == 'testing') {
|
||||
$this->call('TestDataSeeder');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class DefaultUserSeeder
|
||||
*/
|
||||
class DefaultUserSeeder extends Seeder
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
DB::table('users')->delete();
|
||||
if (App::environment() == 'testing' || App::environment() == 'homestead') {
|
||||
|
||||
User::create(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james', 'reset' => null, 'remember_token' => null]);
|
||||
User::create(['email' => 'acceptance@example.com', 'password' => 'acceptance', 'reset' => null, 'remember_token' => null]);
|
||||
User::create(['email' => 'functional@example.com', 'password' => 'functional', 'reset' => null, 'remember_token' => null]);
|
||||
User::create(['email' => 'reset@example.com', 'password' => 'functional', 'reset' => 'okokokokokokokokokokokokokokokok', 'remember_token' => null]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +1,15 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
|
||||
/**
|
||||
*
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
* @SuppressWarnings("TooManyMethods") // I'm fine with this
|
||||
* @SuppressWarnings("CouplingBetweenObjects") // I'm fine with this
|
||||
* @SuppressWarnings("MethodLength") // I'm fine with this
|
||||
*
|
||||
* Class TestContentSeeder
|
||||
* Class TestDataSeeder
|
||||
*/
|
||||
class TestContentSeeder extends Seeder
|
||||
class TestDataSeeder extends Seeder
|
||||
{
|
||||
/** @var string */
|
||||
public $eom;
|
||||
@@ -72,87 +73,123 @@ class TestContentSeeder extends Seeder
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
if (App::environment() == 'testing' || App::environment() == 'homestead') {
|
||||
|
||||
$user = User::whereEmail('thegrumpydictator@gmail.com')->first();
|
||||
|
||||
// create initial accounts and various other stuff:
|
||||
$this->createAssetAccounts($user);
|
||||
$this->createBudgets($user);
|
||||
$this->createCategories($user);
|
||||
$this->createPiggyBanks($user);
|
||||
$this->createReminders($user);
|
||||
$this->createRecurringTransactions($user);
|
||||
$this->createBills($user);
|
||||
$this->createExpenseAccounts($user);
|
||||
$this->createRevenueAccounts($user);
|
||||
|
||||
// get some objects from the database:
|
||||
$checking = Account::whereName('Checking account')->orderBy('id', 'DESC')->first();
|
||||
$savings = Account::whereName('Savings account')->orderBy('id', 'DESC')->first();
|
||||
$landLord = Account::whereName('Land lord')->orderBy('id', 'DESC')->first();
|
||||
$utilities = Account::whereName('Utilities company')->orderBy('id', 'DESC')->first();
|
||||
$television = Account::whereName('TV company')->orderBy('id', 'DESC')->first();
|
||||
$phone = Account::whereName('Phone agency')->orderBy('id', 'DESC')->first();
|
||||
$employer = Account::whereName('Employer')->orderBy('id', 'DESC')->first();
|
||||
User::create(['email' => 'reset@example.com', 'password' => 'functional', 'reset' => 'okokokokokokokokokokokokokokokok', 'remember_token' => null]);
|
||||
User::create(['email' => 'functional@example.com', 'password' => 'functional', 'reset' => null, 'remember_token' => null]);
|
||||
|
||||
|
||||
$bills = Budget::whereName('Bills')->orderBy('id', 'DESC')->first();
|
||||
$groceries = Budget::whereName('Groceries')->orderBy('id', 'DESC')->first();
|
||||
$user = User::create(['email' => 'thegrumpydictator@gmail.com', 'password' => 'james', 'reset' => null, 'remember_token' => null]);
|
||||
Log::debug('Created users.');
|
||||
// create initial accounts and various other stuff:
|
||||
$this->createAssetAccounts($user);
|
||||
Log::debug('Created asset accounts.');
|
||||
$this->createBudgets($user);
|
||||
Log::debug('Created budgets.');
|
||||
$this->createCategories($user);
|
||||
Log::debug('Created categories.');
|
||||
$this->createPiggyBanks($user);
|
||||
Log::debug('Created piggy banks.');
|
||||
$this->createReminders($user);
|
||||
Log::debug('Created reminders.');
|
||||
$this->createRecurringTransactions($user);
|
||||
Log::debug('Created recurring transactions.');
|
||||
$this->createBills($user);
|
||||
Log::debug('Created bills.');
|
||||
$this->createExpenseAccounts($user);
|
||||
Log::debug('Created expense accounts.');
|
||||
$this->createRevenueAccounts($user);
|
||||
Log::debug('Created revenue accounts.');
|
||||
|
||||
$house = Category::whereName('House')->orderBy('id', 'DESC')->first();
|
||||
// get some objects from the database:
|
||||
$checking = Account::whereName('Checking account')->orderBy('id', 'DESC')->first();
|
||||
Log::debug('Found checking: ' . json_encode($checking));
|
||||
$savings = Account::whereName('Savings account')->orderBy('id', 'DESC')->first();
|
||||
Log::debug('Found savings: ' . json_encode($savings));
|
||||
$landLord = Account::whereName('Land lord')->orderBy('id', 'DESC')->first();
|
||||
Log::debug('Found landlord: ' . json_encode($landLord));
|
||||
$utilities = Account::whereName('Utilities company')->orderBy('id', 'DESC')->first();
|
||||
Log::debug('Found utilities: ' . json_encode($utilities));
|
||||
$television = Account::whereName('TV company')->orderBy('id', 'DESC')->first();
|
||||
Log::debug('Found tv company: ' . json_encode($television));
|
||||
$phone = Account::whereName('Phone agency')->orderBy('id', 'DESC')->first();
|
||||
Log::debug('Found phone company: ' . json_encode($phone));
|
||||
$employer = Account::whereName('Employer')->orderBy('id', 'DESC')->first();
|
||||
Log::debug('Found employer: ' . json_encode($employer));
|
||||
|
||||
|
||||
$withdrawal = TransactionType::whereType('Withdrawal')->first();
|
||||
$deposit = TransactionType::whereType('Deposit')->first();
|
||||
$transfer = TransactionType::whereType('Transfer')->first();
|
||||
$bills = Budget::whereName('Bills')->orderBy('id', 'DESC')->first();
|
||||
Log::debug('Found bills budget: ' . json_encode($bills));
|
||||
$groceries = Budget::whereName('Groceries')->orderBy('id', 'DESC')->first();
|
||||
Log::debug('Found groceries budget: ' . json_encode($groceries));
|
||||
|
||||
$euro = TransactionCurrency::whereCode('EUR')->first();
|
||||
|
||||
$rentBill = Bill::where('name', 'Rent')->first();
|
||||
$house = Category::whereName('House')->orderBy('id', 'DESC')->first();
|
||||
Log::debug('Found house category: ' . json_encode($checking));
|
||||
|
||||
|
||||
$current = clone $this->_yearAgoStartOfMonth;
|
||||
while ($current <= $this->_startOfMonth) {
|
||||
$cur = $current->format('Y-m-d');
|
||||
$formatted = $current->format('F Y');
|
||||
$withdrawal = TransactionType::whereType('Withdrawal')->first();
|
||||
Log::debug('Found withdrawal: ' . json_encode($withdrawal));
|
||||
$deposit = TransactionType::whereType('Deposit')->first();
|
||||
Log::debug('Found deposit: ' . json_encode($deposit));
|
||||
$transfer = TransactionType::whereType('Transfer')->first();
|
||||
Log::debug('Found transfer: ' . json_encode($transfer));
|
||||
|
||||
// create expenses for rent, utilities, TV, phone on the 1st of the month.
|
||||
$this->createTransaction($checking, $landLord, 800, $withdrawal, 'Rent for ' . $formatted, $cur, $euro, $bills, $house, $rentBill);
|
||||
$this->createTransaction($checking, $utilities, 150, $withdrawal, 'Utilities for ' . $formatted, $cur, $euro, $bills, $house);
|
||||
$this->createTransaction($checking, $television, 50, $withdrawal, 'TV for ' . $formatted, $cur, $euro, $bills, $house);
|
||||
$this->createTransaction($checking, $phone, 50, $withdrawal, 'Phone bill for ' . $formatted, $cur, $euro, $bills, $house);
|
||||
$euro = TransactionCurrency::whereCode('EUR')->first();
|
||||
Log::debug('Found euro: ' . json_encode($euro));
|
||||
|
||||
// two transactions. One without a budget, one without a category.
|
||||
$this->createTransaction($checking, $phone, 10, $withdrawal, 'Extra charges on phone bill for ' . $formatted, $cur, $euro, null, $house);
|
||||
$this->createTransaction($checking, $television, 5, $withdrawal, 'Extra charges on TV bill for ' . $formatted, $cur, $euro, $bills, null);
|
||||
|
||||
// income from job:
|
||||
$this->createTransaction($employer, $checking, rand(3500, 4000), $deposit, 'Salary for ' . $formatted, $cur, $euro);
|
||||
$this->createTransaction($checking, $savings, 2000, $transfer, 'Salary to savings account in ' . $formatted, $cur, $euro);
|
||||
|
||||
$this->createGroceries($current);
|
||||
$this->createBigExpense(clone $current);
|
||||
|
||||
echo 'Created test-content for ' . $current->format('F Y') . "\n";
|
||||
$current->addMonth();
|
||||
}
|
||||
$rentBill = Bill::where('name', 'Rent')->first();
|
||||
Log::debug('Found bill "rent": ' . json_encode($rentBill));
|
||||
|
||||
|
||||
// piggy bank event
|
||||
// add money to this piggy bank
|
||||
// create a piggy bank event to match:
|
||||
$piggyBank = PiggyBank::whereName('New camera')->orderBy('id', 'DESC')->first();
|
||||
$intoPiggy = $this->createTransaction($checking, $savings, 100, $transfer, 'Money for piggy', $this->yaeom, $euro, $groceries, $house);
|
||||
PiggyBankEvent::create(
|
||||
[
|
||||
'piggy_bank_id' => $piggyBank->id,
|
||||
'transaction_journal_id' => $intoPiggy->id,
|
||||
'date' => $this->yaeom,
|
||||
'amount' => 100
|
||||
]
|
||||
);
|
||||
$current = clone $this->_yearAgoStartOfMonth;
|
||||
while ($current <= $this->_startOfMonth) {
|
||||
$cur = $current->format('Y-m-d');
|
||||
$formatted = $current->format('F Y');
|
||||
Log::debug('Now at: ' . $cur);
|
||||
|
||||
// create expenses for rent, utilities, TV, phone on the 1st of the month.
|
||||
$this->createTransaction($checking, $landLord, 800, $withdrawal, 'Rent for ' . $formatted, $cur, $euro, $bills, $house, $rentBill);
|
||||
Log::debug('Created rent.');
|
||||
$this->createTransaction($checking, $utilities, 150, $withdrawal, 'Utilities for ' . $formatted, $cur, $euro, $bills, $house);
|
||||
Log::debug('Created utilities.');
|
||||
$this->createTransaction($checking, $television, 50, $withdrawal, 'TV for ' . $formatted, $cur, $euro, $bills, $house);
|
||||
Log::debug('Created TV.');
|
||||
$this->createTransaction($checking, $phone, 50, $withdrawal, 'Phone bill for ' . $formatted, $cur, $euro, $bills, $house);
|
||||
Log::debug('Created phone bill.');
|
||||
|
||||
// two transactions. One without a budget, one without a category.
|
||||
$this->createTransaction($checking, $phone, 10, $withdrawal, 'Extra charges on phone bill for ' . $formatted, $cur, $euro, null, $house);
|
||||
Log::debug('Created extra charges no budget.');
|
||||
$this->createTransaction($checking, $television, 5, $withdrawal, 'Extra charges on TV bill for ' . $formatted, $cur, $euro, $bills, null);
|
||||
Log::debug('Created extra charges no category.');
|
||||
|
||||
// income from job:
|
||||
$this->createTransaction($employer, $checking, rand(3500, 4000), $deposit, 'Salary for ' . $formatted, $cur, $euro);
|
||||
Log::debug('Created income.');
|
||||
$this->createTransaction($checking, $savings, 2000, $transfer, 'Salary to savings account in ' . $formatted, $cur, $euro);
|
||||
Log::debug('Created savings.');
|
||||
|
||||
$this->createGroceries($current);
|
||||
Log::debug('Created groceries range.');
|
||||
$this->createBigExpense(clone $current);
|
||||
Log::debug('Created big expense.');
|
||||
|
||||
echo 'Created test-content for ' . $current->format('F Y') . "\n";
|
||||
$current->addMonth();
|
||||
}
|
||||
|
||||
|
||||
// piggy bank event
|
||||
// add money to this piggy bank
|
||||
// create a piggy bank event to match:
|
||||
$piggyBank = PiggyBank::whereName('New camera')->orderBy('id', 'DESC')->first();
|
||||
$intoPiggy = $this->createTransaction($checking, $savings, 100, $transfer, 'Money for piggy', $this->yaeom, $euro, $groceries, $house);
|
||||
PiggyBankEvent::create(
|
||||
[
|
||||
'piggy_bank_id' => $piggyBank->id,
|
||||
'transaction_journal_id' => $intoPiggy->id,
|
||||
'date' => $this->yaeom,
|
||||
'amount' => 100
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,6 +218,9 @@ class TestContentSeeder extends Seeder
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ShortVariable)
|
||||
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
|
||||
*
|
||||
* @param Account $from
|
||||
* @param Account $to
|
||||
* @param $amount
|
||||
@@ -202,15 +242,24 @@ class TestContentSeeder extends Seeder
|
||||
$user = User::whereEmail('thegrumpydictator@gmail.com')->first();
|
||||
|
||||
$billID = is_null($bill) ? null : $bill->id;
|
||||
|
||||
Log::debug('String length of encrypted description ("'.$description.'") is: ' . strlen(Crypt::encrypt($description)));
|
||||
|
||||
/** @var TransactionJournal $journal */
|
||||
$journal = TransactionJournal::create(
|
||||
[
|
||||
'user_id' => $user->id, 'transaction_type_id' => $type->id, 'transaction_currency_id' => $currency->id, 'bill_id' => $billID,
|
||||
'description' => $description, 'completed' => 1, 'date' => $date
|
||||
'user_id' => $user->id,
|
||||
'transaction_type_id' => $type->id,
|
||||
'transaction_currency_id' => $currency->id,
|
||||
'bill_id' => $billID,
|
||||
'description' => $description,
|
||||
'completed' => 1,
|
||||
'date' => $date
|
||||
]
|
||||
);
|
||||
//Log::debug('Journal valid: ' . Steam::boolString($journal->isValid()));
|
||||
//Log::debug('Journal errors: ' . json_encode($journal->getErrors()));
|
||||
//Log::debug('Journal created: ' . json_encode($journal));
|
||||
|
||||
|
||||
Transaction::create(['account_id' => $from->id, 'transaction_journal_id' => $journal->id, 'amount' => $amount * -1]);
|
||||
Transaction::create(['account_id' => $to->id, 'transaction_journal_id' => $journal->id, 'amount' => $amount]);
|
||||
@@ -411,16 +460,8 @@ class TestContentSeeder extends Seeder
|
||||
{
|
||||
// bill
|
||||
Bill::create(
|
||||
[
|
||||
'user_id' => $user->id, 'name' => 'Rent', 'match' => 'rent,landlord',
|
||||
'amount_min' => 700,
|
||||
'amount_max' => 900,
|
||||
'date' => $this->som,
|
||||
'active' => 1,
|
||||
'automatch' => 1,
|
||||
'repeat_freq' => 'monthly',
|
||||
'skip' => 0,
|
||||
]
|
||||
['user_id' => $user->id, 'name' => 'Rent', 'match' => 'rent,landlord', 'amount_min' => 700, 'amount_max' => 900, 'date' => $this->som,
|
||||
'active' => 1, 'automatch' => 1, 'repeat_freq' => 'monthly', 'skip' => 0,]
|
||||
);
|
||||
|
||||
// bill
|
||||
@@ -429,13 +470,10 @@ class TestContentSeeder extends Seeder
|
||||
'user_id' => $user->id,
|
||||
'name' => 'Gas licht',
|
||||
'match' => 'no,match',
|
||||
'amount_min' => 500,
|
||||
'amount_max' => 700,
|
||||
'amount_min' => 500, 'amount_max' => 700,
|
||||
'date' => $this->som,
|
||||
'active' => 1,
|
||||
'automatch' => 1,
|
||||
'repeat_freq' => 'monthly',
|
||||
'skip' => 0,
|
||||
'active' => 1, 'automatch' => 1,
|
||||
'repeat_freq' => 'monthly', 'skip' => 0,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -557,5 +595,8 @@ class TestContentSeeder extends Seeder
|
||||
);
|
||||
$group->transactionjournals()->save($one);
|
||||
$group->transactionjournals()->save($two);
|
||||
$group->save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -41,47 +41,6 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
return $this->getUser()->accounts()->accountTypeIn($types)->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function countAssetAccounts()
|
||||
{
|
||||
return $this->countAccountsByType(['Default account', 'Asset account']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function countExpenseAccounts()
|
||||
{
|
||||
return $this->countAccountsByType(['Expense account', 'Beneficiary account']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of total revenue accounts. Useful for DataTables.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countRevenueAccounts()
|
||||
{
|
||||
return $this->countAccountsByType(['Revenue account']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Account $account
|
||||
*
|
||||
* @return \Account|null
|
||||
*/
|
||||
public function findInitialBalanceAccount(\Account $account)
|
||||
{
|
||||
/** @var \FireflyIII\Database\AccountType\AccountType $acctType */
|
||||
$acctType = \App::make('FireflyIII\Database\AccountType\AccountType');
|
||||
|
||||
$accountType = $acctType->findByWhat('initial');
|
||||
|
||||
return $this->getUser()->accounts()->where('account_type_id', $accountType->id)->where('name', 'LIKE', $account->name . '%')->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $types
|
||||
*
|
||||
@@ -93,7 +52,7 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
* Basic query:
|
||||
*/
|
||||
$query = $this->getUser()->accounts()->accountTypeIn($types)->withMeta()->orderBy('name', 'ASC');;
|
||||
$set = $query->get(['accounts.*']);
|
||||
$set = $query->get(['accounts.*', 'account_meta.data as accountRole']);
|
||||
|
||||
$set->each(
|
||||
function (\Account $account) {
|
||||
@@ -101,63 +60,13 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
* Get last activity date.
|
||||
*/
|
||||
$account->lastActivityDate = $this->getLastActivity($account);
|
||||
$account->accountRole = \Config::get('firefly.accountRoles.' . json_decode($account->accountRole));
|
||||
}
|
||||
);
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all asset accounts. Optional JSON based parameters.
|
||||
*
|
||||
* @param array $metaFilter
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAssetAccounts($metaFilter = [])
|
||||
{
|
||||
$list = $this->getAccountsByType(['Default account', 'Asset account']);
|
||||
$list->each(
|
||||
function (\Account $account) {
|
||||
|
||||
// get accountRole:
|
||||
|
||||
/** @var \AccountMeta $entry */
|
||||
$accountRole = $account->accountmeta()->whereName('accountRole')->first();
|
||||
if (!$accountRole) {
|
||||
$accountRole = new \AccountMeta;
|
||||
$accountRole->account_id = $account->id;
|
||||
$accountRole->name = 'accountRole';
|
||||
$accountRole->data = 'defaultExpense';
|
||||
$accountRole->save();
|
||||
|
||||
}
|
||||
$account->accountRole = $accountRole->data;
|
||||
}
|
||||
);
|
||||
|
||||
return $list;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getExpenseAccounts()
|
||||
{
|
||||
return $this->getAccountsByType(['Expense account', 'Beneficiary account']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all revenue accounts.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getRevenueAccounts()
|
||||
{
|
||||
return $this->getAccountsByType(['Revenue account']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Account $account
|
||||
*
|
||||
@@ -180,51 +89,32 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
{
|
||||
$opposingData = ['name' => $account->name . ' Initial Balance', 'active' => 0, 'what' => 'initial'];
|
||||
$opposingAccount = $this->store($opposingData);
|
||||
|
||||
/*
|
||||
* Create a journal from opposing to account or vice versa.
|
||||
*/
|
||||
$balance = floatval($data['openingbalance']);
|
||||
$date = new Carbon($data['openingbalancedate']);
|
||||
/** @var \FireflyIII\Database\TransactionJournal\TransactionJournal $tj */
|
||||
$tj = \App::make('FireflyIII\Database\TransactionJournal\TransactionJournal');
|
||||
$balance = floatval($data['openingBalance']);
|
||||
$date = new Carbon($data['openingBalanceDate']);
|
||||
/** @var \FireflyIII\Database\TransactionJournal\TransactionJournal $journals */
|
||||
$journals = \App::make('FireflyIII\Database\TransactionJournal\TransactionJournal');
|
||||
$fromAccount = $opposingAccount;
|
||||
$toAccount = $account;
|
||||
if ($balance < 0) {
|
||||
// first transaction draws money from the new account to the opposing
|
||||
$from = $account;
|
||||
$to = $opposingAccount;
|
||||
} else {
|
||||
// first transaction puts money into account
|
||||
$from = $opposingAccount;
|
||||
$to = $account;
|
||||
$fromAccount = $account;
|
||||
$toAccount = $opposingAccount;
|
||||
}
|
||||
|
||||
// data for transaction journal:
|
||||
$balance = $balance < 0 ? $balance * -1 : $balance;
|
||||
|
||||
// find the account type:
|
||||
/** @var \FireflyIII\Database\TransactionType\TransactionType $typeRepository */
|
||||
$typeRepository = \App::make('FireflyIII\Database\TransactionType\TransactionType');
|
||||
$type = $typeRepository->findByWhat('opening');
|
||||
$currency = $journals->getJournalCurrencyById(intval($data['balance_currency_id']));
|
||||
//$currency = \Amount::getDefaultCurrency();
|
||||
|
||||
// find the currency.
|
||||
$currency = \Amount::getDefaultCurrency();
|
||||
$opening = ['transaction_type_id' => $type->id, 'transaction_currency_id' => $currency->id, 'amount' => $balance, 'from' => $fromAccount,
|
||||
'completed' => 0, 'what' => 'opening', 'to' => $toAccount, 'date' => $date,
|
||||
'description' => 'Opening balance for new account ' . $account->name,];
|
||||
|
||||
$opening = [
|
||||
'transaction_type_id' => $type->id,
|
||||
'transaction_currency_id' => $currency->id,
|
||||
'amount' => $balance,
|
||||
'from' => $from,
|
||||
'completed' => 0,
|
||||
'currency' => 'EUR',
|
||||
'what' => 'opening',
|
||||
'to' => $to,
|
||||
'date' => $date,
|
||||
'description' => 'Opening balance for new account ' . $account->name,];
|
||||
|
||||
|
||||
$validation = $tj->validate($opening);
|
||||
$validation = $journals->validate($opening);
|
||||
if ($validation['errors']->count() == 0) {
|
||||
$tj->store($opening);
|
||||
$journals->store($opening);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
@@ -233,45 +123,68 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
\App::abort(500);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Account $account
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLastActivity(\Account $account)
|
||||
{
|
||||
$lastActivityKey = 'account.' . $account->id . '.lastActivityDate';
|
||||
if (\Cache::has($lastActivityKey)) {
|
||||
return \Cache::get($lastActivityKey);
|
||||
}
|
||||
|
||||
$transaction = $account->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->orderBy('transaction_journals.date', 'DESC')->first();
|
||||
if ($transaction) {
|
||||
$date = $transaction->transactionJournal->date;
|
||||
} else {
|
||||
$date = 0;
|
||||
}
|
||||
\Cache::forever($lastActivityKey, $date);
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.ExcessiveMethodLength) // cannot make it shorter because of query.
|
||||
* @param Eloquent $model
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function destroy(Eloquent $model)
|
||||
{
|
||||
|
||||
// delete piggy banks
|
||||
// delete journals:
|
||||
$journals = \TransactionJournal::whereIn(
|
||||
$journals = \TransactionJournal::whereIn(
|
||||
'id', function (QueryBuilder $query) use ($model) {
|
||||
$query->select('transaction_journal_id')
|
||||
->from('transactions')->whereIn(
|
||||
'account_id', function (QueryBuilder $query) use ($model) {
|
||||
$query
|
||||
->select('id')
|
||||
->from('accounts')
|
||||
->where(
|
||||
function (QueryBuilder $q) use ($model) {
|
||||
$q->where('id', $model->id);
|
||||
$q->orWhere(
|
||||
function (QueryBuilder $q) use ($model) {
|
||||
$q->where('accounts.name', 'LIKE', '%' . $model->name . '%');
|
||||
$q->where('accounts.account_type_id', 3);
|
||||
$q->where('accounts.active', 0);
|
||||
}
|
||||
);
|
||||
}
|
||||
)->where('accounts.user_id', $this->getUser()->id);
|
||||
}
|
||||
)->get();
|
||||
->from('transactions')
|
||||
->whereIn(
|
||||
'account_id', function (QueryBuilder $query) use ($model) {
|
||||
$query
|
||||
->select('accounts.id')
|
||||
->from('accounts')
|
||||
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->where(
|
||||
function (QueryBuilder $q) use ($model) {
|
||||
$q->where('accounts.id', $model->id);
|
||||
$q->orWhere(
|
||||
function (QueryBuilder $q) use ($model) {
|
||||
$q->where('accounts.name', 'LIKE', '%' . $model->name . '%');
|
||||
$q->where('account_types.type', 'Initial balance account');
|
||||
$q->where('accounts.active', 0);
|
||||
}
|
||||
);
|
||||
}
|
||||
)->where('accounts.user_id', $this->getUser()->id);
|
||||
}
|
||||
)->get();
|
||||
}
|
||||
)->get();
|
||||
/*
|
||||
* Get all transactions.
|
||||
*/
|
||||
$transactions = [];
|
||||
/** @var \TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
@@ -281,25 +194,26 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
}
|
||||
$journal->delete();
|
||||
}
|
||||
// also delete transactions.
|
||||
if (count($transactions) > 0) {
|
||||
\Transaction::whereIn('id', $transactions)->delete();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Trigger deletion:
|
||||
*/
|
||||
\Event::fire('account.destroy', [$model]);
|
||||
|
||||
// delete accounts:
|
||||
// get account type:
|
||||
/** @var \FireflyIII\Database\AccountType\AccountType $acctType */
|
||||
$acctType = \App::make('FireflyIII\Database\AccountType\AccountType');
|
||||
|
||||
$accountType = $acctType->findByWhat('initial');
|
||||
|
||||
//$q->where('account_types.type', '');
|
||||
|
||||
\Account::where(
|
||||
function (EloquentBuilder $q) use ($model) {
|
||||
function (EloquentBuilder $q) use ($model, $accountType) {
|
||||
$q->where('id', $model->id);
|
||||
$q->orWhere(
|
||||
function (EloquentBuilder $q) use ($model) {
|
||||
function (EloquentBuilder $q) use ($model, $accountType) {
|
||||
$q->where('accounts.name', 'LIKE', '%' . $model->name . '%');
|
||||
$q->where('accounts.account_type_id', 3);
|
||||
$q->where('accounts.account_type_id', $accountType->id);
|
||||
$q->where('accounts.active', 0);
|
||||
}
|
||||
);
|
||||
@@ -318,9 +232,6 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
public function store(array $data)
|
||||
{
|
||||
|
||||
/*
|
||||
* Find account type.
|
||||
*/
|
||||
/** @var \FireflyIII\Database\AccountType\AccountType $acctType */
|
||||
$acctType = \App::make('FireflyIII\Database\AccountType\AccountType');
|
||||
|
||||
@@ -330,7 +241,6 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
$data['account_type_id'] = $accountType->id;
|
||||
$data['active'] = isset($data['active']) && $data['active'] === '1' ? 1 : 0;
|
||||
|
||||
|
||||
$data = array_except($data, ['_token', 'what']);
|
||||
$account = new \Account($data);
|
||||
if (!$account->isValid()) {
|
||||
@@ -339,7 +249,7 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
\App::abort(500);
|
||||
}
|
||||
$account->save();
|
||||
if (isset($data['openingbalance']) && floatval($data['openingbalance']) != 0) {
|
||||
if (isset($data['openingBalance']) && floatval($data['openingBalance']) != 0) {
|
||||
$this->storeInitialBalance($account, $data);
|
||||
}
|
||||
|
||||
@@ -379,15 +289,15 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
|
||||
$model->save();
|
||||
|
||||
if (isset($data['openingbalance']) && isset($data['openingbalancedate']) && strlen($data['openingbalancedate']) > 0) {
|
||||
if (isset($data['openingBalance']) && isset($data['openingBalanceDate']) && strlen($data['openingBalanceDate']) > 0) {
|
||||
/** @noinspection PhpParamsInspection */
|
||||
$openingBalance = $this->openingBalanceTransaction($model);
|
||||
if (is_null($openingBalance)) {
|
||||
$this->storeInitialBalance($model, $data);
|
||||
} else {
|
||||
$openingBalance->date = new Carbon($data['openingbalancedate']);
|
||||
$openingBalance->date = new Carbon($data['openingBalanceDate']);
|
||||
$openingBalance->save();
|
||||
$amount = floatval($data['openingbalance']);
|
||||
$amount = floatval($data['openingBalance']);
|
||||
/** @var \Transaction $transaction */
|
||||
foreach ($openingBalance->transactions as $transaction) {
|
||||
if ($transaction->account_id == $model->id) {
|
||||
@@ -453,14 +363,14 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
* Opening balance and opening balance date.
|
||||
*/
|
||||
if (isset($model['what']) && $model['what'] == 'asset') {
|
||||
if (isset($model['openingbalance']) && strlen($model['openingbalance']) > 0 && !is_numeric($model['openingbalance'])) {
|
||||
$errors->add('openingbalance', 'This is not a number.');
|
||||
if (isset($model['openingBalance']) && strlen($model['openingBalance']) > 0 && !is_numeric($model['openingBalance'])) {
|
||||
$errors->add('openingBalance', 'This is not a number.');
|
||||
}
|
||||
if (isset($model['openingbalancedate']) && strlen($model['openingbalancedate']) > 0) {
|
||||
if (isset($model['openingBalanceDate']) && strlen($model['openingBalanceDate']) > 0) {
|
||||
try {
|
||||
new Carbon($model['openingbalancedate']);
|
||||
new Carbon($model['openingBalanceDate']);
|
||||
} catch (\Exception $e) {
|
||||
$errors->add('openingbalancedate', 'This date is invalid.');
|
||||
$errors->add('openingBalanceDate', 'This date is invalid.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -469,11 +379,11 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
if (!$errors->has('name')) {
|
||||
$successes->add('name', 'OK');
|
||||
}
|
||||
if (!$errors->has('openingbalance')) {
|
||||
$successes->add('openingbalance', 'OK');
|
||||
if (!$errors->has('openingBalance')) {
|
||||
$successes->add('openingBalance', 'OK');
|
||||
}
|
||||
if (!$errors->has('openingbalancedate')) {
|
||||
$successes->add('openingbalancedate', 'OK');
|
||||
if (!$errors->has('openingBalanceDate')) {
|
||||
$successes->add('openingBalanceDate', 'OK');
|
||||
}
|
||||
|
||||
return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes];
|
||||
@@ -492,6 +402,9 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param $what
|
||||
*
|
||||
* @throws NotImplementedException
|
||||
@@ -507,6 +420,7 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
*
|
||||
* @return Collection
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
@@ -531,14 +445,14 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
*/
|
||||
public function firstExpenseAccountOrCreate($name)
|
||||
{
|
||||
/** @var \FireflyIII\Database\AccountType\AccountType $accountTypeRepository */
|
||||
$accountTypeRepository = \App::make('FireflyIII\Database\AccountType\AccountType');
|
||||
/** @var \FireflyIII\Database\AccountType\AccountType $typeRepository */
|
||||
$typeRepository = \App::make('FireflyIII\Database\AccountType\AccountType');
|
||||
|
||||
$accountType = $accountTypeRepository->findByWhat('expense');
|
||||
$accountType = $typeRepository->findByWhat('expense');
|
||||
|
||||
// if name is "", find cash account:
|
||||
if (strlen($name) == 0) {
|
||||
$cashAccountType = $accountTypeRepository->findByWhat('cash');
|
||||
$cashAccountType = $typeRepository->findByWhat('cash');
|
||||
|
||||
// find or create cash account:
|
||||
return \Account::firstOrCreate(
|
||||
@@ -560,10 +474,20 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
*/
|
||||
public function firstRevenueAccountOrCreate($name)
|
||||
{
|
||||
/** @var \FireflyIII\Database\AccountType\AccountType $accountTypeRepository */
|
||||
$accountTypeRepository = \App::make('FireflyIII\Database\AccountType\AccountType');
|
||||
/** @var \FireflyIII\Database\AccountType\AccountType $typeRepository */
|
||||
$typeRepository = \App::make('FireflyIII\Database\AccountType\AccountType');
|
||||
|
||||
$accountType = $accountTypeRepository->findByWhat('revenue');
|
||||
$accountType = $typeRepository->findByWhat('revenue');
|
||||
|
||||
// if name is "", find cash account:
|
||||
if (strlen($name) == 0) {
|
||||
$cashAccountType = $typeRepository->findByWhat('cash');
|
||||
|
||||
// find or create cash account:
|
||||
return \Account::firstOrCreate(
|
||||
['name' => 'Cash account', 'account_type_id' => $cashAccountType->id, 'active' => 0, 'user_id' => $this->getUser()->id,]
|
||||
);
|
||||
}
|
||||
|
||||
$data = ['user_id' => $this->getUser()->id, 'account_type_id' => $accountType->id, 'name' => $name, 'active' => 1];
|
||||
|
||||
@@ -571,57 +495,6 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Account $account
|
||||
* @param int $limit
|
||||
*
|
||||
* @return \Illuminate\Pagination\Paginator
|
||||
*/
|
||||
public function getAllTransactionJournals(\Account $account, $limit = 50)
|
||||
{
|
||||
$offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0;
|
||||
$set = $this->getUser()->transactionJournals()->withRelevantData()->leftJoin(
|
||||
'transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id'
|
||||
)->where('transactions.account_id', $account->id)->take($limit)->offset($offset)->orderBy('date', 'DESC')->get(
|
||||
['transaction_journals.*']
|
||||
);
|
||||
$count = $this->getUser()->transactionJournals()->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->orderBy('date', 'DESC')->where('transactions.account_id', $account->id)->count();
|
||||
$items = [];
|
||||
foreach ($set as $entry) {
|
||||
$items[] = $entry;
|
||||
}
|
||||
|
||||
return \Paginator::make($items, $count, $limit);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Account $account
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLastActivity(\Account $account)
|
||||
{
|
||||
$lastActivityKey = 'account.' . $account->id . '.lastActivityDate';
|
||||
if (\Cache::has($lastActivityKey)) {
|
||||
return \Cache::get($lastActivityKey);
|
||||
}
|
||||
|
||||
$transaction = $account->transactions()
|
||||
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->orderBy('transaction_journals.date', 'DESC')->first();
|
||||
if ($transaction) {
|
||||
$date = $transaction->transactionJournal->date;
|
||||
} else {
|
||||
$date = 0;
|
||||
}
|
||||
\Cache::forever($lastActivityKey, $date);
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Account $account
|
||||
* @param int $limit
|
||||
@@ -656,24 +529,4 @@ class Account implements CUDInterface, CommonDatabaseCallsInterface, AccountInte
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return \Illuminate\Pagination\Paginator
|
||||
*/
|
||||
public function getTransactionJournalsInRange(\Account $account, Carbon $start, Carbon $end)
|
||||
{
|
||||
$set = $this->getUser()->transactionJournals()->transactionTypes(['Withdrawal'])->withRelevantData()->leftJoin(
|
||||
'transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id'
|
||||
)->where('transactions.account_id', $account->id)->before($end)->after($start)->orderBy('date', 'DESC')->get(
|
||||
['transaction_journals.*']
|
||||
);
|
||||
|
||||
return $set;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -21,34 +21,6 @@ interface AccountInterface
|
||||
*/
|
||||
public function countAccountsByType(array $types);
|
||||
|
||||
/**
|
||||
* Counts the number of total asset accounts. Useful for DataTables.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countAssetAccounts();
|
||||
|
||||
/**
|
||||
* Counts the number of total expense accounts. Useful for DataTables.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countExpenseAccounts();
|
||||
|
||||
/**
|
||||
* Counts the number of total revenue accounts. Useful for DataTables.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countRevenueAccounts();
|
||||
|
||||
/**
|
||||
* @param \Account $account
|
||||
*
|
||||
* @return \Account|null
|
||||
*/
|
||||
public function findInitialBalanceAccount(\Account $account);
|
||||
|
||||
/**
|
||||
* Get all accounts of the selected types. Is also capable of handling DataTables' parameters.
|
||||
*
|
||||
@@ -58,24 +30,6 @@ interface AccountInterface
|
||||
*/
|
||||
public function getAccountsByType(array $types);
|
||||
|
||||
/**
|
||||
* Get all asset accounts. The parameters are optional and are provided by the DataTables plugin.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAssetAccounts();
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
public function getExpenseAccounts();
|
||||
|
||||
/**
|
||||
* Get all revenue accounts.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getRevenueAccounts();
|
||||
|
||||
/**
|
||||
* @param \Account $account
|
||||
|
||||
@@ -19,9 +19,11 @@ class AccountType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
|
||||
/**
|
||||
* @param Eloquent $model
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @return bool
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function destroy(Eloquent $model)
|
||||
{
|
||||
@@ -30,9 +32,11 @@ class AccountType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @return \Eloquent
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function store(array $data)
|
||||
{
|
||||
@@ -42,9 +46,11 @@ class AccountType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
/**
|
||||
* @param Eloquent $model
|
||||
* @param array $data
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @return bool
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function update(Eloquent $model, array $data)
|
||||
{
|
||||
@@ -52,6 +58,8 @@ class AccountType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Validates an array. Returns an array containing MessageBags
|
||||
* errors/warnings/successes.
|
||||
*
|
||||
@@ -59,6 +67,7 @@ class AccountType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
*
|
||||
* @return array
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function validate(array $model)
|
||||
{
|
||||
@@ -66,12 +75,15 @@ class AccountType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Returns an object with id $id.
|
||||
*
|
||||
* @param int $objectId
|
||||
*
|
||||
* @return \Eloquent
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function find($objectId)
|
||||
{
|
||||
@@ -88,34 +100,27 @@ class AccountType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
*/
|
||||
public function findByWhat($what)
|
||||
{
|
||||
switch ($what) {
|
||||
case 'expense':
|
||||
return \AccountType::whereType('Expense account')->first();
|
||||
break;
|
||||
case 'asset':
|
||||
return \AccountType::whereType('Asset account')->first();
|
||||
break;
|
||||
case 'revenue':
|
||||
return \AccountType::whereType('Revenue account')->first();
|
||||
break;
|
||||
case 'cash':
|
||||
return \AccountType::whereType('Cash account')->first();
|
||||
break;
|
||||
case 'initial':
|
||||
return \AccountType::whereType('Initial balance account')->first();
|
||||
break;
|
||||
default:
|
||||
throw new FireflyException('Cannot find account type described as "' . e($what) . '".');
|
||||
break;
|
||||
|
||||
$typeMap = [
|
||||
'expense' => 'Expense account',
|
||||
'asset' => 'Asset account',
|
||||
'revenue' => 'Revenue account',
|
||||
'cash' => 'Cash account',
|
||||
'initial' => 'Initial balance account',
|
||||
];
|
||||
if (isset($typeMap[$what])) {
|
||||
return \AccountType::whereType($typeMap[$what])->first();
|
||||
}
|
||||
throw new FireflyException('Cannot find account type described as "' . e($what) . '".');
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Returns all objects.
|
||||
*
|
||||
* @return Collection
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
@@ -123,10 +128,13 @@ class AccountType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param array $ids
|
||||
*
|
||||
* @return Collection
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function getByIds(array $ids)
|
||||
{
|
||||
|
||||
@@ -114,7 +114,7 @@ class Bill implements CUDInterface, CommonDatabaseCallsInterface, BillInterface
|
||||
$warnings = new MessageBag;
|
||||
$successes = new MessageBag;
|
||||
$errors = new MessageBag;
|
||||
if (isset($model['amount_min']) && isset($model['amount_max']) && floatval($model['amount_min']) > floatval($model['amount_max'])) {
|
||||
if (floatval($model['amount_min']) > floatval($model['amount_max'])) {
|
||||
$errors->add('amount_max', 'Maximum amount can not be less than minimum amount.');
|
||||
$errors->add('amount_min', 'Minimum amount can not be more than maximum amount.');
|
||||
}
|
||||
@@ -133,12 +133,15 @@ class Bill implements CUDInterface, CommonDatabaseCallsInterface, BillInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Returns an object with id $id.
|
||||
*
|
||||
* @param int $objectId
|
||||
*
|
||||
* @return \Eloquent
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function find($objectId)
|
||||
{
|
||||
@@ -146,12 +149,15 @@ class Bill implements CUDInterface, CommonDatabaseCallsInterface, BillInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc.
|
||||
*
|
||||
* @param $what
|
||||
*
|
||||
* @return \AccountType|null
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function findByWhat($what)
|
||||
{
|
||||
@@ -169,39 +175,18 @@ class Bill implements CUDInterface, CommonDatabaseCallsInterface, BillInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
* @param array $ids
|
||||
*
|
||||
* @return Collection
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function getByIds(array $ids)
|
||||
{
|
||||
throw new NotImplementedException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all objects.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getActive()
|
||||
{
|
||||
return $this->getUser()->bills()->where('active', 1)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Bill $bill
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return \TransactionJournal|null
|
||||
*/
|
||||
public function getJournalForBillInRange(\Bill $bill, Carbon $start, Carbon $end)
|
||||
{
|
||||
return $this->getUser()->transactionjournals()->where('bill_id', $bill->id)->after($start)->before($end)->first();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Bill $bill
|
||||
*
|
||||
@@ -218,15 +203,14 @@ class Bill implements CUDInterface, CommonDatabaseCallsInterface, BillInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param \Bill $bill
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
public function nextExpectedMatch(\Bill $bill)
|
||||
{
|
||||
/*
|
||||
* The date Firefly tries to find. If this stays null, it's "unknown".
|
||||
*/
|
||||
$finalDate = null;
|
||||
if ($bill->active == 0) {
|
||||
return $finalDate;
|
||||
@@ -238,10 +222,6 @@ class Bill implements CUDInterface, CommonDatabaseCallsInterface, BillInterface
|
||||
*/
|
||||
$today = \DateKit::addPeriod(new Carbon, $bill->repeat_freq, 0);
|
||||
|
||||
/*
|
||||
* FF3 loops from the $start of the bill, and to make sure
|
||||
* $skip works, it adds one (for modulo).
|
||||
*/
|
||||
$skip = $bill->skip + 1;
|
||||
$start = \DateKit::startOfPeriod(new Carbon, $bill->repeat_freq);
|
||||
/*
|
||||
|
||||
@@ -11,18 +11,6 @@ use Carbon\Carbon;
|
||||
*/
|
||||
interface BillInterface
|
||||
{
|
||||
/**
|
||||
* @param \Bill $bill
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return null|\TransactionJournal
|
||||
* @internal param Carbon $current
|
||||
* @internal param Carbon $currentEnd
|
||||
*
|
||||
*/
|
||||
public function getJournalForBillInRange(\Bill $bill, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param \Bill $bill
|
||||
*
|
||||
|
||||
@@ -8,9 +8,9 @@ use FireflyIII\Database\SwitchUser;
|
||||
use FireflyIII\Exception\FireflyException;
|
||||
use FireflyIII\Exception\NotImplementedException;
|
||||
use Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||
|
||||
/**
|
||||
* Class Budget
|
||||
@@ -97,6 +97,71 @@ class Budget implements CUDInterface, CommonDatabaseCallsInterface, BudgetInterf
|
||||
return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function expenseNoBudget(Carbon $start, Carbon $end)
|
||||
{
|
||||
// Add expenses that have no budget:
|
||||
return $this->getUser()
|
||||
->transactionjournals()
|
||||
->whereNotIn(
|
||||
'transaction_journals.id', function (QueryBuilder $query) use ($start, $end) {
|
||||
$query
|
||||
->select('transaction_journals.id')
|
||||
->from('transaction_journals')
|
||||
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->where('transaction_journals.date', '>=', $start->format('Y-m-d 00:00:00'))
|
||||
->where('transaction_journals.date', '<=', $end->format('Y-m-d 00:00:00'));
|
||||
}
|
||||
)
|
||||
->before($end)
|
||||
->after($start)
|
||||
->lessThan(0)
|
||||
->transactionTypes(['Withdrawal'])
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsNoBudget(Carbon $start, Carbon $end)
|
||||
{
|
||||
$set = $this->getUser()
|
||||
->transactionjournals()
|
||||
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->whereNull('budget_transaction_journal.id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->orderBy('transaction_journals.date')
|
||||
->get(['transaction_journals.*']);
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method includes the time because otherwise, SQLite does not understand it.
|
||||
*
|
||||
* @param \Budget $budget
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return \LimitRepetition|null
|
||||
*/
|
||||
public function repetitionOnStartingOnDate(\Budget $budget, Carbon $date)
|
||||
{
|
||||
return \LimitRepetition::
|
||||
leftJoin('budget_limits', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')
|
||||
->where('limit_repetitions.startdate', $date->format('Y-m-d 00:00:00'))
|
||||
->where('budget_limits.budget_id', $budget->id)
|
||||
->first(['limit_repetitions.*']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object with id $id.
|
||||
*
|
||||
@@ -110,12 +175,15 @@ class Budget implements CUDInterface, CommonDatabaseCallsInterface, BudgetInterf
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc.
|
||||
*
|
||||
* @param $what
|
||||
*
|
||||
* @return \AccountType|null
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function findByWhat($what)
|
||||
{
|
||||
@@ -135,10 +203,13 @@ class Budget implements CUDInterface, CommonDatabaseCallsInterface, BudgetInterf
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param array $ids
|
||||
*
|
||||
* @return Collection
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function getByIds(array $ids)
|
||||
{
|
||||
@@ -190,116 +261,6 @@ class Budget implements CUDInterface, CommonDatabaseCallsInterface, BudgetInterf
|
||||
return $budget->limitrepetitions()->where('limit_repetitions.startdate', $date)->first(['limit_repetitions.*']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Budget $budget
|
||||
* @param int $limit
|
||||
*
|
||||
* @return \Illuminate\Pagination\Paginator
|
||||
*/
|
||||
public function getTransactionJournals(\Budget $budget, $limit = 50)
|
||||
{
|
||||
$offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0;
|
||||
$set = $budget->transactionJournals()->withRelevantData()->take($limit)->offset($offset)->orderBy('date', 'DESC')->get(['transaction_journals.*']);
|
||||
$count = $budget->transactionJournals()->count();
|
||||
$items = [];
|
||||
foreach ($set as $entry) {
|
||||
$items[] = $entry;
|
||||
}
|
||||
|
||||
return \Paginator::make($items, $count, $limit);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Budget $budget
|
||||
* @param \LimitRepetition $repetition
|
||||
* @param int $limit
|
||||
*
|
||||
* @return \Illuminate\Pagination\Paginator
|
||||
*/
|
||||
public function getTransactionJournalsInRepetition(\Budget $budget, \LimitRepetition $repetition, $limit = 50)
|
||||
{
|
||||
$start = $repetition->startdate;
|
||||
$end = $repetition->enddate;
|
||||
|
||||
$offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0;
|
||||
$set = $budget->transactionJournals()->withRelevantData()->before($end)->after($start)->take($limit)->offset($offset)->orderBy('date', 'DESC')->get(
|
||||
['transaction_journals.*']
|
||||
);
|
||||
$count = $budget->transactionJournals()->before($end)->after($start)->count();
|
||||
$items = [];
|
||||
foreach ($set as $entry) {
|
||||
$items[] = $entry;
|
||||
}
|
||||
|
||||
return \Paginator::make($items, $count, $limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method includes the time because otherwise, SQLite does not understand it.
|
||||
*
|
||||
* @param \Budget $budget
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return \LimitRepetition|null
|
||||
*/
|
||||
public function repetitionOnStartingOnDate(\Budget $budget, Carbon $date)
|
||||
{
|
||||
return \LimitRepetition::
|
||||
leftJoin('budget_limits', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')
|
||||
->where('limit_repetitions.startdate', $date->format('Y-m-d 00:00:00'))
|
||||
->where('budget_limits.budget_id', $budget->id)
|
||||
->first(['limit_repetitions.*']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function expenseNoBudget(Carbon $start, Carbon $end)
|
||||
{
|
||||
// Add expenses that have no budget:
|
||||
return $this->getUser()
|
||||
->transactionjournals()
|
||||
->whereNotIn(
|
||||
'transaction_journals.id', function (QueryBuilder $query) use ($start, $end) {
|
||||
$query
|
||||
->select('transaction_journals.id')
|
||||
->from('transaction_journals')
|
||||
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->where('transaction_journals.date', '>=', $start->format('Y-m-d 00:00:00'))
|
||||
->where('transaction_journals.date', '<=', $end->format('Y-m-d 00:00:00'));
|
||||
}
|
||||
)
|
||||
->before($end)
|
||||
->after($start)
|
||||
->lessThan(0)
|
||||
->transactionTypes(['Withdrawal'])
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsNoBudget(Carbon $start, Carbon $end)
|
||||
{
|
||||
$set = $this->getUser()
|
||||
->transactionjournals()
|
||||
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->whereNull('budget_transaction_journal.id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->orderBy('transaction_journals.date')
|
||||
->get(['transaction_journals.*']);
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Budget $budget
|
||||
* @param Carbon $date
|
||||
@@ -316,20 +277,6 @@ class Budget implements CUDInterface, CommonDatabaseCallsInterface, BudgetInterf
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Budget $budget
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function spentInPeriod(\Budget $budget, Carbon $start, Carbon $end)
|
||||
{
|
||||
$sum = floatval($budget->transactionjournals()->before($end)->after($start)->lessThan(0)->sum('amount')) * -1;
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method updates the amount (envelope) for the given date and budget. This results in a (new) limit (aka an envelope)
|
||||
* for that budget. Returned to the user is the new limit repetition.
|
||||
@@ -343,7 +290,7 @@ class Budget implements CUDInterface, CommonDatabaseCallsInterface, BudgetInterf
|
||||
*/
|
||||
public function updateLimitAmount(\Budget $budget, Carbon $date, $amount)
|
||||
{
|
||||
/** @var \Limit $limit */
|
||||
/** @var \BudgetLimit $limit */
|
||||
$limit = $this->limitOnStartingOnDate($budget, $date);
|
||||
if (!$limit) {
|
||||
// create one!
|
||||
@@ -381,7 +328,7 @@ class Budget implements CUDInterface, CommonDatabaseCallsInterface, BudgetInterf
|
||||
* @param \Budget $budget
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return \Limit
|
||||
* @return \BudgetLimit
|
||||
*/
|
||||
public function limitOnStartingOnDate(\Budget $budget, Carbon $date)
|
||||
{
|
||||
|
||||
@@ -99,12 +99,15 @@ class Category implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Returns an object with id $id.
|
||||
*
|
||||
* @param int $objectId
|
||||
*
|
||||
* @return \Eloquent
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function find($objectId)
|
||||
{
|
||||
@@ -112,12 +115,15 @@ class Category implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc.
|
||||
*
|
||||
* @param $what
|
||||
*
|
||||
* @return \AccountType|null
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function findByWhat($what)
|
||||
{
|
||||
@@ -125,6 +131,8 @@ class Category implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Returns all objects.
|
||||
*
|
||||
* @return Collection
|
||||
@@ -135,10 +143,13 @@ class Category implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param array $ids
|
||||
*
|
||||
* @return Collection
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function getByIds(array $ids)
|
||||
{
|
||||
@@ -195,19 +206,6 @@ class Category implements CUDInterface, CommonDatabaseCallsInterface
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Category $category
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return null
|
||||
* @throws NotImplementedException
|
||||
* @internal param \Category $budget
|
||||
*/
|
||||
public function repetitionOnStartingOnDate(\Category $category, Carbon $date)
|
||||
{
|
||||
throw new NotImplementedException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Category $category
|
||||
* @param Carbon $date
|
||||
|
||||
@@ -21,7 +21,6 @@ class PiggyBank extends PiggyBankShared implements CUDInterface, CommonDatabaseC
|
||||
*
|
||||
* @return mixed
|
||||
* @throws FireflyException
|
||||
* @throws NotImplementedException
|
||||
*/
|
||||
public function findRepetitionByDate(\PiggyBank $piggyBank, Carbon $date)
|
||||
{
|
||||
@@ -30,13 +29,10 @@ class PiggyBank extends PiggyBankShared implements CUDInterface, CommonDatabaseC
|
||||
if ($reps->count() == 1) {
|
||||
return $reps->first();
|
||||
}
|
||||
if ($reps->count() == 0) {
|
||||
throw new FireflyException('Should always find a piggy bank repetition.');
|
||||
}
|
||||
// should filter the one we need:
|
||||
$repetitions = $reps->filter(
|
||||
function (\PiggyBankRepetition $rep) use ($date) {
|
||||
if ($date >= $rep->startdate && $date <= $rep->targetdate) {
|
||||
if ($date->between($rep->startdate, $rep->targetdate)) {
|
||||
return $rep;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,12 +58,15 @@ class PiggyBankShared
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc.
|
||||
*
|
||||
* @param $what
|
||||
*
|
||||
* @return \AccountType|null
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function findByWhat($what)
|
||||
{
|
||||
@@ -75,14 +78,11 @@ class PiggyBankShared
|
||||
*
|
||||
* @return Collection
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function getByIds(array $ids)
|
||||
{
|
||||
return \PiggyBank::
|
||||
leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')->whereIn('piggy_banks.id', [$ids])->where(
|
||||
'accounts.user_id', $this->getUser()->id
|
||||
)
|
||||
->first(['piggy_banks.*']);
|
||||
throw new NotImplementedException;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,6 +123,8 @@ class PiggyBankShared
|
||||
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param Eloquent $model
|
||||
* @param array $data
|
||||
*
|
||||
|
||||
@@ -17,6 +17,8 @@ class RepeatedExpense extends PiggyBankShared implements CUDInterface, CommonDat
|
||||
{
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* Based on the piggy bank, the reminder-setting and
|
||||
* other variables this method tries to divide the piggy bank into equal parts. Each is
|
||||
* accommodated by a reminder (if everything goes to plan).
|
||||
|
||||
@@ -22,9 +22,11 @@ class Transaction implements CUDInterface, CommonDatabaseCallsInterface
|
||||
|
||||
/**
|
||||
* @param Eloquent $model
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @return bool
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function destroy(Eloquent $model)
|
||||
{
|
||||
@@ -59,11 +61,14 @@ class Transaction implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param Eloquent $model
|
||||
* @param array $data
|
||||
*
|
||||
* @return bool
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function update(Eloquent $model, array $data)
|
||||
{
|
||||
@@ -92,12 +97,15 @@ class Transaction implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Returns an object with id $id.
|
||||
*
|
||||
* @param int $objectId
|
||||
*
|
||||
* @return \Eloquent
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function find($objectId)
|
||||
{
|
||||
@@ -105,12 +113,15 @@ class Transaction implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc.
|
||||
*
|
||||
* @param $what
|
||||
*
|
||||
* @return \AccountType|null
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function findByWhat($what)
|
||||
{
|
||||
@@ -122,6 +133,7 @@ class Transaction implements CUDInterface, CommonDatabaseCallsInterface
|
||||
*
|
||||
* @return Collection
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
@@ -129,10 +141,13 @@ class Transaction implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param array $ids
|
||||
*
|
||||
* @return Collection
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function getByIds(array $ids)
|
||||
{
|
||||
|
||||
@@ -89,23 +89,27 @@ class TransactionCurrency implements TransactionCurrencyInterface, CommonDatabas
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Returns an object with id $id.
|
||||
*
|
||||
* @param int $objectId
|
||||
* @throws NotImplementedException
|
||||
*
|
||||
* @return \Eloquent
|
||||
*/
|
||||
public function find($objectId)
|
||||
{
|
||||
throw new NotImplementedException;
|
||||
return \TransactionCurrency::find($objectId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc.
|
||||
*
|
||||
* @param $what
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return \AccountType|null
|
||||
*/
|
||||
@@ -125,8 +129,11 @@ class TransactionCurrency implements TransactionCurrencyInterface, CommonDatabas
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param array $objectIds
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
|
||||
@@ -63,12 +63,13 @@ class TransactionJournal implements TransactionJournalInterface, CUDInterface, C
|
||||
*/
|
||||
public function store(array $data)
|
||||
{
|
||||
$currency = $this->getJournalCurrency($data['currency']);
|
||||
$journal = new \TransactionJournal(
|
||||
$journal = new \TransactionJournal(
|
||||
[
|
||||
'transaction_type_id' => $data['transaction_type_id'],
|
||||
'transaction_currency_id' => $currency->id, 'user_id' => $this->getUser()->id,
|
||||
'description' => $data['description'], 'date' => $data['date'], 'completed' => 0]
|
||||
'transaction_currency_id' => $data['transaction_currency_id'],
|
||||
'user_id' => $this->getUser()->id,
|
||||
'description' => $data['description'],
|
||||
'date' => $data['date'], 'completed' => 0]
|
||||
);
|
||||
$journal->save();
|
||||
|
||||
@@ -102,7 +103,7 @@ class TransactionJournal implements TransactionJournalInterface, CUDInterface, C
|
||||
public function update(Eloquent $model, array $data)
|
||||
{
|
||||
$journalType = $this->getJournalType($data['what']);
|
||||
$currency = $this->getJournalCurrency($data['currency']);
|
||||
$currency = $this->getJournalCurrencyById($data['transaction_currency_id']);
|
||||
$model->description = $data['description'];
|
||||
$model->date = $data['date'];
|
||||
|
||||
@@ -117,9 +118,6 @@ class TransactionJournal implements TransactionJournalInterface, CUDInterface, C
|
||||
$this->storeBudget($data, $model);
|
||||
$this->storeCategory($data, $model);
|
||||
|
||||
/*
|
||||
* Now we can update the transactions related to this journal.
|
||||
*/
|
||||
$amount = floatval($data['amount']);
|
||||
/** @var \Transaction $transaction */
|
||||
foreach ($model->transactions()->get() as $transaction) {
|
||||
@@ -164,109 +162,29 @@ class TransactionJournal implements TransactionJournalInterface, CUDInterface, C
|
||||
if (!isset($model['what'])) {
|
||||
$errors->add('description', 'Internal error: need to know type of transaction!');
|
||||
}
|
||||
/*
|
||||
* Amount
|
||||
*/
|
||||
if (isset($model['amount']) && floatval($model['amount']) < 0.01) {
|
||||
$errors->add('amount', 'Amount must be > 0.01');
|
||||
} else {
|
||||
if (!isset($model['amount'])) {
|
||||
$errors->add('amount', 'Amount must be set!');
|
||||
} else {
|
||||
$successes->add('amount', 'OK');
|
||||
if (strlen($model['description']) == 0) {
|
||||
$errors->add('description', 'The description field is required.');
|
||||
}
|
||||
$errors = $errors->merge($this->_validateAmount($model));
|
||||
$errors = $errors->merge($this->_validateBudget($model));
|
||||
$errors = $errors->merge($this->_validateAccount($model));
|
||||
|
||||
$list = ['date', 'description', 'amount', 'budget_id', 'from', 'to', 'account_from_id', 'account_to_id', 'category', 'account_id', 'expense_account',
|
||||
'revenue_account'];
|
||||
foreach ($list as $entry) {
|
||||
if (!$errors->has($entry)) {
|
||||
$successes->add($entry, 'OK');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Budget
|
||||
*/
|
||||
if (isset($model['budget_id']) && !ctype_digit($model['budget_id'])) {
|
||||
$errors->add('budget_id', 'Invalid budget');
|
||||
} else {
|
||||
$successes->add('budget_id', 'OK');
|
||||
}
|
||||
|
||||
$successes->add('category', 'OK');
|
||||
|
||||
/*
|
||||
* Many checks to catch invalid or not-existing accounts.
|
||||
*/
|
||||
switch (true) {
|
||||
// this combination is often seen in withdrawals.
|
||||
case (isset($model['account_id']) && isset($model['expense_account'])):
|
||||
if (intval($model['account_id']) < 1) {
|
||||
$errors->add('account_id', 'Invalid account.');
|
||||
} else {
|
||||
$successes->add('account_id', 'OK');
|
||||
}
|
||||
$successes->add('expense_account', 'OK');
|
||||
break;
|
||||
case (isset($model['account_id']) && isset($model['revenue_account'])):
|
||||
if (intval($model['account_id']) < 1) {
|
||||
$errors->add('account_id', 'Invalid account.');
|
||||
} else {
|
||||
$successes->add('account_id', 'OK');
|
||||
}
|
||||
$successes->add('revenue_account', 'OK');
|
||||
break;
|
||||
case (isset($model['account_from_id']) && isset($model['account_to_id'])):
|
||||
if (intval($model['account_from_id']) < 1 || intval($model['account_from_id']) < 1) {
|
||||
$errors->add('account_from_id', 'Invalid account selected.');
|
||||
$errors->add('account_to_id', 'Invalid account selected.');
|
||||
|
||||
} else {
|
||||
if (intval($model['account_from_id']) == intval($model['account_to_id'])) {
|
||||
$errors->add('account_to_id', 'Cannot be the same as "from" account.');
|
||||
$errors->add('account_from_id', 'Cannot be the same as "to" account.');
|
||||
} else {
|
||||
$successes->add('account_from_id', 'OK');
|
||||
$successes->add('account_to_id', 'OK');
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case (isset($model['to']) && isset($model['from'])):
|
||||
if (is_object($model['to']) && is_object($model['from'])) {
|
||||
$successes->add('from', 'OK');
|
||||
$successes->add('to', 'OK');
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new FireflyException('Cannot validate accounts for transaction journal.');
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add "OK"
|
||||
*/
|
||||
if (!$errors->has('description')) {
|
||||
$successes->add('description', 'OK');
|
||||
}
|
||||
if (!$errors->has('date')) {
|
||||
$successes->add('date', 'OK');
|
||||
}
|
||||
|
||||
return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes];
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $currency
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @return null|\TransactionCurrency
|
||||
*/
|
||||
public function getJournalCurrency($currency)
|
||||
{
|
||||
/** @var \FireflyIII\Database\TransactionCurrency\TransactionCurrency $currencyRepository */
|
||||
$currencyRepository = \App::make('FireflyIII\Database\TransactionCurrency\TransactionCurrency');
|
||||
|
||||
return $currencyRepository->findByCode($currency);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
@@ -377,25 +295,133 @@ class TransactionJournal implements TransactionJournalInterface, CUDInterface, C
|
||||
return $typeRepository->findByWhat($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $currencyId
|
||||
*
|
||||
* @return null|\TransactionCurrency
|
||||
*/
|
||||
public function getJournalCurrencyById($currencyId)
|
||||
{
|
||||
/** @var \FireflyIII\Database\TransactionCurrency\TransactionCurrency $currencyRepository */
|
||||
$currencyRepository = \App::make('FireflyIII\Database\TransactionCurrency\TransactionCurrency');
|
||||
|
||||
return $currencyRepository->find($currencyId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
*
|
||||
* @param array $model
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
protected function _validateAmount(array $model)
|
||||
{
|
||||
$errors = new MessageBag;
|
||||
if (isset($model['amount']) && floatval($model['amount']) < 0.01) {
|
||||
$errors->add('amount', 'Amount must be > 0.01');
|
||||
} else {
|
||||
if (!isset($model['amount'])) {
|
||||
$errors->add('amount', 'Amount must be set!');
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
*
|
||||
* @param array $model
|
||||
*
|
||||
* @return MessageBag
|
||||
*/
|
||||
protected function _validateBudget(array $model)
|
||||
{
|
||||
/*
|
||||
* Budget (is not in rules)
|
||||
*/
|
||||
$errors = new MessageBag;
|
||||
if (isset($model['budget_id']) && !ctype_digit($model['budget_id'])) {
|
||||
$errors->add('budget_id', 'Invalid budget');
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
*
|
||||
* @param array $model
|
||||
*
|
||||
* @return MessageBag
|
||||
* @throws FireflyException
|
||||
*/
|
||||
protected function _validateAccount(array $model)
|
||||
{
|
||||
$errors = new MessageBag;
|
||||
switch (true) {
|
||||
// this combination is often seen in withdrawals.
|
||||
case (isset($model['account_id']) && isset($model['expense_account'])):
|
||||
if (intval($model['account_id']) < 1) {
|
||||
$errors->add('account_id', 'Invalid account.');
|
||||
}
|
||||
break;
|
||||
// often seen in deposits
|
||||
case (isset($model['account_id']) && isset($model['revenue_account'])):
|
||||
if (intval($model['account_id']) < 1) {
|
||||
$errors->add('account_id', 'Invalid account.');
|
||||
}
|
||||
break;
|
||||
// often seen in transfers
|
||||
case (isset($model['account_from_id']) && isset($model['account_to_id'])):
|
||||
if (intval($model['account_from_id']) < 1 || intval($model['account_from_id']) < 1) {
|
||||
$errors->add('account_from_id', 'Invalid account selected.');
|
||||
$errors->add('account_to_id', 'Invalid account selected.');
|
||||
|
||||
} else {
|
||||
if (intval($model['account_from_id']) == intval($model['account_to_id'])) {
|
||||
$errors->add('account_to_id', 'Cannot be the same as "from" account.');
|
||||
$errors->add('account_from_id', 'Cannot be the same as "to" account.');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case (isset($model['from']) && isset($model['to'])):
|
||||
break;
|
||||
default:
|
||||
throw new FireflyException('Cannot validate accounts for transaction journal.');
|
||||
break;
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object with id $id.
|
||||
*
|
||||
* @param int $objectId
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @throws NotImplementedException
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @return \Eloquent
|
||||
*/
|
||||
public function find($objectId)
|
||||
{
|
||||
return $this->getUser()->transactionjournals()->find($objectId);
|
||||
throw new NotImplementedException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Finds an account type using one of the "$what"'s: expense, asset, revenue, opening, etc.
|
||||
*
|
||||
* @param $what
|
||||
*
|
||||
* @return \AccountType|null
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function findByWhat($what)
|
||||
{
|
||||
@@ -406,11 +432,11 @@ class TransactionJournal implements TransactionJournalInterface, CUDInterface, C
|
||||
* Returns all objects.
|
||||
*
|
||||
* @return Collection
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
return $this->getUser()->transactionjournals()->with(['TransactionType', 'transactions', 'transactions.account', 'transactions.account.accountType'])
|
||||
->get();
|
||||
throw new NotImplementedException;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -444,17 +470,6 @@ class TransactionJournal implements TransactionJournalInterface, CUDInterface, C
|
||||
return $this->getUser()->transactionjournals()->orderBy('date', 'ASC')->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getInDateRange(Carbon $start, Carbon $end)
|
||||
{
|
||||
return $this->getuser()->transactionjournals()->withRelevantData()->before($end)->after($start)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
*
|
||||
@@ -539,6 +554,19 @@ class TransactionJournal implements TransactionJournalInterface, CUDInterface, C
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $currency
|
||||
*
|
||||
* @return null|\TransactionCurrency
|
||||
*/
|
||||
public function getJournalCurrency($currency)
|
||||
{
|
||||
/** @var \FireflyIII\Database\TransactionCurrency\TransactionCurrency $currencyRepository */
|
||||
$currencyRepository = \App::make('FireflyIII\Database\TransactionCurrency\TransactionCurrency');
|
||||
|
||||
return $currencyRepository->findByCode($currency);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $limit
|
||||
*
|
||||
|
||||
@@ -19,14 +19,6 @@ interface TransactionJournalInterface
|
||||
*/
|
||||
public function first();
|
||||
|
||||
/**
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getInDateRange(Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
*
|
||||
|
||||
@@ -20,10 +20,13 @@ class TransactionType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param Eloquent $model
|
||||
*
|
||||
* @return bool
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function destroy(Eloquent $model)
|
||||
{
|
||||
@@ -31,10 +34,13 @@ class TransactionType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return \Eloquent
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function store(array $data)
|
||||
{
|
||||
@@ -42,11 +48,14 @@ class TransactionType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param Eloquent $model
|
||||
* @param array $data
|
||||
*
|
||||
* @return bool
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function update(Eloquent $model, array $data)
|
||||
{
|
||||
@@ -54,6 +63,8 @@ class TransactionType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Validates an array. Returns an array containing MessageBags
|
||||
* errors/warnings/successes.
|
||||
*
|
||||
@@ -61,6 +72,7 @@ class TransactionType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
*
|
||||
* @return array
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function validate(array $model)
|
||||
{
|
||||
@@ -68,12 +80,15 @@ class TransactionType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Returns an object with id $id.
|
||||
*
|
||||
* @param int $objectId
|
||||
*
|
||||
* @return \Eloquent
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function find($objectId)
|
||||
{
|
||||
@@ -96,17 +111,21 @@ class TransactionType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
'withdrawal' => 'Withdrawal',
|
||||
'deposit' => 'Deposit',
|
||||
];
|
||||
if(!isset($translation[$what])) {
|
||||
if (!isset($translation[$what])) {
|
||||
throw new FireflyException('Cannot find transaction type described as "' . e($what) . '".');
|
||||
}
|
||||
|
||||
return \TransactionType::whereType($translation[$what])->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* Returns all objects.
|
||||
*
|
||||
* @return Collection
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
@@ -114,10 +133,13 @@ class TransactionType implements CUDInterface, CommonDatabaseCallsInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param array $ids
|
||||
*
|
||||
* @return Collection
|
||||
* @throws NotImplementedException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function getByIds(array $ids)
|
||||
{
|
||||
|
||||
@@ -34,6 +34,8 @@ class PiggyBank
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param \TransactionJournal $journal
|
||||
*
|
||||
* @throws \FireflyIII\Exception\FireflyException
|
||||
@@ -109,6 +111,8 @@ class PiggyBank
|
||||
*/
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param \TransactionJournal $journal
|
||||
* @param int $piggyBankId
|
||||
*/
|
||||
@@ -176,6 +180,8 @@ class PiggyBank
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's 6. More than 5 but alright.
|
||||
*
|
||||
* Validates the presence of repetitions for all repeated expenses!
|
||||
*/
|
||||
public function validateRepeatedExpenses()
|
||||
@@ -185,32 +191,24 @@ class PiggyBank
|
||||
}
|
||||
/** @var \FireflyIII\Database\PiggyBank\RepeatedExpense $repository */
|
||||
$repository = \App::make('FireflyIII\Database\PiggyBank\RepeatedExpense');
|
||||
|
||||
$list = $repository->get();
|
||||
$today = Carbon::now();
|
||||
|
||||
/** @var \PiggyBank $entry */
|
||||
foreach ($list as $entry) {
|
||||
$start = $entry->startdate;
|
||||
$target = $entry->targetdate;
|
||||
// find a repetition on this date:
|
||||
$count = $entry->piggyBankrepetitions()->starts($start)->targets($target)->count();
|
||||
$count = $entry->piggyBankrepetitions()->starts($entry->startdate)->targets($entry->targetdate)->count();
|
||||
if ($count == 0) {
|
||||
$repetition = new \PiggyBankRepetition;
|
||||
$repetition->piggyBank()->associate($entry);
|
||||
$repetition->startdate = $start;
|
||||
$repetition->targetdate = $target;
|
||||
$repetition->startdate = $entry->startdate;
|
||||
$repetition->targetdate = $entry->targetdate;
|
||||
$repetition->currentamount = 0;
|
||||
$repetition->save();
|
||||
}
|
||||
// then continue and do something in the current relevant time frame.
|
||||
|
||||
$currentTarget = clone $target;
|
||||
$currentTarget = clone $entry->startdate;
|
||||
$currentStart = null;
|
||||
while ($currentTarget < $today) {
|
||||
$currentStart = \DateKit::subtractPeriod($currentTarget, $entry->rep_length, 0);
|
||||
$currentTarget = \DateKit::addPeriod($currentTarget, $entry->rep_length, 0);
|
||||
// create if not exists:
|
||||
$count = $entry->piggyBankRepetitions()->starts($currentStart)->targets($currentTarget)->count();
|
||||
if ($count == 0) {
|
||||
$repetition = new \PiggyBankRepetition;
|
||||
|
||||
@@ -32,6 +32,7 @@ class FF3ServiceProvider extends ServiceProvider
|
||||
/**
|
||||
* Return the services bla bla.
|
||||
*
|
||||
* @CodeCoverageIgnore
|
||||
* @return array
|
||||
*/
|
||||
public function provides()
|
||||
|
||||
@@ -24,169 +24,15 @@ class Form
|
||||
*/
|
||||
public static function ffAmount($name, $value = null, array $options = [])
|
||||
{
|
||||
$label = self::label($name, $options);
|
||||
$options = self::expandOptionArray($name, $label, $options);
|
||||
$classes = self::getHolderClasses($name);
|
||||
$value = self::fillFieldValue($name, $value);
|
||||
$options['step'] = 'any';
|
||||
$options['min'] = '0.01';
|
||||
|
||||
return self::ffInput('amount', $name, $value, $options);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $name
|
||||
* @param null $value
|
||||
* @param array $options
|
||||
* @param array $list
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public static function ffInput($type, $name, $value = null, array $options = [], $list = [])
|
||||
{
|
||||
/*
|
||||
* add some defaults to this method:
|
||||
*/
|
||||
$options['class'] = 'form-control';
|
||||
$options['id'] = 'ffInput_' . $name;
|
||||
$options['autocomplete'] = 'off';
|
||||
$label = self::label($name, $options);
|
||||
|
||||
/*
|
||||
* Make label and placeholder look nice.
|
||||
*/
|
||||
$options['placeholder'] = ucfirst($name);
|
||||
|
||||
/*
|
||||
* Get pre filled value:
|
||||
*/
|
||||
if (\Session::has('preFilled')) {
|
||||
$preFilled = \Session::get('preFilled');
|
||||
$value = isset($preFilled[$name]) && is_null($value) ? $preFilled[$name] : $value;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the value.
|
||||
*/
|
||||
if (!is_null(\Input::old($name))) {
|
||||
/*
|
||||
* Old value overrules $value.
|
||||
*/
|
||||
$value = \Input::old($name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get errors, warnings and successes from session:
|
||||
*/
|
||||
/** @var MessageBag $errors */
|
||||
$errors = \Session::get('errors');
|
||||
|
||||
/** @var MessageBag $warnings */
|
||||
$warnings = \Session::get('warnings');
|
||||
|
||||
/** @var MessageBag $successes */
|
||||
$successes = \Session::get('successes');
|
||||
|
||||
|
||||
/*
|
||||
* If errors, add some more classes.
|
||||
*/
|
||||
switch (true) {
|
||||
case (!is_null($errors) && $errors->has($name)):
|
||||
$classes = 'form-group has-error has-feedback';
|
||||
break;
|
||||
case (!is_null($warnings) && $warnings->has($name)):
|
||||
$classes = 'form-group has-warning has-feedback';
|
||||
break;
|
||||
case (!is_null($successes) && $successes->has($name)):
|
||||
$classes = 'form-group has-success has-feedback';
|
||||
break;
|
||||
default:
|
||||
$classes = 'form-group';
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add some HTML.
|
||||
*/
|
||||
$html = '<div class="' . $classes . '">';
|
||||
$html .= '<label for="' . $options['id'] . '" class="col-sm-4 control-label">' . $label . '</label>';
|
||||
$html .= '<div class="col-sm-8">';
|
||||
|
||||
|
||||
/*
|
||||
* Switch input type:
|
||||
*/
|
||||
unset($options['label']);
|
||||
switch ($type) {
|
||||
case 'text':
|
||||
$html .= \Form::input('text', $name, $value, $options);
|
||||
break;
|
||||
case 'amount':
|
||||
$html .= '<div class="input-group"><div class="input-group-addon">' . \Amount::getCurrencySymbol() . '</div>';
|
||||
$html .= \Form::input('number', $name, $value, $options);
|
||||
$html .= '</div>';
|
||||
break;
|
||||
case 'number':
|
||||
$html .= \Form::input('number', $name, $value, $options);
|
||||
break;
|
||||
case 'checkbox':
|
||||
$checked = $options['checked'];
|
||||
unset($options['placeholder'], $options['autocomplete'], $options['class']);
|
||||
$html .= '<div class="checkbox"><label>';
|
||||
$html .= \Form::checkbox($name, $value, $checked, $options);
|
||||
$html .= '</label></div>';
|
||||
|
||||
|
||||
break;
|
||||
case 'date':
|
||||
$html .= \Form::input('date', $name, $value, $options);
|
||||
break;
|
||||
case 'select':
|
||||
$html .= \Form::select($name, $list, $value, $options);
|
||||
break;
|
||||
default:
|
||||
throw new FireflyException('Cannot handle type "' . $type . '" in FFFormBuilder.');
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If errors, respond to them:
|
||||
*/
|
||||
|
||||
if (!is_null($errors)) {
|
||||
if ($errors->has($name)) {
|
||||
$html .= '<span class="glyphicon glyphicon-remove form-control-feedback"></span>';
|
||||
$html .= '<p class="text-danger">' . e($errors->first($name)) . '</p>';
|
||||
}
|
||||
}
|
||||
unset($errors);
|
||||
/*
|
||||
* If warnings, respond to them:
|
||||
*/
|
||||
|
||||
if (!is_null($warnings)) {
|
||||
if ($warnings->has($name)) {
|
||||
$html .= '<span class="glyphicon glyphicon-warning-sign form-control-feedback"></span>';
|
||||
$html .= '<p class="text-warning">' . e($warnings->first($name)) . '</p>';
|
||||
}
|
||||
}
|
||||
unset($warnings);
|
||||
|
||||
/*
|
||||
* If successes, respond to them:
|
||||
*/
|
||||
|
||||
if (!is_null($successes)) {
|
||||
if ($successes->has($name)) {
|
||||
$html .= '<span class="glyphicon glyphicon-ok form-control-feedback"></span>';
|
||||
$html .= '<p class="text-success">' . e($successes->first($name)) . '</p>';
|
||||
}
|
||||
}
|
||||
unset($successes);
|
||||
|
||||
$html .= '</div>';
|
||||
$html .= '</div>';
|
||||
$defaultCurrency = isset($options['currency']) ? $options['currency'] : \Amount::getDefaultCurrency();
|
||||
$currencies = \TransactionCurrency::orderBy('code','ASC')->get();
|
||||
$html = \View::make('form.amount', compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
|
||||
|
||||
return $html;
|
||||
|
||||
@@ -204,12 +50,81 @@ class Form
|
||||
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'];
|
||||
'account_from_id' => 'Account from', 'account_to_id' => 'Account to', 'account_id' => 'Asset account', 'budget_id' => 'Budget'
|
||||
, 'piggy_bank_id' => 'Piggy bank'];
|
||||
|
||||
|
||||
return isset($labels[$name]) ? $labels[$name] : str_replace('_', ' ', ucfirst($name));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $label
|
||||
* @param array $options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function expandOptionArray($name, $label, array $options)
|
||||
{
|
||||
$options['class'] = 'form-control';
|
||||
$options['id'] = 'ffInput_' . $name;
|
||||
$options['autocomplete'] = 'off';
|
||||
$options['placeholder'] = ucfirst($label);
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getHolderClasses($name)
|
||||
{
|
||||
/*
|
||||
* Get errors, warnings and successes from session:
|
||||
*/
|
||||
/** @var MessageBag $errors */
|
||||
$errors = \Session::get('errors');
|
||||
|
||||
/** @var MessageBag $successes */
|
||||
$successes = \Session::get('successes');
|
||||
|
||||
switch (true) {
|
||||
case (!is_null($errors) && $errors->has($name)):
|
||||
$classes = 'form-group has-error has-feedback';
|
||||
break;
|
||||
case (!is_null($successes) && $successes->has($name)):
|
||||
$classes = 'form-group has-success has-feedback';
|
||||
break;
|
||||
default:
|
||||
$classes = 'form-group';
|
||||
break;
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function fillFieldValue($name, $value)
|
||||
{
|
||||
if (\Session::has('preFilled')) {
|
||||
$preFilled = \Session::get('preFilled');
|
||||
$value = isset($preFilled[$name]) && is_null($value) ? $preFilled[$name] : $value;
|
||||
}
|
||||
if (!is_null(\Input::old($name))) {
|
||||
$value = \Input::old($name);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $value
|
||||
@@ -220,10 +135,15 @@ class Form
|
||||
*/
|
||||
public static function ffBalance($name, $value = null, array $options = [])
|
||||
{
|
||||
$label = self::label($name, $options);
|
||||
$options = self::expandOptionArray($name, $label, $options);
|
||||
$classes = self::getHolderClasses($name);
|
||||
$value = self::fillFieldValue($name, $value);
|
||||
$options['step'] = 'any';
|
||||
|
||||
return self::ffInput('amount', $name, $value, $options);
|
||||
|
||||
$defaultCurrency = isset($options['currency']) ? $options['currency'] : \Amount::getDefaultCurrency();
|
||||
$currencies = \TransactionCurrency::orderBy('code','ASC')->get();
|
||||
$html = \View::make('form.balance', compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,8 +158,16 @@ class Form
|
||||
public static function ffCheckbox($name, $value = 1, $checked = null, $options = [])
|
||||
{
|
||||
$options['checked'] = $checked === true ? true : null;
|
||||
$label = self::label($name, $options);
|
||||
$options = self::expandOptionArray($name, $label, $options);
|
||||
$classes = self::getHolderClasses($name);
|
||||
$value = self::fillFieldValue($name, $value);
|
||||
|
||||
return self::ffInput('checkbox', $name, $value, $options);
|
||||
unset($options['placeholder'], $options['autocomplete'], $options['class']);
|
||||
|
||||
$html = \View::make('form.checkbox', compact('classes', 'name', 'label', 'value', 'options'))->render();
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -252,7 +180,13 @@ class Form
|
||||
*/
|
||||
public static function ffDate($name, $value = null, array $options = [])
|
||||
{
|
||||
return self::ffInput('date', $name, $value, $options);
|
||||
$label = self::label($name, $options);
|
||||
$options = self::expandOptionArray($name, $label, $options);
|
||||
$classes = self::getHolderClasses($name);
|
||||
$value = self::fillFieldValue($name, $value);
|
||||
$html = \View::make('form.date', compact('classes', 'name', 'label', 'value', 'options'))->render();
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -265,9 +199,14 @@ class Form
|
||||
*/
|
||||
public static function ffInteger($name, $value = null, array $options = [])
|
||||
{
|
||||
$label = self::label($name, $options);
|
||||
$options = self::expandOptionArray($name, $label, $options);
|
||||
$classes = self::getHolderClasses($name);
|
||||
$value = self::fillFieldValue($name, $value);
|
||||
$options['step'] = '1';
|
||||
$html = \View::make('form.integer', compact('classes', 'name', 'label', 'value', 'options'))->render();
|
||||
|
||||
return self::ffInput('number', $name, $value, $options);
|
||||
return $html;
|
||||
|
||||
}
|
||||
|
||||
@@ -284,57 +223,9 @@ class Form
|
||||
{
|
||||
$previousValue = \Input::old('post_submit_action');
|
||||
$previousValue = is_null($previousValue) ? 'store' : $previousValue;
|
||||
/*
|
||||
* Store.
|
||||
*/
|
||||
switch ($type) {
|
||||
case 'create':
|
||||
$store = '<div class="form-group"><label for="' . $name . '_store" class="col-sm-4 control-label">Store</label>';
|
||||
$store .= '<div class="col-sm-8"><div class="radio"><label>';
|
||||
$store .= \Form::radio('post_submit_action', 'store', $previousValue == 'store', ['id' => $name . '_store']);
|
||||
$store .= 'Store ' . $name . '</label></div></div></div>';
|
||||
break;
|
||||
case 'update':
|
||||
$store = '<div class="form-group"><label for="' . $name . 'update" class="col-sm-4 control-label">Store</label>';
|
||||
$store .= '<div class="col-sm-8"><div class="radio"><label>';
|
||||
$store .= \Form::radio('post_submit_action', 'update', $previousValue == 'update' || $previousValue == 'store', ['id' => $name . '_update']);
|
||||
$store .= 'Update ' . $name . '</label></div></div></div>';
|
||||
break;
|
||||
default:
|
||||
throw new FireflyException('Cannot create ffOptionsList for option (store) ' . $type);
|
||||
break;
|
||||
}
|
||||
$html = \View::make('form.options', compact('type', 'name', 'previousValue'))->render();
|
||||
|
||||
/*
|
||||
* validate is always the same:
|
||||
*/
|
||||
$validate = '<div class="form-group"><label for="' . $name . 'validate_only" class="col-sm-4 control-label">Validate only';
|
||||
$validate .= '</label><div class="col-sm-8"><div class="radio"><label>';
|
||||
$validate .= \Form::radio('post_submit_action', 'validate_only', $previousValue == 'validate_only', ['id' => $name . '_validate_only']);
|
||||
$validate .= 'Only validate, do not save</label></div></div></div>';
|
||||
|
||||
/*
|
||||
* Store & return:
|
||||
*/
|
||||
switch ($type) {
|
||||
case 'create':
|
||||
$return = '<div class="form-group"><label for="' . $name . 'return_to_form" class="col-sm-4 control-label">';
|
||||
$return .= 'Return here</label><div class="col-sm-8"><div class="radio"><label>';
|
||||
$return .= \Form::radio('post_submit_action', 'create_another', $previousValue == 'create_another', ['id' => $name . '_create_another']);
|
||||
$return .= 'After storing, return here to create another one.</label></div></div></div>';
|
||||
break;
|
||||
case 'update':
|
||||
$return = '<div class="form-group"><label for="' . $name . 'return_to_edit" class="col-sm-4 control-label">';
|
||||
$return .= 'Return here</label><div class="col-sm-8"><div class="radio"><label>';
|
||||
$return .= \Form::radio('post_submit_action', 'return_to_edit', $previousValue == 'return_to_edit', ['id' => $name . '_return_to_edit']);
|
||||
$return .= 'After updating, return here.</label></div></div></div>';
|
||||
break;
|
||||
default:
|
||||
throw new FireflyException('Cannot create ffOptionsList for option (store+return) ' . $type);
|
||||
break;
|
||||
}
|
||||
|
||||
return $store . $validate . $return;
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -344,11 +235,16 @@ class Form
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public static function ffSelect($name, array $list = [], $selected = null, array $options = [])
|
||||
{
|
||||
return self::ffInput('select', $name, $selected, $options, $list);
|
||||
$label = self::label($name, $options);
|
||||
$options = self::expandOptionArray($name, $label, $options);
|
||||
$classes = self::getHolderClasses($name);
|
||||
$selected = self::fillFieldValue($name, $selected);
|
||||
$html = \View::make('form.select', compact('classes', 'name', 'label', 'selected', 'options', 'list'))->render();
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -361,9 +257,14 @@ class Form
|
||||
*/
|
||||
public static function ffTags($name, $value = null, array $options = [])
|
||||
{
|
||||
$label = self::label($name, $options);
|
||||
$options = self::expandOptionArray($name, $label, $options);
|
||||
$classes = self::getHolderClasses($name);
|
||||
$value = self::fillFieldValue($name, $value);
|
||||
$options['data-role'] = 'tagsinput';
|
||||
$html = \View::make('form.tags', compact('classes', 'name', 'label', 'value', 'options'))->render();
|
||||
|
||||
return self::ffInput('text', $name, $value, $options);
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -376,7 +277,13 @@ class Form
|
||||
*/
|
||||
public static function ffText($name, $value = null, array $options = [])
|
||||
{
|
||||
return self::ffInput('text', $name, $value, $options);
|
||||
$label = self::label($name, $options);
|
||||
$options = self::expandOptionArray($name, $label, $options);
|
||||
$classes = self::getHolderClasses($name);
|
||||
$value = self::fillFieldValue($name, $value);
|
||||
$html = \View::make('form.text', compact('classes', 'name', 'label', 'value', 'options'))->render();
|
||||
|
||||
return $html;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,14 +56,36 @@ class Related implements RelatedInterface
|
||||
}
|
||||
$exclude = array_unique($exclude);
|
||||
|
||||
$query = $this->getUser()->transactionjournals()
|
||||
->withRelevantData()
|
||||
->before($end)
|
||||
->after($start)
|
||||
->whereNotIn('id', $exclude)
|
||||
->where('description', 'LIKE', '%' . $query . '%')
|
||||
->get();
|
||||
/** @var Collection $collection */
|
||||
$collection = $this->getUser()->transactionjournals()
|
||||
->withRelevantData()
|
||||
->before($end)
|
||||
->where('encrypted', 0)
|
||||
->after($start)
|
||||
->whereNotIn('id', $exclude)
|
||||
->where('description', 'LIKE', '%' . $query . '%')
|
||||
->get();
|
||||
|
||||
return $query;
|
||||
// manually search encrypted entries:
|
||||
/** @var Collection $encryptedCollection */
|
||||
$encryptedCollection = $this->getUser()->transactionjournals()
|
||||
->withRelevantData()
|
||||
->before($end)
|
||||
->where('encrypted', 1)
|
||||
->after($start)
|
||||
->whereNotIn('id', $exclude)
|
||||
->get();
|
||||
$encrypted = $encryptedCollection->filter(
|
||||
function (\TransactionJournal $journal) use ($query) {
|
||||
$strPos = strpos($journal->description, $query);
|
||||
if ($strPos !== false) {
|
||||
return $journal;
|
||||
}
|
||||
}
|
||||
);
|
||||
$collected = $collection->merge($encrypted);
|
||||
|
||||
|
||||
return $collected;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,15 +12,6 @@ use Illuminate\Support\Collection;
|
||||
class Helper implements HelperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $what
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getTransactionTypeIdByWhat($what) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the account_id, which is the asset account that paid for the transaction.
|
||||
@@ -49,7 +40,7 @@ class Helper implements HelperInterface
|
||||
/** @var \FireflyIII\Database\Account\Account $accountRepository */
|
||||
$accountRepository = \App::make('FireflyIII\Database\Account\Account');
|
||||
|
||||
return $accountRepository->getAssetAccounts();
|
||||
return $accountRepository->getAccountsByType(['Default account', 'Asset account']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,4 +81,5 @@ class Helper implements HelperInterface
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -22,13 +22,6 @@ interface HelperInterface
|
||||
*/
|
||||
public function getAssetAccount($what, Collection $transactions);
|
||||
|
||||
/**
|
||||
* @param $what
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getTransactionTypeIdByWhat($what);
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
|
||||
@@ -7,12 +7,12 @@ use FireflyIII\Database\Account\Account as AccountRepository;
|
||||
use FireflyIII\Database\SwitchUser;
|
||||
use FireflyIII\Database\TransactionJournal\TransactionJournal as JournalRepository;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class Report
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
*
|
||||
* Class Report
|
||||
*
|
||||
* @package FireflyIII\Report
|
||||
*/
|
||||
@@ -45,6 +45,8 @@ class Report implements ReportInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* This methods fails to take in account transfers FROM shared accounts.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $limit
|
||||
@@ -115,7 +117,7 @@ class Report implements ReportInterface
|
||||
$accounts = [];
|
||||
/** @var \Account $account */
|
||||
foreach ($list as $account) {
|
||||
$id = intval($account->id);
|
||||
$id = intval($account->id);
|
||||
/** @noinspection PhpParamsInspection */
|
||||
$accounts[$id] = [
|
||||
'name' => $account->name,
|
||||
@@ -205,18 +207,18 @@ class Report implements ReportInterface
|
||||
$set = $this->_queries->journalsByExpenseAccount($start, $end);
|
||||
$expenses = $this->_helper->makeArray($set);
|
||||
|
||||
$alt = $this->_queries->sharedExpenses($start, $end);
|
||||
$transfers = $this->_helper->makeArray($alt);
|
||||
|
||||
$expenses[-1] = [
|
||||
'amount' => 0,
|
||||
'name' => 'Transfers to shared',
|
||||
'spent' => 0
|
||||
];
|
||||
|
||||
foreach ($transfers as $transfer) {
|
||||
$expenses[-1]['amount'] += $transfer['amount'];
|
||||
}
|
||||
// $alt = $this->_queries->sharedExpenses($start, $end);
|
||||
// $transfers = $this->_helper->makeArray($alt);
|
||||
//
|
||||
// $expenses[-1] = [
|
||||
// 'amount' => 0,
|
||||
// 'name' => 'Transfers to shared',
|
||||
// 'spent' => 0
|
||||
// ];
|
||||
//
|
||||
// foreach ($transfers as $transfer) {
|
||||
// $expenses[-1]['amount'] += $transfer['amount'];
|
||||
// }
|
||||
|
||||
$expenses = $this->_helper->sortArray($expenses);
|
||||
$limited = $this->_helper->limitArray($expenses, $limit);
|
||||
@@ -226,6 +228,10 @@ class Report implements ReportInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets all incomes (journals) in a list.
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @param bool $shared
|
||||
*
|
||||
@@ -239,46 +245,48 @@ class Report implements ReportInterface
|
||||
$end->endOfMonth();
|
||||
$userId = $this->_accounts->getUser()->id;
|
||||
|
||||
return $this->_queries->incomeByPeriod($start, $end);
|
||||
|
||||
$list = \TransactionJournal::leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')
|
||||
->leftJoin(
|
||||
'account_meta', function (JoinClause $join) {
|
||||
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->transactionTypes(['Deposit'])
|
||||
->where('transaction_journals.user_id', $userId)
|
||||
->where('transactions.amount', '>', 0)
|
||||
->where('transaction_journals.user_id', \Auth::user()->id)
|
||||
->where('account_meta.data', '!=', '"sharedExpense"')
|
||||
->orderBy('date', 'ASC')
|
||||
->before($end)->after($start)->get(['transaction_journals.*']);
|
||||
// $list = \TransactionJournal::leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
// ->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')
|
||||
// ->leftJoin(
|
||||
// 'account_meta', function (JoinClause $join) {
|
||||
// $join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole');
|
||||
// }
|
||||
// )
|
||||
// ->transactionTypes(['Deposit'])
|
||||
// ->where('transaction_journals.user_id', $userId)
|
||||
// ->where('transactions.amount', '>', 0)
|
||||
// ->where('transaction_journals.user_id', \Auth::user()->id)
|
||||
// ->where('account_meta.data', '!=', '"sharedExpense"')
|
||||
// ->orderBy('date', 'ASC')
|
||||
// ->before($end)->after($start)->get(['transaction_journals.*']);
|
||||
//
|
||||
// // incoming from a shared account: it's profit (income):
|
||||
// $transfers = \TransactionJournal::withRelevantData()
|
||||
// ->leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
// ->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')
|
||||
// ->leftJoin(
|
||||
// 'account_meta', function (JoinClause $join) {
|
||||
// $join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole');
|
||||
// }
|
||||
// )
|
||||
// ->transactionTypes(['Transfer'])
|
||||
// ->where('transaction_journals.user_id', $userId)
|
||||
// ->where('transactions.amount', '<', 0)
|
||||
// ->where('account_meta.data', '=', '"sharedExpense"')
|
||||
// ->orderBy('date', 'ASC')
|
||||
// ->before($end)->after($start)->get(['transaction_journals.*']);
|
||||
//
|
||||
// $list = $list->merge($transfers);
|
||||
// $list->sort(
|
||||
// function (\TransactionJournal $journal) {
|
||||
// return $journal->date->format('U');
|
||||
// }
|
||||
// );
|
||||
//
|
||||
// return $list;
|
||||
|
||||
// incoming from a shared account: it's profit (income):
|
||||
$transfers = \TransactionJournal::withRelevantData()
|
||||
->leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||
->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')
|
||||
->leftJoin(
|
||||
'account_meta', function (JoinClause $join) {
|
||||
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->transactionTypes(['Transfer'])
|
||||
->where('transaction_journals.user_id', $userId)
|
||||
->where('transactions.amount', '<', 0)
|
||||
->where('account_meta.data', '=', '"sharedExpense"')
|
||||
->orderBy('date', 'ASC')
|
||||
->before($end)->after($start)->get(['transaction_journals.*']);
|
||||
|
||||
$list = $list->merge($transfers);
|
||||
$list->sort(
|
||||
function (\TransactionJournal $journal) {
|
||||
return $journal->date->format('U');
|
||||
}
|
||||
);
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -295,21 +303,21 @@ class Report implements ReportInterface
|
||||
|
||||
\PiggyBank::
|
||||
leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
|
||||
->where('accounts.user_id', \Auth::user()->id)
|
||||
->where('repeats', 0)
|
||||
->where(
|
||||
function (Builder $query) use ($start, $end) {
|
||||
$query->whereNull('piggy_banks.deleted_at');
|
||||
$query->orWhere(
|
||||
function (Builder $query) use ($start, $end) {
|
||||
$query->whereNotNull('piggy_banks.deleted_at');
|
||||
$query->where('piggy_banks.deleted_at', '>=', $start->format('Y-m-d 00:00:00'));
|
||||
$query->where('piggy_banks.deleted_at', '<=', $end->format('Y-m-d 00:00:00'));
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
->get(['piggy_banks.*']);
|
||||
->where('accounts.user_id', \Auth::user()->id)
|
||||
->where('repeats', 0)
|
||||
->where(
|
||||
function (Builder $query) use ($start, $end) {
|
||||
$query->whereNull('piggy_banks.deleted_at');
|
||||
$query->orWhere(
|
||||
function (Builder $query) use ($start, $end) {
|
||||
$query->whereNotNull('piggy_banks.deleted_at');
|
||||
$query->where('piggy_banks.deleted_at', '>=', $start->format('Y-m-d 00:00:00'));
|
||||
$query->where('piggy_banks.deleted_at', '<=', $end->format('Y-m-d 00:00:00'));
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
->get(['piggy_banks.*']);
|
||||
|
||||
|
||||
}
|
||||
@@ -353,6 +361,7 @@ class Report implements ReportInterface
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $limit
|
||||
@@ -361,8 +370,7 @@ class Report implements ReportInterface
|
||||
*/
|
||||
public function revenueGroupedByAccount(Carbon $start, Carbon $end, $limit = 15)
|
||||
{
|
||||
return $this->_queries->journalsByRevenueAccount($start, $end);
|
||||
|
||||
return $this->_queries->journalsByRevenueAccount($start, $end, $limit);
|
||||
|
||||
|
||||
}
|
||||
@@ -387,7 +395,7 @@ class Report implements ReportInterface
|
||||
$sharedAccounts[] = $account->id;
|
||||
}
|
||||
|
||||
$accounts = $this->_accounts->getAssetAccounts()->filter(
|
||||
$accounts = $this->_accounts->getAccountsByType(['Default account', 'Asset account'])->filter(
|
||||
function (\Account $account) use ($sharedAccounts) {
|
||||
if (!in_array($account->id, $sharedAccounts)) {
|
||||
return $account;
|
||||
|
||||
@@ -68,16 +68,13 @@ class ReportQuery implements ReportQueryInterface
|
||||
}
|
||||
)
|
||||
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'otherJournals.id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->before($end)->after($start)
|
||||
->where('transaction_types.type', 'Withdrawal')
|
||||
->where('transaction_journals.user_id', \Auth::user()->id)
|
||||
->whereNull('budget_transaction_journal.budget_id')
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
->whereNull('budget_transaction_journal.budget_id')->whereNull('transaction_journals.deleted_at')
|
||||
->whereNull('otherJournals.deleted_at')
|
||||
->where('transactions.account_id', $account->id)
|
||||
->whereNotNull('transaction_group_transaction_journal.transaction_group_id')
|
||||
->groupBy('transaction_journals.id')
|
||||
->whereNotNull('transaction_group_transaction_journal.transaction_group_id')->groupBy('transaction_journals.id')
|
||||
->get(
|
||||
[
|
||||
'transaction_journals.id as transferId',
|
||||
@@ -202,6 +199,70 @@ class ReportQuery implements ReportQueryInterface
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns all "income" journals in a certain period, which are both transfers from a shared account
|
||||
* and "ordinary" deposits. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does
|
||||
* not group and returns different fields.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function incomeByPeriod(Carbon $start, Carbon $end)
|
||||
{
|
||||
return \TransactionJournal::
|
||||
leftJoin(
|
||||
'transactions as t_from', function (JoinClause $join) {
|
||||
$join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts as ac_from', 't_from.account_id', '=', 'ac_from.id')
|
||||
->leftJoin(
|
||||
'account_meta as acm_from', function (JoinClause $join) {
|
||||
$join->on('ac_from.id', '=', 'acm_from.account_id')->where('acm_from.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'transactions as t_to', function (JoinClause $join) {
|
||||
$join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts as ac_to', 't_to.account_id', '=', 'ac_to.id')
|
||||
->leftJoin(
|
||||
'account_meta as acm_to', function (JoinClause $join) {
|
||||
$join->on('ac_to.id', '=', 'acm_to.account_id')->where('acm_to.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->where(
|
||||
function ($query) {
|
||||
$query->where(
|
||||
function ($q) {
|
||||
$q->where('transaction_types.type', 'Deposit');
|
||||
$q->where('acm_to.data', '!=', '"sharedExpense"');
|
||||
}
|
||||
);
|
||||
$query->orWhere(
|
||||
function ($q) {
|
||||
$q->where('transaction_types.type', 'Transfer');
|
||||
$q->where('acm_from.data', '=', '"sharedExpense"');
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
->before($end)->after($start)
|
||||
->where('transaction_journals.user_id', \Auth::user()->id)
|
||||
->groupBy('t_from.account_id')->orderBy('transaction_journals.date')
|
||||
->get(
|
||||
['transaction_journals.id',
|
||||
'transaction_journals.description',
|
||||
'transaction_types.type',
|
||||
't_to.amount', 'transaction_journals.date', 't_from.account_id as account_id',
|
||||
'ac_from.name as name']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of expenses grouped by the budget they were filed under.
|
||||
*
|
||||
@@ -278,6 +339,8 @@ class ReportQuery implements ReportQueryInterface
|
||||
* Gets a list of expense accounts and the expenses therein, grouped by that expense account.
|
||||
* This result excludes transfers to shared accounts which are expenses, technically.
|
||||
*
|
||||
* So now it will include them!
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
@@ -309,8 +372,25 @@ class ReportQuery implements ReportQueryInterface
|
||||
}
|
||||
)
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->where('transaction_types.type', 'Withdrawal')
|
||||
->where('acm_from.data', '!=', '"sharedExpense"')
|
||||
|
||||
->where(
|
||||
function ($query) {
|
||||
$query->where(
|
||||
function ($q) {
|
||||
$q->where('transaction_types.type', 'Withdrawal');
|
||||
$q->where('acm_from.data', '!=', '"sharedExpense"');
|
||||
}
|
||||
);
|
||||
$query->orWhere(
|
||||
function ($q) {
|
||||
$q->where('transaction_types.type', 'Transfer');
|
||||
$q->where('acm_to.data', '=', '"sharedExpense"');
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
->before($end)
|
||||
->after($start)
|
||||
->where('transaction_journals.user_id', \Auth::user()->id)
|
||||
@@ -324,10 +404,11 @@ class ReportQuery implements ReportQueryInterface
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $limit
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsByRevenueAccount(Carbon $start, Carbon $end)
|
||||
public function journalsByRevenueAccount(Carbon $start, Carbon $end, $limit = 15)
|
||||
{
|
||||
return \TransactionJournal::
|
||||
leftJoin(
|
||||
@@ -353,8 +434,22 @@ class ReportQuery implements ReportQueryInterface
|
||||
}
|
||||
)
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->where('transaction_types.type', 'Deposit')
|
||||
->where('acm_to.data', '!=', '"sharedExpense"')
|
||||
->where(
|
||||
function ($query) {
|
||||
$query->where(
|
||||
function ($q) {
|
||||
$q->where('transaction_types.type', 'Deposit');
|
||||
$q->where('acm_to.data', '!=', '"sharedExpense"');
|
||||
}
|
||||
);
|
||||
$query->orWhere(
|
||||
function ($q) {
|
||||
$q->where('transaction_types.type', 'Transfer');
|
||||
$q->where('acm_from.data', '=', '"sharedExpense"');
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
->before($end)->after($start)
|
||||
->where('transaction_journals.user_id', \Auth::user()->id)
|
||||
->groupBy('t_from.account_id')->orderBy('amount')
|
||||
|
||||
@@ -117,6 +117,18 @@ interface ReportQueryInterface
|
||||
*/
|
||||
public function journalsByRevenueAccount(Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* This method returns all "income" journals in a certain period, which are both transfers from a shared account
|
||||
* and "ordinary" deposits. The query used is almost equal to ReportQueryInterface::journalsByRevenueAccount but it does
|
||||
* not group and returns different fields.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function incomeByPeriod(Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* With an equally misleading name, this query returns are transfers to shared accounts. These are considered
|
||||
* expenses.
|
||||
|
||||
@@ -80,6 +80,8 @@ class Search
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param array $words
|
||||
*
|
||||
* @return Collection
|
||||
|
||||
@@ -3,6 +3,8 @@ namespace FireflyIII\Shared\Mail;
|
||||
|
||||
use Swift_RfcComplianceException;
|
||||
use Illuminate\Mail\Message;
|
||||
use Swift_TransportException;
|
||||
|
||||
/**
|
||||
* Class Registration
|
||||
*
|
||||
@@ -57,7 +59,16 @@ class Registration implements RegistrationInterface
|
||||
}
|
||||
);
|
||||
} catch (Swift_RfcComplianceException $e) {
|
||||
\Log::error($e->getMessage());
|
||||
return false;
|
||||
} catch(Swift_TransportException $e) {
|
||||
\Log::error($e->getMessage());
|
||||
return false;
|
||||
} catch(\Exception $e) {
|
||||
\Log::error($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
@@ -84,7 +95,16 @@ class Registration implements RegistrationInterface
|
||||
}
|
||||
);
|
||||
} catch (Swift_RfcComplianceException $e) {
|
||||
\Log::error($e->getMessage());
|
||||
return false;
|
||||
} catch(Swift_TransportException $e) {
|
||||
\Log::error($e->getMessage());
|
||||
return false;
|
||||
} catch(\Exception $e) {
|
||||
\Log::error($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ use FireflyIII\Exception\FireflyException;
|
||||
class Date
|
||||
{
|
||||
/**
|
||||
* @param Carbon $theDate
|
||||
* @param Carbon $theDate
|
||||
* @param $repeatFreq
|
||||
* @param $skip
|
||||
*
|
||||
@@ -25,41 +25,37 @@ class Date
|
||||
$date = clone $theDate;
|
||||
$add = ($skip + 1);
|
||||
|
||||
switch ($repeatFreq) {
|
||||
default:
|
||||
throw new FireflyException('Cannot do addPeriod for $repeat_freq "' . $repeatFreq . '"');
|
||||
break;
|
||||
case 'daily':
|
||||
$date->addDays($add);
|
||||
break;
|
||||
case 'week':
|
||||
case 'weekly':
|
||||
$date->addWeeks($add);
|
||||
break;
|
||||
case 'month':
|
||||
case 'monthly':
|
||||
$date->addMonths($add);
|
||||
break;
|
||||
case 'quarter':
|
||||
case 'quarterly':
|
||||
$months = $add * 3;
|
||||
$date->addMonths($months);
|
||||
break;
|
||||
case 'half-year':
|
||||
$months = $add * 6;
|
||||
$date->addMonths($months);
|
||||
break;
|
||||
case 'year':
|
||||
case 'yearly':
|
||||
$date->addYears($add);
|
||||
break;
|
||||
$functionMap = [
|
||||
'daily' => 'addDays',
|
||||
'weekly' => 'addWeeks',
|
||||
'week' => 'addWeeks',
|
||||
'month' => 'addMonths',
|
||||
'monthly' => 'addMonths',
|
||||
'quarter' => 'addMonths',
|
||||
'quarterly' => 'addMonths',
|
||||
'half-year' => 'addMonths',
|
||||
'year' => 'addYears',
|
||||
'yearly' => 'addYears',
|
||||
];
|
||||
$modifierMap = [
|
||||
'quarter' => 3,
|
||||
'quarterly' => 3,
|
||||
'half-year' => 6,
|
||||
];
|
||||
if (!isset($functionMap[$repeatFreq])) {
|
||||
throw new FireflyException('Cannot do addPeriod for $repeat_freq "' . $repeatFreq . '"');
|
||||
}
|
||||
if (isset($modifierMap[$repeatFreq])) {
|
||||
$add = $add * $modifierMap[$repeatFreq];
|
||||
}
|
||||
$function = $functionMap[$repeatFreq];
|
||||
$date->$function($add);
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $theCurrentEnd
|
||||
* @param Carbon $theCurrentEnd
|
||||
* @param $repeatFreq
|
||||
*
|
||||
* @return Carbon
|
||||
@@ -68,78 +64,81 @@ class Date
|
||||
public function endOfPeriod(Carbon $theCurrentEnd, $repeatFreq)
|
||||
{
|
||||
$currentEnd = clone $theCurrentEnd;
|
||||
switch ($repeatFreq) {
|
||||
default:
|
||||
throw new FireflyException('Cannot do endOfPeriod for $repeat_freq ' . $repeatFreq);
|
||||
break;
|
||||
case 'daily':
|
||||
$currentEnd->addDay();
|
||||
break;
|
||||
case 'week':
|
||||
case 'weekly':
|
||||
$currentEnd->addWeek()->subDay();
|
||||
break;
|
||||
case 'month':
|
||||
case 'monthly':
|
||||
$currentEnd->addMonth()->subDay();
|
||||
break;
|
||||
case 'quarter':
|
||||
case 'quarterly':
|
||||
$currentEnd->addMonths(3)->subDay();
|
||||
break;
|
||||
case 'half-year':
|
||||
$currentEnd->addMonths(6)->subDay();
|
||||
break;
|
||||
case 'year':
|
||||
case 'yearly':
|
||||
$currentEnd->addYear()->subDay();
|
||||
break;
|
||||
|
||||
$functionMap = [
|
||||
'daily' => 'addDay',
|
||||
'week' => 'addWeek',
|
||||
'weekly' => 'addWeek',
|
||||
'month' => 'addMonth',
|
||||
'monthly' => 'addMonth',
|
||||
'quarter' => 'addMonths',
|
||||
'quarterly' => 'addMonths',
|
||||
'half-year' => 'addMonths',
|
||||
'year' => 'addYear',
|
||||
'yearly' => 'addYear',
|
||||
];
|
||||
$modifierMap = [
|
||||
'quarter' => 3,
|
||||
'quarterly' => 3,
|
||||
'half-year' => 6,
|
||||
];
|
||||
|
||||
$subDay = ['week', 'weekly', 'month', 'monthly', 'quarter', 'quarterly', 'half-year', 'year', 'yearly'];
|
||||
|
||||
if (!isset($functionMap[$repeatFreq])) {
|
||||
throw new FireflyException('Cannot do endOfPeriod for $repeat_freq ' . $repeatFreq);
|
||||
}
|
||||
$function = $functionMap[$repeatFreq];
|
||||
if (isset($modifierMap[$repeatFreq])) {
|
||||
$currentEnd->$function($modifierMap[$repeatFreq]);
|
||||
} else {
|
||||
$currentEnd->$function();
|
||||
}
|
||||
if (in_array($repeatFreq, $subDay)) {
|
||||
$currentEnd->subDay();
|
||||
}
|
||||
|
||||
return $currentEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $theCurrentEnd
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param Carbon $theCurrentEnd
|
||||
* @param $repeatFreq
|
||||
* @param Carbon $maxDate
|
||||
* @param Carbon $maxDate
|
||||
*
|
||||
* @return Carbon
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function endOfX(Carbon $theCurrentEnd, $repeatFreq, Carbon $maxDate)
|
||||
{
|
||||
$functionMap = [
|
||||
'daily' => 'endOfDay',
|
||||
'week' => 'endOfWeek',
|
||||
'weekly' => 'endOfWeek',
|
||||
'month' => 'endOfMonth',
|
||||
'monthly' => 'endOfMonth',
|
||||
'quarter' => 'lastOfQuarter',
|
||||
'quarterly' => 'lastOfQuarter',
|
||||
'year' => 'endOfYear',
|
||||
'yearly' => 'endOfYear',
|
||||
];
|
||||
$specials = ['mont', 'monthly'];
|
||||
|
||||
$currentEnd = clone $theCurrentEnd;
|
||||
switch ($repeatFreq) {
|
||||
default:
|
||||
throw new FireflyException('Cannot do endOfPeriod for $repeat_freq ' . $repeatFreq);
|
||||
break;
|
||||
case 'daily':
|
||||
$currentEnd->endOfDay();
|
||||
break;
|
||||
case 'week':
|
||||
case 'weekly':
|
||||
$currentEnd->endOfWeek();
|
||||
break;
|
||||
case 'month':
|
||||
case 'monthly':
|
||||
$currentEnd->endOfMonth();
|
||||
break;
|
||||
case 'quarter':
|
||||
case 'quarterly':
|
||||
$currentEnd->lastOfQuarter();
|
||||
break;
|
||||
case 'half-year':
|
||||
$month = intval($theCurrentEnd->format('m'));
|
||||
$currentEnd->endOfYear();
|
||||
if ($month <= 6) {
|
||||
$currentEnd->subMonths(6);
|
||||
}
|
||||
break;
|
||||
case 'year':
|
||||
case 'yearly':
|
||||
$currentEnd->endOfYear();
|
||||
break;
|
||||
|
||||
if (isset($functionMap[$repeatFreq])) {
|
||||
$function = $functionMap[$repeatFreq];
|
||||
$currentEnd->$function();
|
||||
|
||||
}
|
||||
if (isset($specials[$repeatFreq])) {
|
||||
$month = intval($theCurrentEnd->format('m'));
|
||||
$currentEnd->endOfYear();
|
||||
if ($month <= 6) {
|
||||
$currentEnd->subMonths(6);
|
||||
}
|
||||
}
|
||||
if ($currentEnd > $maxDate) {
|
||||
return clone $maxDate;
|
||||
@@ -149,7 +148,7 @@ class Date
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
* @param Carbon $date
|
||||
* @param $repeatFrequency
|
||||
*
|
||||
* @return string
|
||||
@@ -157,33 +156,25 @@ class Date
|
||||
*/
|
||||
public function periodShow(Carbon $date, $repeatFrequency)
|
||||
{
|
||||
switch ($repeatFrequency) {
|
||||
default:
|
||||
throw new FireflyException('No date formats for frequency "' . $repeatFrequency . '"!');
|
||||
break;
|
||||
case 'daily':
|
||||
return $date->format('j F Y');
|
||||
break;
|
||||
case 'week':
|
||||
case 'weekly':
|
||||
return $date->format('\W\e\e\k W, Y');
|
||||
break;
|
||||
case 'quarter':
|
||||
return $date->format('F Y');
|
||||
break;
|
||||
case 'monthly':
|
||||
case 'month':
|
||||
return $date->format('F Y');
|
||||
break;
|
||||
case 'year':
|
||||
case 'yearly':
|
||||
return $date->format('Y');
|
||||
break;
|
||||
$formatMap = [
|
||||
'daily' => 'j F Y',
|
||||
'week' => '\W\e\e\k W, Y',
|
||||
'weekly' => '\W\e\e\k W, Y',
|
||||
'quarter' => 'F Y',
|
||||
'month' => 'F Y',
|
||||
'monthly' => 'F Y',
|
||||
'year' => 'Y',
|
||||
'yearly' => 'Y',
|
||||
|
||||
];
|
||||
if (isset($formatMap[$repeatFrequency])) {
|
||||
return $date->format($formatMap[$repeatFrequency]);
|
||||
}
|
||||
throw new FireflyException('No date formats for frequency "' . $repeatFrequency . '"!');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $theDate
|
||||
* @param Carbon $theDate
|
||||
* @param $repeatFreq
|
||||
*
|
||||
* @return Carbon
|
||||
@@ -192,43 +183,38 @@ class Date
|
||||
public function startOfPeriod(Carbon $theDate, $repeatFreq)
|
||||
{
|
||||
$date = clone $theDate;
|
||||
switch ($repeatFreq) {
|
||||
default:
|
||||
throw new FireflyException('Cannot do startOfPeriod for $repeat_freq ' . $repeatFreq);
|
||||
break;
|
||||
case 'daily':
|
||||
$date->startOfDay();
|
||||
break;
|
||||
case 'week':
|
||||
case 'weekly':
|
||||
$date->startOfWeek();
|
||||
break;
|
||||
case 'month':
|
||||
case 'monthly':
|
||||
$date->startOfMonth();
|
||||
break;
|
||||
case 'quarter':
|
||||
case 'quarterly':
|
||||
$date->firstOfQuarter();
|
||||
break;
|
||||
case 'half-year':
|
||||
$month = intval($date->format('m'));
|
||||
$date->startOfYear();
|
||||
if ($month >= 7) {
|
||||
$date->addMonths(6);
|
||||
}
|
||||
break;
|
||||
case 'year':
|
||||
case 'yearly':
|
||||
$date->startOfYear();
|
||||
break;
|
||||
}
|
||||
|
||||
return $date;
|
||||
$functionMap = [
|
||||
'daily' => 'startOfDay',
|
||||
'week' => 'startOfWeek',
|
||||
'weekly' => 'startOfWeek',
|
||||
'month' => 'startOfMonth',
|
||||
'monthly' => 'startOfMonth',
|
||||
'quarter' => 'firstOfQuarter',
|
||||
'quartly' => 'firstOfQuarter',
|
||||
'year' => 'startOfYear',
|
||||
'yearly' => 'startOfYear',
|
||||
];
|
||||
if (isset($functionMap[$repeatFreq])) {
|
||||
$function = $functionMap[$repeatFreq];
|
||||
$date->$function();
|
||||
|
||||
return $date;
|
||||
}
|
||||
if ($repeatFreq == 'half-year') {
|
||||
$month = intval($date->format('m'));
|
||||
$date->startOfYear();
|
||||
if ($month >= 7) {
|
||||
$date->addMonths(6);
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
throw new FireflyException('Cannot do startOfPeriod for $repeat_freq ' . $repeatFreq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $theDate
|
||||
* @param Carbon $theDate
|
||||
* @param $repeatFreq
|
||||
* @param int $subtract
|
||||
*
|
||||
@@ -238,38 +224,35 @@ class Date
|
||||
public function subtractPeriod(Carbon $theDate, $repeatFreq, $subtract = 1)
|
||||
{
|
||||
$date = clone $theDate;
|
||||
switch ($repeatFreq) {
|
||||
default:
|
||||
throw new FireflyException('Cannot do subtractPeriod for $repeat_freq ' . $repeatFreq);
|
||||
break;
|
||||
case 'day':
|
||||
case 'daily':
|
||||
$date->subDays($subtract);
|
||||
break;
|
||||
case 'week':
|
||||
case 'weekly':
|
||||
$date->subWeeks($subtract);
|
||||
break;
|
||||
case 'month':
|
||||
case 'monthly':
|
||||
$date->subMonths($subtract);
|
||||
break;
|
||||
case 'quarter':
|
||||
case 'quarterly':
|
||||
$months = $subtract * 3;
|
||||
$date->subMonths($months);
|
||||
break;
|
||||
case 'half-year':
|
||||
$months = $subtract * 6;
|
||||
$date->subMonths($months);
|
||||
break;
|
||||
case 'year':
|
||||
case 'yearly':
|
||||
$date->subYears($subtract);
|
||||
break;
|
||||
|
||||
$functionMap = [
|
||||
'daily' => 'subDays',
|
||||
'week' => 'subWeeks',
|
||||
'weekly' => 'subWeeks',
|
||||
'month' => 'subMonths',
|
||||
'monthly' => 'subMonths',
|
||||
'year' => 'subYears',
|
||||
'yearly' => 'subYears',
|
||||
];
|
||||
$modifierMap = [
|
||||
'quarter' => 3,
|
||||
'quarterly' => 3,
|
||||
'half-year' => 6,
|
||||
];
|
||||
if (isset($functionMap[$repeatFreq])) {
|
||||
$function = $functionMap[$repeatFreq];
|
||||
$date->$function($subtract);
|
||||
|
||||
return $date;
|
||||
}
|
||||
if (isset($modifierMap[$repeatFreq])) {
|
||||
$subtract = $subtract * $modifierMap[$repeatFreq];
|
||||
$date->subMonths($subtract);
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
return $date;
|
||||
throw new FireflyException('Cannot do subtractPeriod for $repeat_freq ' . $repeatFreq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,36 +69,29 @@ class Filter
|
||||
*/
|
||||
protected function updateStartDate($range, Carbon $start)
|
||||
{
|
||||
switch ($range) {
|
||||
default:
|
||||
throw new FireflyException('updateStartDate cannot handle $range ' . $range);
|
||||
break;
|
||||
case '1D':
|
||||
$start->startOfDay();
|
||||
break;
|
||||
case '1W':
|
||||
$start->startOfWeek();
|
||||
break;
|
||||
case '1M':
|
||||
$start->startOfMonth();
|
||||
break;
|
||||
case '3M':
|
||||
$start->firstOfQuarter();
|
||||
break;
|
||||
case '6M':
|
||||
if (intval($start->format('m')) >= 7) {
|
||||
$start->startOfYear()->addMonths(6);
|
||||
} else {
|
||||
$start->startOfYear();
|
||||
}
|
||||
break;
|
||||
case '1Y':
|
||||
$start->startOfYear();
|
||||
break;
|
||||
$functionMap = [
|
||||
'1D' => 'startOfDay',
|
||||
'1W' => 'startOfWeek',
|
||||
'1M' => 'startOfMonth',
|
||||
'3M' => 'firstOfQuarter',
|
||||
'1Y' => 'startOfYear',
|
||||
];
|
||||
if (isset($functionMap[$range])) {
|
||||
$function = $functionMap[$range];
|
||||
$start->$function();
|
||||
|
||||
return $start;
|
||||
}
|
||||
if ($range == '6M') {
|
||||
if (intval($start->format('m')) >= 7) {
|
||||
$start->startOfYear()->addMonths(6);
|
||||
} else {
|
||||
$start->startOfYear();
|
||||
}
|
||||
|
||||
return $start;
|
||||
|
||||
return $start;
|
||||
}
|
||||
throw new FireflyException('updateStartDate cannot handle $range ' . $range);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,40 +103,36 @@ class Filter
|
||||
*/
|
||||
protected function updateEndDate($range, Carbon $start)
|
||||
{
|
||||
$end = clone $start;
|
||||
switch ($range) {
|
||||
default:
|
||||
throw new FireflyException('updateEndDate cannot handle $range ' . $range);
|
||||
break;
|
||||
case '1D':
|
||||
$end->endOfDay();
|
||||
break;
|
||||
case '1W':
|
||||
$end->endOfWeek();
|
||||
break;
|
||||
case '1M':
|
||||
$end->endOfMonth();
|
||||
break;
|
||||
case '3M':
|
||||
$end->lastOfQuarter();
|
||||
break;
|
||||
case '6M':
|
||||
if (intval($start->format('m')) >= 7) {
|
||||
$end->endOfYear();
|
||||
} else {
|
||||
$end->startOfYear()->addMonths(6);
|
||||
}
|
||||
break;
|
||||
case '1Y':
|
||||
$end->endOfYear();
|
||||
break;
|
||||
$functionMap = [
|
||||
'1D' => 'endOfDay',
|
||||
'1W' => 'endOfWeek',
|
||||
'1M' => 'endOfMonth',
|
||||
'3M' => 'lastOfQuarter',
|
||||
'1Y' => 'endOfYear',
|
||||
];
|
||||
$end = clone $start;
|
||||
|
||||
if (isset($functionMap[$range])) {
|
||||
$function = $functionMap[$range];
|
||||
$end->$function();
|
||||
|
||||
return $end;
|
||||
}
|
||||
if ($range == '6M') {
|
||||
if (intval($start->format('m')) >= 7) {
|
||||
$end->endOfYear();
|
||||
} else {
|
||||
$end->startOfYear()->addMonths(6);
|
||||
}
|
||||
|
||||
return $end;
|
||||
return $end;
|
||||
}
|
||||
throw new FireflyException('updateEndDate cannot handle $range ' . $range);
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param $range
|
||||
* @param Carbon $date
|
||||
*
|
||||
@@ -152,37 +141,28 @@ class Filter
|
||||
*/
|
||||
protected function periodName($range, Carbon $date)
|
||||
{
|
||||
switch ($range) {
|
||||
default:
|
||||
throw new FireflyException('No _periodName() for range "' . $range . '"');
|
||||
break;
|
||||
case '1D':
|
||||
return $date->format('jS F Y');
|
||||
break;
|
||||
case '1W':
|
||||
return 'week ' . $date->format('W, Y');
|
||||
break;
|
||||
case '1M':
|
||||
return $date->format('F Y');
|
||||
break;
|
||||
case '3M':
|
||||
$month = intval($date->format('m'));
|
||||
|
||||
return 'Q' . ceil(($month / 12) * 4) . ' ' . $date->format('Y');
|
||||
break;
|
||||
case '6M':
|
||||
$month = intval($date->format('m'));
|
||||
$half = ceil(($month / 12) * 2);
|
||||
$halfName = $half == 1 ? 'first' : 'second';
|
||||
|
||||
return $halfName . ' half of ' . $date->format('d-m-Y');
|
||||
break;
|
||||
case '1Y':
|
||||
return $date->format('Y');
|
||||
break;
|
||||
|
||||
|
||||
$formatMap = [
|
||||
'1D' => 'jS F Y',
|
||||
'1W' => '\w\e\ek W, Y',
|
||||
'1M' => 'F Y',
|
||||
'1Y' => 'Y',
|
||||
];
|
||||
if (isset($formatMap[$range])) {
|
||||
return $date->format($formatMap[$range]);
|
||||
}
|
||||
if ($range == '3M') {
|
||||
$month = intval($date->format('m'));
|
||||
|
||||
return 'Q' . ceil(($month / 12) * 4) . ' ' . $date->format('Y');
|
||||
}
|
||||
if ($range == '6M') {
|
||||
$month = intval($date->format('m'));
|
||||
$half = ceil(($month / 12) * 2);
|
||||
$halfName = $half == 1 ? 'first' : 'second';
|
||||
|
||||
return $halfName . ' half of ' . $date->format('d-m-Y');
|
||||
}
|
||||
throw new FireflyException('No _periodName() for range "' . $range . '"');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -194,37 +174,35 @@ class Filter
|
||||
*/
|
||||
public function previous($range, Carbon $date)
|
||||
{
|
||||
switch ($range) {
|
||||
default:
|
||||
throw new FireflyException('Cannot do _previous() on ' . $range);
|
||||
break;
|
||||
case '1D':
|
||||
$date->startOfDay()->subDay();
|
||||
break;
|
||||
case '1W':
|
||||
$date->startOfWeek()->subWeek();
|
||||
break;
|
||||
case '1M':
|
||||
$date->startOfMonth()->subMonth();
|
||||
break;
|
||||
case '3M':
|
||||
$date->firstOfQuarter()->subMonths(3)->firstOfQuarter();
|
||||
break;
|
||||
case '6M':
|
||||
$month = intval($date->format('m'));
|
||||
if ($month <= 6) {
|
||||
$date->startOfYear()->subMonths(6);
|
||||
} else {
|
||||
$date->startOfYear();
|
||||
}
|
||||
break;
|
||||
case '1Y':
|
||||
$date->startOfYear()->subYear();
|
||||
break;
|
||||
$functionMap = [
|
||||
'1D' => 'Day',
|
||||
'1W' => 'Week',
|
||||
'1M' => 'Month',
|
||||
'1Y' => 'Year'
|
||||
];
|
||||
|
||||
if (isset($functionMap[$range])) {
|
||||
$startFunction = 'startOf' . $functionMap[$range];
|
||||
$subFunction = 'sub' . $functionMap[$range];
|
||||
$date->$startFunction()->$subFunction();
|
||||
|
||||
return $date;
|
||||
}
|
||||
if ($range == '3M') {
|
||||
$date->firstOfQuarter()->subMonths(3)->firstOfQuarter();
|
||||
|
||||
return $date;
|
||||
return $date;
|
||||
}
|
||||
if ($range == '6M') {
|
||||
$month = intval($date->format('m'));
|
||||
$date->startOfYear();
|
||||
if ($month <= 6) {
|
||||
$date->subMonths(6);
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
throw new FireflyException('Cannot do _previous() on ' . $range);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,8 @@ use Illuminate\Support\Collection;
|
||||
class Form
|
||||
{
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* Takes any collection and tries to make a sensible select list compatible array of it.
|
||||
*
|
||||
* @param Collection $set
|
||||
@@ -32,7 +34,7 @@ class Form
|
||||
$title = null;
|
||||
|
||||
foreach ($fields as $field) {
|
||||
if (is_null($title) && isset($entry->$field)) {
|
||||
if (isset($entry->$field)) {
|
||||
$title = $entry->$field;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ class Reminders
|
||||
{
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param \Reminder $reminder
|
||||
*
|
||||
* @return int
|
||||
@@ -62,6 +64,9 @@ class Reminders
|
||||
return $reminders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*/
|
||||
public function updateReminders()
|
||||
{
|
||||
/** @var Collection $set */
|
||||
|
||||
@@ -35,6 +35,7 @@ class Steam
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @param $boolean
|
||||
*
|
||||
* @return string
|
||||
@@ -61,12 +62,18 @@ class Steam
|
||||
{
|
||||
$pct = $repetition->currentamount / $piggyBank->targetamount * 100;
|
||||
if ($pct > 100) {
|
||||
// @codeCoverageIgnoreStart
|
||||
return 100;
|
||||
// @codeCoverageIgnoreEnd
|
||||
} else {
|
||||
return floor($pct);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function removeEmptyBudgetLimits()
|
||||
{
|
||||
$user = \Auth::user();
|
||||
|
||||
@@ -11,6 +11,8 @@ use Illuminate\Validation\Validator;
|
||||
class FireflyValidator extends Validator
|
||||
{
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
*
|
||||
* @param $attribute
|
||||
* @param $value
|
||||
* @param $parameters
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Eloquent\SoftDeletingTrait;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
use \Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingTrait;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
/**
|
||||
* Class Account
|
||||
@@ -18,15 +18,15 @@ class Account extends Eloquent
|
||||
* @var array
|
||||
*/
|
||||
public static $rules
|
||||
= [
|
||||
= [
|
||||
'name' => ['required', 'between:1,100'],
|
||||
'user_id' => 'required|exists:users,id',
|
||||
'account_type_id' => 'required|exists:account_types,id',
|
||||
'active' => 'required|boolean'
|
||||
|
||||
];
|
||||
protected $dates = ['deleted_at', 'created_at', 'updated_at'];
|
||||
protected $fillable = ['name', 'user_id', 'account_type_id', 'active'];
|
||||
protected $dates = ['deleted_at', 'created_at', 'updated_at'];
|
||||
protected $fillable = ['name', 'user_id', 'account_type_id', 'active'];
|
||||
|
||||
/**
|
||||
* Account type.
|
||||
@@ -67,7 +67,7 @@ class Account extends Eloquent
|
||||
/**
|
||||
*
|
||||
* @param EloquentBuilder $query
|
||||
* @param array $types
|
||||
* @param array $types
|
||||
*/
|
||||
public function scopeAccountTypeIn(EloquentBuilder $query, array $types)
|
||||
{
|
||||
@@ -82,9 +82,13 @@ class Account extends Eloquent
|
||||
*
|
||||
* @param EloquentBuilder $query
|
||||
*/
|
||||
public function scopeWithMeta(EloquentBuilder $query)
|
||||
public function scopeWithMeta(EloquentBuilder $query, $field = 'accountRole')
|
||||
{
|
||||
$query->with(['accountmeta']);
|
||||
$query->leftJoin(
|
||||
'account_meta', function (JoinClause $join) use ($field) {
|
||||
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', $field);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
use \Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
use FireflyIII\Exception\FireflyException;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
use \Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,7 @@ class TransactionJournal extends Eloquent
|
||||
protected $rules
|
||||
= ['transaction_type_id' => 'required|exists:transaction_types,id',
|
||||
'transaction_currency_id' => 'required|exists:transaction_currencies,id',
|
||||
'description' => 'required|between:1,255',
|
||||
'description' => 'required|between:1,1024',
|
||||
'date' => 'required|date',
|
||||
'completed' => 'required|between:0,1'];
|
||||
|
||||
@@ -82,6 +82,15 @@ class TransactionJournal extends Eloquent
|
||||
return ['created_at', 'updated_at', 'date'];
|
||||
}
|
||||
|
||||
public function getDescriptionAttribute($value)
|
||||
{
|
||||
if ($this->encrypted) {
|
||||
return Crypt::decrypt($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
@@ -198,6 +207,12 @@ class TransactionJournal extends Eloquent
|
||||
);
|
||||
}
|
||||
|
||||
public function setDescriptionAttribute($value)
|
||||
{
|
||||
$this->attributes['description'] = Crypt::encrypt($value);
|
||||
$this->attributes['encrypted'] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
|
||||
@@ -204,7 +204,7 @@ Route::group(
|
||||
Route::get('/categories/edit/{category}', ['uses' => 'CategoryController@edit', 'as' => 'categories.edit']);
|
||||
Route::get('/categories/delete/{category}', ['uses' => 'CategoryController@delete', 'as' => 'categories.delete']);
|
||||
Route::get('/categories/show/{category}', ['uses' => 'CategoryController@show', 'as' => 'categories.show']);
|
||||
Route::get('/categories/list/noCategory', ['uses' => 'CategoryController@noCategory', 'as' => 'categories.noBudget']);
|
||||
Route::get('/categories/list/noCategory', ['uses' => 'CategoryController@noCategory', 'as' => 'categories.noCategory']);
|
||||
|
||||
// currency controller
|
||||
Route::get('/currency', ['uses' => 'CurrencyController@index', 'as' => 'currency.index']);
|
||||
@@ -222,11 +222,13 @@ Route::group(
|
||||
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/budget/{budget}/{limitrepetition}', ['uses' => 'GoogleChartController@budgetLimitSpending']);
|
||||
|
||||
Route::get('/chart/piggy_history/{piggyBank}', ['uses' => 'GoogleChartController@piggyBankHistory']);
|
||||
|
||||
// google chart for components (categories + budgets combined)
|
||||
Route::get('/chart/budget/{budget}/spending/{year}', ['uses' => 'GoogleChartController@budgetsAndSpending']);
|
||||
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']);
|
||||
|
||||
// help controller
|
||||
|
||||
@@ -9,7 +9,9 @@ use League\FactoryMuffin\Facade as f;
|
||||
class TestCase extends Illuminate\Foundation\Testing\TestCase
|
||||
{
|
||||
/**
|
||||
* Creates the application.
|
||||
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
|
||||
*
|
||||
* Creates the application..
|
||||
*
|
||||
* @return \Symfony\Component\HttpKernel\HttpKernelInterface
|
||||
*/
|
||||
|
||||
@@ -15,8 +15,12 @@ League\FactoryMuffin\Facade::define(
|
||||
|
||||
return $set[rand(0, count($set) - 1)];
|
||||
},
|
||||
'rep_every' => function() {return rand(0,3);},
|
||||
'rep_times' => function() {return rand(0,3);},
|
||||
'rep_every' => function () {
|
||||
return rand(0, 3);
|
||||
},
|
||||
'rep_times' => function () {
|
||||
return rand(0, 3);
|
||||
},
|
||||
'reminder' => function () {
|
||||
$set = ['day', 'week', 'quarter', 'month', 'year'];
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ League\FactoryMuffin\Facade::define(
|
||||
'account_id' => 'factory|Account',
|
||||
'transaction_journal_id' => 'factory|TransactionJournal',
|
||||
'description' => 'sentence',
|
||||
'amount' => function() {
|
||||
return round(rand(100,10000) / 100,2);
|
||||
'amount' => function () {
|
||||
return round(rand(100, 10000) / 100, 2);
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
@if($what == 'asset')
|
||||
{{Form::ffBalance('openingbalance')}}
|
||||
{{Form::ffDate('openingbalancedate', date('Y-m-d'))}}
|
||||
@endif
|
||||
{{Form::ffBalance('openingBalance')}}
|
||||
{{Form::ffDate('openingBalanceDate', date('Y-m-d'))}}
|
||||
@endif
|
||||
{{Form::ffCheckbox('active','1',true)}}
|
||||
{{Form::ffSelect('account_role',Config::get('firefly.accountRoles'))}}
|
||||
</div>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<div class="panel-body">
|
||||
{{Form::ffCheckbox('active','1')}}
|
||||
@if($account->accounttype->type == 'Default account' || $account->accounttype->type == 'Asset account')
|
||||
{{Form::ffBalance('openingBalance')}}
|
||||
{{Form::ffBalance('openingBalance',null, ['currency' => $openingBalance->transactionCurrency])}}
|
||||
{{Form::ffDate('openingBalanceDate')}}
|
||||
{{Form::ffSelect('account_role',Config::get('firefly.accountRoles'))}}
|
||||
@endif
|
||||
|
||||
@@ -6,6 +6,21 @@
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-fw {{$subTitleIcon}} fa-fw"></i> {{{$account->name}}}
|
||||
|
||||
|
||||
<!-- ACTIONS MENU -->
|
||||
<div class="pull-right">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown">
|
||||
Actions
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu pull-right" role="menu">
|
||||
<li><a href="{{route('accounts.edit',$account->id)}}"><i class="fa fa-pencil fa-fw"></i> Edit</a></li>
|
||||
<li><a href="{{route('accounts.delete',$account->id)}}"><i class="fa fa-trash fa-fw"></i> Delete</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div id="overview-chart"></div>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
Overview
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div id="componentOverview"></div>
|
||||
<div id="budgetOverview"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -71,7 +71,8 @@
|
||||
@stop
|
||||
@section('scripts')
|
||||
<script type="text/javascript">
|
||||
var componentID = {{$budget->id}};
|
||||
var budgetID = {{$budget->id}};
|
||||
var currencyCode = '{{Amount::getCurrencyCode()}}';
|
||||
@if(!is_null($repetition))
|
||||
var repetitionID = {{$repetition->id}};
|
||||
var year = {{$repetition->startdate->format('Y')}};
|
||||
|
||||
@@ -43,25 +43,11 @@
|
||||
<li>Set the default currency display;</li>
|
||||
<li>Set the default currency for new transactions;</li>
|
||||
<li>Add, modify and remove supported currencies.</li>
|
||||
<li>Display the actual currency of a transaction</li>
|
||||
<li>Update a transaction's currency.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-red">
|
||||
<div class="panel-heading">
|
||||
Not supported yet
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
<li>Display the actual currency of a transaction<br />
|
||||
<small>See the help-page.</small></li>
|
||||
<li>
|
||||
Update a transaction's currency.
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
20
app/views/form/amount.blade.php
Normal file
20
app/views/form/amount.blade.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<div class="{{{$classes}}}">
|
||||
<label for="{{{$options['id']}}}" class="col-sm-4 control-label">{{{$label}}}</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-default dropdown-toggle amountCurrencyDropdown" data-toggle="dropdown" aria-expanded="false">
|
||||
<span id="amountCurrentSymbol">{{$defaultCurrency->symbol}}</span> <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
@foreach($currencies as $currency)
|
||||
<li><a href="#" class="currencySelect" data-id="{{{$currency->id}}}" data-field="amount" data-currency="{{{$currency->code}}}" data-symbol="{{{$currency->symbol}}}">{{{$currency->name}}}</a></li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
{{Form::input('number', $name, $value, $options)}}
|
||||
{{Form::input('hidden','amount_currency_id',$defaultCurrency->id)}}
|
||||
@include('form.feedback')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
20
app/views/form/balance.blade.php
Normal file
20
app/views/form/balance.blade.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<div class="{{{$classes}}}">
|
||||
<label for="{{{$options['id']}}}" class="col-sm-4 control-label">{{{$label}}}</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-default dropdown-toggle balanceCurrencyDropdown" data-toggle="dropdown" aria-expanded="false">
|
||||
<span id="balanceCurrentSymbol">{{$defaultCurrency->symbol}}</span> <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
@foreach($currencies as $currency)
|
||||
<li><a href="#" class="currencySelect" data-id="{{{$currency->id}}}" data-field="balance" data-currency="{{{$currency->code}}}" data-symbol="{{{$currency->symbol}}}">{{{$currency->name}}}</a></li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
{{Form::input('number', $name, $value, $options)}}
|
||||
{{Form::input('hidden','balance_currency_id',$defaultCurrency->id)}}
|
||||
@include('form.feedback')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
11
app/views/form/checkbox.blade.php
Normal file
11
app/views/form/checkbox.blade.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<div class="{{{$classes}}}">
|
||||
<label for="{{{$options['id']}}}" class="col-sm-4 control-label">{{{$label}}}</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
{{Form::checkbox($name, $value, $options['checked'], $options)}}
|
||||
</label>
|
||||
</div>
|
||||
@include('form.feedback')
|
||||
</div>
|
||||
</div>
|
||||
7
app/views/form/date.blade.php
Normal file
7
app/views/form/date.blade.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<div class="{{{$classes}}}">
|
||||
<label for="{{{$options['id']}}}" class="col-sm-4 control-label">{{{$label}}}</label>
|
||||
<div class="col-sm-8">
|
||||
{{Form::input('date', $name, $value, $options)}}
|
||||
@include('form.feedback')
|
||||
</div>
|
||||
</div>
|
||||
12
app/views/form/feedback.blade.php
Normal file
12
app/views/form/feedback.blade.php
Normal file
@@ -0,0 +1,12 @@
|
||||
@if(Session::has('errors') && Session::get('errors')->has($name))
|
||||
<span class="glyphicon glyphicon-remove form-control-feedback"></span>
|
||||
<p class="text-danger">{{{Session::get('errors')->first($name)}}}</p>
|
||||
@endif
|
||||
@if(Session::has('warnings') && Session::get('warnings')->has($name))
|
||||
<span class="glyphicon glyphicon-warning-sign form-control-feedback"></span>
|
||||
<p class="text-warning">{{{Session::get('warnings')->first($name)}}}</p>
|
||||
@endif
|
||||
@if(Session::has('successes') && Session::get('successes')->has($name))
|
||||
<span class="glyphicon glyphicon-ok form-control-feedback"></span>
|
||||
<p class="text-success">{{{Session::get('successes')->first($name)}}}</p>
|
||||
@endif
|
||||
9
app/views/form/integer.blade.php
Normal file
9
app/views/form/integer.blade.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<div class="{{{$classes}}}">
|
||||
<label for="{{{$options['id']}}}" class="col-sm-4 control-label">{{{$label}}}</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
{{Form::input('number', $name, $value, $options)}}
|
||||
@include('form.feedback')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user