mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Merge branch 'laravel5' into develop
Conflicts: resources/views/reports/month.blade.php Upgraded to Laravel 5.
This commit is contained in:
commit
da4b1c7276
16
.env.example
Normal file
16
.env.example
Normal file
@ -0,0 +1,16 @@
|
||||
APP_ENV=local
|
||||
APP_DEBUG=true
|
||||
APP_KEY=SomeRandomString
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=localhost
|
||||
DB_DATABASE=homestead
|
||||
DB_USERNAME=homestead
|
||||
DB_PASSWORD=secret
|
||||
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
|
||||
EMAIL_SMTP=
|
||||
EMAIL_USERNAME=
|
||||
EMAIL_PASSWORD=
|
13
.env.testing
Normal file
13
.env.testing
Normal file
@ -0,0 +1,13 @@
|
||||
APP_ENV=testing
|
||||
APP_DEBUG=true
|
||||
APP_KEY=SomeRandomString
|
||||
|
||||
DB_CONNECTION=sqlite
|
||||
DB_HOST=localhost
|
||||
DB_DATABASE=homestead
|
||||
DB_USERNAME=homestead
|
||||
DB_PASSWORD=secret
|
||||
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,8 +1,6 @@
|
||||
/bootstrap/compiled.php
|
||||
/vendor
|
||||
composer.phar
|
||||
.env.*.php
|
||||
.env.php
|
||||
Thumbs.db
|
||||
.idea/
|
||||
tests/_output/*
|
||||
@ -25,3 +23,5 @@ tests/_data/dump.sql
|
||||
db.sqlite_snapshot
|
||||
c3.php
|
||||
db.sqlite-journal
|
||||
tests/_output/*
|
||||
.env
|
||||
|
@ -11,11 +11,13 @@ addons:
|
||||
install:
|
||||
- rm composer.lock
|
||||
- composer install
|
||||
- php artisan env
|
||||
- mv -v .env.testing .env
|
||||
|
||||
script:
|
||||
- ./tests/_data/db.sh
|
||||
- php vendor/bin/codecept build
|
||||
- php vendor/bin/codecept run --coverage --coverage-xml
|
||||
- php vendor/bin/codecept run --coverage --coverage-xml --no-exit
|
||||
|
||||
after_script:
|
||||
- cp -v tests/_output/coverage.xml build/logs/clover.xml
|
||||
|
@ -1,4 +1,4 @@
|
||||
Firefly III (v3.2.5)
|
||||
Firefly III (v3.3)
|
||||
===========
|
||||
|
||||
[](https://travis-ci.org/JC5/firefly-iii)
|
||||
|
@ -1,606 +0,0 @@
|
||||
# ************************************************************
|
||||
# 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-02 19:01: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-02 19:00:13','2015-01-02 19:00:13','Default account',1),
|
||||
(2,'2015-01-02 19:00:13','2015-01-02 19:00:13','Cash account',0),
|
||||
(3,'2015-01-02 19:00:13','2015-01-02 19:00:13','Asset account',1),
|
||||
(4,'2015-01-02 19:00:13','2015-01-02 19:00:13','Expense account',1),
|
||||
(5,'2015-01-02 19:00:13','2015-01-02 19:00:13','Revenue account',1),
|
||||
(6,'2015-01-02 19:00:13','2015-01-02 19:00:13','Initial balance account',0),
|
||||
(7,'2015-01-02 19:00:13','2015-01-02 19:00:13','Beneficiary account',1),
|
||||
(8,'2015-01-02 19:00:13','2015-01-02 19:00:13','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_ci_combi` (`startdate`,`repeat_freq`),
|
||||
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);
|
||||
|
||||
/*!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-02 19:00:13','2015-01-02 19:00:13',NULL,'EUR','Euro','€'),
|
||||
(2,'2015-01-02 19:00:13','2015-01-02 19:00:13',NULL,'USD','US Dollar','$'),
|
||||
(3,'2015-01-02 19:00:13','2015-01-02 19:00:13',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(255) COLLATE utf8_unicode_ci DEFAULT NULL,
|
||||
`completed` tinyint(1) NOT NULL,
|
||||
`date` date NOT NULL,
|
||||
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-02 19:00:13','2015-01-02 19:00:13',NULL,'Withdrawal'),
|
||||
(2,'2015-01-02 19:00:13','2015-01-02 19:00:13',NULL,'Deposit'),
|
||||
(3,'2015-01-02 19:00:13','2015-01-02 19:00:13',NULL,'Transfer'),
|
||||
(4,'2015-01-02 19:00:13','2015-01-02 19:00:13',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 */;
|
@ -1,607 +0,0 @@
|
||||
# ************************************************************
|
||||
# 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 */;
|
11
app/Commands/Command.php
Normal file
11
app/Commands/Command.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php namespace FireflyIII\Commands;
|
||||
/**
|
||||
* Class Command
|
||||
*
|
||||
* @package FireflyIII\Commands
|
||||
*/
|
||||
abstract class Command
|
||||
{
|
||||
|
||||
|
||||
}
|
37
app/Console/Commands/Inspire.php
Normal file
37
app/Console/Commands/Inspire.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php namespace FireflyIII\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Foundation\Inspiring;
|
||||
|
||||
/**
|
||||
* Class Inspire
|
||||
*
|
||||
* @package FireflyIII\Console\Commands
|
||||
*/
|
||||
class Inspire extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Display an inspiring quote';
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'inspire';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->comment(PHP_EOL . Inspiring::quote() . PHP_EOL);
|
||||
}
|
||||
|
||||
}
|
37
app/Console/Kernel.php
Normal file
37
app/Console/Kernel.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php namespace FireflyIII\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
/**
|
||||
* Class Kernel
|
||||
*
|
||||
* @package FireflyIII\Console
|
||||
*/
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
|
||||
/**
|
||||
* The Artisan commands provided by your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $commands
|
||||
= [
|
||||
'FireflyIII\Console\Commands\Inspire',
|
||||
];
|
||||
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
$schedule->command('inspire')
|
||||
->hourly();
|
||||
}
|
||||
|
||||
}
|
13
app/Events/Event.php
Normal file
13
app/Events/Event.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php namespace FireflyIII\Events;
|
||||
|
||||
/**
|
||||
* Class Event
|
||||
*
|
||||
* @package FireflyIII\Events
|
||||
*/
|
||||
abstract class Event
|
||||
{
|
||||
|
||||
//
|
||||
|
||||
}
|
20
app/Events/JournalDeleted.php
Normal file
20
app/Events/JournalDeleted.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php namespace FireflyIII\Events;
|
||||
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class JournalDeleted extends Event
|
||||
{
|
||||
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Exception;
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
||||
|
||||
/**
|
||||
* Class FireflyException
|
||||
*
|
||||
* @package FireflyIII\Exception
|
||||
* @package FireflyIII\Exceptions
|
||||
*/
|
||||
class FireflyException extends \Exception
|
||||
{
|
56
app/Exceptions/Handler.php
Normal file
56
app/Exceptions/Handler.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php namespace FireflyIII\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
|
||||
/**
|
||||
* Class Handler
|
||||
*
|
||||
* @package FireflyIII\Exceptions
|
||||
*/
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* A list of the exception types that should not be reported.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dontReport
|
||||
= [
|
||||
'Symfony\Component\HttpKernel\Exception\HttpException'
|
||||
];
|
||||
|
||||
/**
|
||||
* Render an exception into an HTTP response.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Exception $e
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function render($request, Exception $e)
|
||||
{
|
||||
if ($this->isHttpException($e)) {
|
||||
return $this->renderHttpException($e);
|
||||
} else {
|
||||
return parent::render($request, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report or log an exception.
|
||||
*
|
||||
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
|
||||
*
|
||||
* @param \Exception $e
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function report(Exception $e)
|
||||
{
|
||||
/** @noinspection PhpInconsistentReturnPointsInspection */
|
||||
return parent::report($e);
|
||||
}
|
||||
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
<?php
|
||||
namespace FireflyIII\Exception;
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
||||
|
||||
/**
|
||||
* Class NotImplementedException
|
||||
*
|
||||
* @package FireflyIII\Exception
|
||||
* @package FireflyIII\Exceptions
|
||||
*/
|
||||
class NotImplementedException extends \Exception
|
||||
{
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
namespace FireflyIII\Exception;
|
||||
namespace FireflyIII\Exceptions;
|
||||
|
||||
/**
|
||||
* Class ValidationException
|
||||
* Class ValidationExceptions
|
||||
*
|
||||
* @package FireflyIII\Exception
|
||||
*/
|
33
app/Handlers/Events/JournalDeletedHandler.php
Normal file
33
app/Handlers/Events/JournalDeletedHandler.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php namespace FireflyIII\Handlers\Events;
|
||||
|
||||
use FireflyIII\Events\JournalDeleted;
|
||||
use Illuminate\Contracts\Queue\ShouldBeQueued;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
|
||||
class JournalDeletedHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Create the event handler.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param JournalDeleted $event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(JournalDeleted $event)
|
||||
{
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
}
|
175
app/Helpers/Report/ReportHelper.php
Normal file
175
app/Helpers/Report/ReportHelper.php
Normal file
@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Report;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class ReportHelper
|
||||
*
|
||||
* @package FireflyIII\Helpers\Report
|
||||
*/
|
||||
class ReportHelper implements ReportHelperInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* This methods fails to take in account transfers FROM shared accounts.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $limit
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function expensesGroupedByAccount(Carbon $start, Carbon $end, $limit = 15)
|
||||
{
|
||||
$result = $this->_queries->journalsByExpenseAccount($start, $end);
|
||||
$array = $this->_helper->makeArray($result);
|
||||
$limited = $this->_helper->limitArray($array, $limit);
|
||||
|
||||
return $limited;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Carbon
|
||||
*/
|
||||
public function firstDate()
|
||||
{
|
||||
$journal = Auth::user()->transactionjournals()->orderBy('date', 'ASC')->first();
|
||||
if ($journal) {
|
||||
return $journal->date;
|
||||
}
|
||||
|
||||
return Carbon::now();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets some kind of list for a monthly overview.
|
||||
*
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getBudgetsForMonth(Carbon $date)
|
||||
{
|
||||
$start = clone $date;
|
||||
$start->startOfMonth();
|
||||
$end = clone $date;
|
||||
$end->endOfMonth();
|
||||
// all budgets
|
||||
$set = \Auth::user()->budgets()
|
||||
->leftJoin(
|
||||
'budget_limits', function (JoinClause $join) use ($date) {
|
||||
$join->on('budget_limits.budget_id', '=', 'budgets.id')->where('budget_limits.startdate', '=', $date->format('Y-m-d'));
|
||||
}
|
||||
)
|
||||
->get(['budgets.*', 'budget_limits.amount as amount']);
|
||||
|
||||
|
||||
$budgets = $this->_helper->makeArray($set);
|
||||
$amountSet = $this->_queries->journalsByBudget($start, $end);
|
||||
$amounts = $this->_helper->makeArray($amountSet);
|
||||
$combined = $this->_helper->mergeArrays($budgets, $amounts);
|
||||
$combined[0]['spent'] = isset($combined[0]['spent']) ? $combined[0]['spent'] : 0.0;
|
||||
$combined[0]['amount'] = isset($combined[0]['amount']) ? $combined[0]['amount'] : 0.0;
|
||||
$combined[0]['name'] = 'No budget';
|
||||
|
||||
// find transactions to shared expense accounts, which are without a budget by default:
|
||||
$transfers = $this->_queries->sharedExpenses($start, $end);
|
||||
foreach ($transfers as $transfer) {
|
||||
$combined[0]['spent'] += floatval($transfer->amount) * -1;
|
||||
}
|
||||
|
||||
return $combined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listOfMonths(Carbon $date)
|
||||
{
|
||||
$start = clone $date;
|
||||
$end = Carbon::now();
|
||||
$months = [];
|
||||
while ($start <= $end) {
|
||||
$months[] = [
|
||||
'formatted' => $start->format('F Y'),
|
||||
'month' => intval($start->format('m')),
|
||||
'year' => intval($start->format('Y')),
|
||||
];
|
||||
$start->addMonth();
|
||||
}
|
||||
|
||||
return $months;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listOfYears(Carbon $date)
|
||||
{
|
||||
$start = clone $date;
|
||||
$end = Carbon::now();
|
||||
$years = [];
|
||||
while ($start <= $end) {
|
||||
$years[] = $start->format('Y');
|
||||
$start->addYear();
|
||||
}
|
||||
|
||||
return $years;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function yearBalanceReport(Carbon $date)
|
||||
{
|
||||
$start = clone $date;
|
||||
$end = clone $date;
|
||||
$sharedAccounts = [];
|
||||
$sharedCollection = \Auth::user()->accounts()
|
||||
->leftJoin('account_meta', 'account_meta.account_id', '=', 'accounts.id')
|
||||
->where('account_meta.name', '=', 'accountRole')
|
||||
->where('account_meta.data', '=', json_encode('sharedExpense'))
|
||||
->get(['accounts.id']);
|
||||
|
||||
foreach ($sharedCollection as $account) {
|
||||
$sharedAccounts[] = $account->id;
|
||||
}
|
||||
|
||||
$accounts = \Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*'])->filter(
|
||||
function (Account $account) use ($sharedAccounts) {
|
||||
if (!in_array($account->id, $sharedAccounts)) {
|
||||
return $account;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
$report = [];
|
||||
$start->startOfYear()->subDay();
|
||||
$end->endOfYear();
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$report[] = [
|
||||
'start' => \Steam::balance($account, $start),
|
||||
'end' => \Steam::balance($account, $end),
|
||||
'account' => $account,
|
||||
'shared' => $account->accountRole == 'sharedExpense'
|
||||
];
|
||||
}
|
||||
|
||||
return $report;
|
||||
}
|
||||
}
|
62
app/Helpers/Report/ReportHelperInterface.php
Normal file
62
app/Helpers/Report/ReportHelperInterface.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Helpers\Report;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface ReportHelperInterface
|
||||
*
|
||||
* @package FireflyIII\Helpers\Report
|
||||
*/
|
||||
interface ReportHelperInterface
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return Carbon
|
||||
*/
|
||||
public function firstDate();
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listOfMonths(Carbon $date);
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function listOfYears(Carbon $date);
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function yearBalanceReport(Carbon $date);
|
||||
|
||||
/**
|
||||
* This methods fails to take in account transfers FROM shared accounts.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param int $limit
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function expensesGroupedByAccount(Carbon $start, Carbon $end, $limit = 15);
|
||||
|
||||
/**
|
||||
* This method gets some kind of list for a monthly overview.
|
||||
*
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getBudgetsForMonth(Carbon $date);
|
||||
}
|
510
app/Helpers/Report/ReportQuery.php
Normal file
510
app/Helpers/Report/ReportQuery.php
Normal file
@ -0,0 +1,510 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: sander
|
||||
* Date: 22/02/15
|
||||
* Time: 18:30
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Helpers\Report;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use DB;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Illuminate\Support\Collection;
|
||||
use Steam;
|
||||
|
||||
/**
|
||||
* Class ReportQuery
|
||||
*
|
||||
* @package FireflyIII\Helpers\Report
|
||||
*/
|
||||
class ReportQuery implements ReportQueryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* This query retrieves a list of accounts that are active and not shared.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function accountList()
|
||||
{
|
||||
return Auth::user()->accounts()
|
||||
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->leftJoin(
|
||||
'account_meta', function (JoinClause $join) {
|
||||
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', "accountRole");
|
||||
}
|
||||
)
|
||||
->whereIn('account_types.type', ['Default account', 'Cash account', 'Asset account'])
|
||||
->where('active', 1)
|
||||
->where(
|
||||
function (Builder $query) {
|
||||
$query->where('account_meta.data', '!=', '"sharedExpense"');
|
||||
$query->orWhereNull('account_meta.data');
|
||||
}
|
||||
)
|
||||
->get(['accounts.*']);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will get a list of all expenses in a certain time period that have no budget
|
||||
* and are balanced by a transfer to make up for it.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function balancedTransactionsList(Account $account, Carbon $start, Carbon $end)
|
||||
{
|
||||
|
||||
$set = TransactionJournal::
|
||||
leftJoin('transaction_group_transaction_journal', 'transaction_group_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin(
|
||||
'transaction_group_transaction_journal as otherFromGroup', function (JoinClause $join) {
|
||||
$join->on('otherFromGroup.transaction_group_id', '=', 'transaction_group_transaction_journal.transaction_group_id')
|
||||
->on('otherFromGroup.transaction_journal_id', '!=', 'transaction_journals.id');
|
||||
}
|
||||
)
|
||||
->leftJoin('transaction_journals as otherJournals', 'otherJournals.id', '=', 'otherFromGroup.transaction_journal_id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'otherJournals.transaction_type_id')
|
||||
->leftJoin(
|
||||
'transactions', function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'otherJournals.id')
|
||||
->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('otherJournals.deleted_at')
|
||||
->where('transactions.account_id', $account->id)
|
||||
->whereNotNull('transaction_group_transaction_journal.transaction_group_id')
|
||||
->first(
|
||||
[
|
||||
DB::Raw('SUM(`transactions`.`amount`) as `amount`')
|
||||
]
|
||||
);
|
||||
$sum = 0;
|
||||
if (!is_null($set)) {
|
||||
$sum = floatval($set->amount);
|
||||
}
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a users accounts combined with various meta-data related to the start and end date.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAllAccounts(Carbon $start, Carbon $end)
|
||||
{
|
||||
$set = Auth::user()->accounts()->orderBy('accounts.name', 'ASC')
|
||||
->accountTypeIn(['Default account', 'Asset account', 'Cash account'])
|
||||
->leftJoin(
|
||||
'account_meta', function (JoinClause $join) {
|
||||
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->where(
|
||||
function (Builder $query) {
|
||||
$query->where('account_meta.data', '!=', '"sharedExpense"');
|
||||
$query->orWhereNull('account_meta.data');
|
||||
}
|
||||
)
|
||||
->get(['accounts.*']);
|
||||
$set->each(
|
||||
function (Account $account) use ($start, $end) {
|
||||
/** @noinspection PhpParamsInspection */
|
||||
$account->startBalance = Steam::balance($account, $start);
|
||||
$account->endBalance = Steam::balance($account, $end);
|
||||
}
|
||||
);
|
||||
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs a summary of all expenses grouped by budget, related to the account.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBudgetSummary(Account $account, Carbon $start, Carbon $end)
|
||||
{
|
||||
$set = TransactionJournal::
|
||||
leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('budgets', 'budgets.id', '=', 'budget_transaction_journal.budget_id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->leftJoin(
|
||||
'transactions', function (JoinClause $join) {
|
||||
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->where('accounts.id', $account->id)
|
||||
->where('transaction_journals.user_id', Auth::user()->id)
|
||||
->where('transaction_types.type', 'Withdrawal')
|
||||
->groupBy('budgets.id')
|
||||
->orderBy('budgets.name', 'ASC')
|
||||
->get(['budgets.id', 'budgets.name', DB::Raw('SUM(`transactions`.`amount`) as `amount`')]);
|
||||
|
||||
return $set;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_journals.encrypted',
|
||||
'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.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsByBudget(Carbon $start, Carbon $end)
|
||||
{
|
||||
return Auth::user()->transactionjournals()
|
||||
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('budgets', 'budget_transaction_journal.budget_id', '=', 'budgets.id')
|
||||
->leftJoin(
|
||||
'transactions', function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transactions.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
|
||||
->leftJoin(
|
||||
'account_meta', function (JoinClause $join) {
|
||||
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id')
|
||||
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
|
||||
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
|
||||
->where('account_meta.data', '!=', '"sharedExpense"')
|
||||
->where('transaction_types.type', 'Withdrawal')
|
||||
->groupBy('budgets.id')
|
||||
->orderBy('budgets.name', 'ASC')
|
||||
->get(['budgets.id', 'budgets.name', DB::Raw('SUM(`transactions`.`amount`) AS `spent`')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of categories and the expenses therein, grouped by the relevant category.
|
||||
* This result excludes transfers to shared accounts which are expenses, technically.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsByCategory(Carbon $start, Carbon $end)
|
||||
{
|
||||
return Auth::user()->transactionjournals()
|
||||
->leftJoin(
|
||||
'category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'
|
||||
)
|
||||
->leftJoin('categories', 'category_transaction_journal.category_id', '=', 'categories.id')
|
||||
->leftJoin(
|
||||
'transactions', function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transactions.amount', '<', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
|
||||
->leftJoin(
|
||||
'account_meta', function (JoinClause $join) {
|
||||
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id')
|
||||
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
|
||||
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
|
||||
->where('account_meta.data', '!=', '"sharedExpense"')
|
||||
->where('transaction_types.type', 'Withdrawal')
|
||||
->groupBy('categories.id')
|
||||
->orderBy('amount')
|
||||
->get(['categories.id', 'categories.name', DB::Raw('SUM(`transactions`.`amount`) AS `amount`')]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsByExpenseAccount(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', '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)
|
||||
->groupBy('t_to.account_id')
|
||||
->orderBy('amount', 'DESC')
|
||||
->get(['t_to.account_id as id', 'ac_to.name as name', DB::Raw('SUM(t_to.amount) as `amount`')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns all deposits into asset accounts, grouped by the revenue account,
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsByRevenueAccount(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('amount')
|
||||
->get(['t_from.account_id as account_id', 'ac_from.name as name', DB::Raw('SUM(t_from.amount) as `amount`')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* With an equally misleading name, this query returns are transfers to shared accounts. These are considered
|
||||
* expenses.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function sharedExpenses(Carbon $start, Carbon $end)
|
||||
{
|
||||
return TransactionJournal::
|
||||
leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->leftJoin(
|
||||
'transactions', function (JoinClause $join) {
|
||||
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where(
|
||||
'transactions.amount', '>', 0
|
||||
);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
|
||||
->leftJoin(
|
||||
'account_meta', function (JoinClause $join) {
|
||||
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->where('account_meta.data', '"sharedExpense"')
|
||||
->after($start)
|
||||
->before($end)
|
||||
->where('transaction_types.type', 'Transfer')
|
||||
->where('transaction_journals.user_id', Auth::user()->id)
|
||||
->get(
|
||||
['transaction_journals.id', 'transaction_journals.description', 'transactions.account_id', 'accounts.name',
|
||||
'transactions.amount']
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* With a slightly misleading name, this query returns all transfers to shared accounts
|
||||
* which are technically expenses, since it won't be just your money that gets spend.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function sharedExpensesByCategory(Carbon $start, Carbon $end)
|
||||
{
|
||||
return TransactionJournal::
|
||||
leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->leftJoin(
|
||||
'transactions', function (JoinClause $join) {
|
||||
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where(
|
||||
'transactions.amount', '>', 0
|
||||
);
|
||||
}
|
||||
)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
|
||||
->leftJoin(
|
||||
'account_meta', function (JoinClause $join) {
|
||||
$join->on('account_meta.account_id', '=', 'accounts.id')->where('account_meta.name', '=', 'accountRole');
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'
|
||||
)
|
||||
->leftJoin('categories', 'category_transaction_journal.category_id', '=', 'categories.id')
|
||||
->where('account_meta.data', '"sharedExpense"')
|
||||
->after($start)
|
||||
->before($end)
|
||||
->where('transaction_types.type', 'Transfer')
|
||||
->where('transaction_journals.user_id', Auth::user()->id)
|
||||
->groupBy('categories.name')
|
||||
->get(
|
||||
[
|
||||
'categories.id',
|
||||
'categories.name as name',
|
||||
DB::Raw('SUM(`transactions`.`amount`) * -1 AS `amount`')
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -1,15 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Report;
|
||||
namespace FireflyIII\Helpers\Report;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
|
||||
/**
|
||||
* Interface ReportQueryInterface
|
||||
*
|
||||
* @package FireflyIII\Report
|
||||
* @package FireflyIII\Helpers\Report
|
||||
*/
|
||||
interface ReportQueryInterface
|
||||
{
|
||||
@ -32,49 +32,16 @@ interface ReportQueryInterface
|
||||
public function getAllAccounts(Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* Grabs a summary of all expenses grouped by budget, related to the account.
|
||||
* 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 \Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBudgetSummary(\Account $account, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* This method will sum up all expenses in a certain time period that have no budget
|
||||
* and are balanced by a transfer to make up for it.
|
||||
*
|
||||
* @param \Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function balancedTransactionsSum(\Account $account, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* This method will get a list of all expenses in a certain time period that have no budget
|
||||
* and are balanced by a transfer to make up for it.
|
||||
*
|
||||
* @param \Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function balancedTransactionsList(\Account $account, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* Gets a list of all budgets and if present, the amount of the current BudgetLimit
|
||||
* as well
|
||||
*
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getAllBudgets(Carbon $date);
|
||||
public function incomeByPeriod(Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* Gets a list of expenses grouped by the budget they were filed under.
|
||||
@ -101,6 +68,8 @@ interface 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
|
||||
*
|
||||
@ -110,6 +79,7 @@ interface ReportQueryInterface
|
||||
|
||||
/**
|
||||
* This method returns all deposits into asset accounts, grouped by the revenue account,
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
@ -117,18 +87,6 @@ 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.
|
||||
@ -142,7 +100,7 @@ interface ReportQueryInterface
|
||||
|
||||
/**
|
||||
* With a slightly misleading name, this query returns all transfers to shared accounts
|
||||
* grouped by category (which are technically expenses, since it won't be just your money that gets spend).
|
||||
* which are technically expenses, since it won't be just your money that gets spend.
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
@ -151,4 +109,26 @@ interface ReportQueryInterface
|
||||
*/
|
||||
public function sharedExpensesByCategory(Carbon $start, Carbon $end);
|
||||
|
||||
}
|
||||
/**
|
||||
* Grabs a summary of all expenses grouped by budget, related to the account.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBudgetSummary(Account $account, Carbon $start, Carbon $end);
|
||||
|
||||
/**
|
||||
* This method will get a list of all expenses in a certain time period that have no budget
|
||||
* and are balanced by a transfer to make up for it.
|
||||
*
|
||||
* @param Account $account
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function balancedTransactionsList(Account $account, Carbon $start, Carbon $end);
|
||||
}
|
193
app/Http/Controllers/AccountController.php
Normal file
193
app/Http/Controllers/AccountController.php
Normal file
@ -0,0 +1,193 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use App;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\AccountFormRequest;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use Input;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use View;
|
||||
|
||||
/**
|
||||
* Class AccountController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class AccountController extends Controller
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
View::share('mainTitleIcon', 'fa-credit-card');
|
||||
View::share('title', 'Accounts');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $what
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create($what = 'asset')
|
||||
{
|
||||
$subTitleIcon = Config::get('firefly.subTitlesByIdentifier.' . $what);
|
||||
$subTitle = 'Create a new ' . e($what) . ' account';
|
||||
|
||||
return view('accounts.create', compact('subTitleIcon', 'what', 'subTitle'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function delete(Account $account)
|
||||
{
|
||||
$subTitle = 'Delete ' . strtolower(e($account->accountType->type)) . ' "' . e($account->name) . '"';
|
||||
|
||||
return view('accounts.delete', compact('account', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Account $account, AccountRepositoryInterface $repository)
|
||||
{
|
||||
|
||||
$type = $account->accountType->type;
|
||||
$typeName = Config::get('firefly.shortNamesByFullName.' . $type);
|
||||
$name = $account->name;
|
||||
|
||||
$repository->destroy($account);
|
||||
|
||||
Session::flash('success', 'The ' . e($typeName) . ' account "' . e($name) . '" was deleted.');
|
||||
|
||||
return Redirect::route('accounts.index', $typeName);
|
||||
}
|
||||
|
||||
public function edit(Account $account, AccountRepositoryInterface $repository)
|
||||
{
|
||||
$what = Config::get('firefly.shortNamesByFullName')[$account->accountType->type];
|
||||
$subTitle = 'Edit ' . strtolower(e($account->accountType->type)) . ' "' . e($account->name) . '"';
|
||||
$subTitleIcon = Config::get('firefly.subIconsByIdentifier.' . $what);
|
||||
$openingBalance = $repository->openingBalanceTransaction($account);
|
||||
|
||||
// pre fill some useful values.
|
||||
|
||||
// the opening balance is tricky:
|
||||
$openingBalanceAmount = null;
|
||||
if ($openingBalance) {
|
||||
$transaction = $openingBalance->transactions()->where('account_id', $account->id)->first();
|
||||
$openingBalanceAmount = $transaction->amount;
|
||||
}
|
||||
|
||||
$preFilled = [
|
||||
'accountRole' => $account->getMeta('accountRole'),
|
||||
'openingBalanceDate' => $openingBalance ? $openingBalance->date->format('Y-m-d') : null,
|
||||
'openingBalance' => $openingBalanceAmount
|
||||
];
|
||||
Session::flash('preFilled', $preFilled);
|
||||
|
||||
return view('accounts.edit', compact('account', 'subTitle', 'subTitleIcon', 'openingBalance', 'what'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $what
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function index($what = 'default')
|
||||
{
|
||||
$subTitle = Config::get('firefly.subTitlesByIdentifier.' . $what);
|
||||
$subTitleIcon = Config::get('firefly.subIconsByIdentifier.' . $what);
|
||||
$types = Config::get('firefly.accountTypesByIdentifier.' . $what);
|
||||
$accounts = Auth::user()->accounts()->accountTypeIn($types)->get(['accounts.*']);
|
||||
|
||||
return view('accounts.index', compact('what', 'subTitleIcon', 'subTitle', 'accounts'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param string $range
|
||||
* @param AccountRepositoryInterface $repository
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function show(Account $account, $range = 'session')
|
||||
{
|
||||
/** @var \FireflyIII\Repositories\Account\AccountRepositoryInterface $repository */
|
||||
$repository = App::make('FireflyIII\Repositories\Account\AccountRepositoryInterface');
|
||||
$page = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page'));
|
||||
$subTitleIcon = Config::get('firefly.subTitlesByIdentifier.' . $account->accountType->type);
|
||||
$what = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type);
|
||||
$journals = $repository->getJournals($account, $page, $range);
|
||||
$subTitle = 'Details for ' . strtolower(e($account->accountType->type)) . ' "' . e($account->name) . '"';
|
||||
|
||||
return view('accounts.show', compact('account', 'what', 'range', 'subTitleIcon', 'journals', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param AccountFormRequest $request
|
||||
* @param AccountRepositoryInterface $repository
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(AccountFormRequest $request, AccountRepositoryInterface $repository)
|
||||
{
|
||||
$accountData = [
|
||||
'name' => $request->input('name'),
|
||||
'accountType' => $request->input('what'),
|
||||
'active' => true,
|
||||
'user' => Auth::user()->id,
|
||||
'accountRole' => $request->input('accountRole'),
|
||||
'openingBalance' => floatval($request->input('openingBalance')),
|
||||
'openingBalanceDate' => new Carbon($request->input('openingBalanceDate')),
|
||||
'openingBalanceCurrency' => intval($request->input('balance_currency_id')),
|
||||
|
||||
];
|
||||
$account = $repository->store($accountData);
|
||||
|
||||
Session::flash('success', 'New account "' . $account->name . '" stored!');
|
||||
|
||||
return Redirect::route('accounts.index', $request->input('what'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param AccountFormRequest $request
|
||||
* @param AccountRepositoryInterface $repository
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(Account $account, AccountFormRequest $request, AccountRepositoryInterface $repository)
|
||||
{
|
||||
$what = Config::get('firefly.shortNamesByFullName.' . $account->accountType->type);
|
||||
$accountData = [
|
||||
'name' => $request->input('name'),
|
||||
'active' => $request->input('active'),
|
||||
'user' => Auth::user()->id,
|
||||
'accountRole' => $request->input('accountRole'),
|
||||
'openingBalance' => floatval($request->input('openingBalance')),
|
||||
'openingBalanceDate' => new Carbon($request->input('openingBalanceDate')),
|
||||
'openingBalanceCurrency' => intval($request->input('balance_currency_id')),
|
||||
];
|
||||
|
||||
$repository->update($account, $accountData);
|
||||
|
||||
Session::flash('success', 'Account "' . $account->name . '" updated.');
|
||||
|
||||
return Redirect::route('accounts.index', $what);
|
||||
|
||||
}
|
||||
|
||||
}
|
46
app/Http/Controllers/Auth/AuthController.php
Normal file
46
app/Http/Controllers/Auth/AuthController.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php namespace FireflyIII\Http\Controllers\Auth;
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Contracts\Auth\Registrar;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
|
||||
|
||||
/**
|
||||
* Class AuthController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers\Auth
|
||||
*/
|
||||
class AuthController extends Controller
|
||||
{
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Registration & Login Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller handles the registration of new users, as well as the
|
||||
| authentication of existing users. By default, this controller uses
|
||||
| a simple trait to add these behaviors. Why don't you explore it?
|
||||
|
|
||||
*/
|
||||
|
||||
use AuthenticatesAndRegistersUsers;
|
||||
|
||||
public $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new authentication controller instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\Guard $auth
|
||||
* @param \Illuminate\Contracts\Auth\Registrar $registrar
|
||||
*
|
||||
*/
|
||||
public function __construct(Guard $auth, Registrar $registrar)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->registrar = $registrar;
|
||||
|
||||
$this->middleware('guest', ['except' => 'getLogout']);
|
||||
}
|
||||
|
||||
}
|
48
app/Http/Controllers/Auth/PasswordController.php
Normal file
48
app/Http/Controllers/Auth/PasswordController.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php namespace FireflyIII\Http\Controllers\Auth;
|
||||
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Contracts\Auth\PasswordBroker;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
|
||||
/**
|
||||
* Class PasswordController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers\Auth
|
||||
*/
|
||||
class PasswordController extends Controller
|
||||
{
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Controller
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This controller is responsible for handling password reset requests
|
||||
| and uses a simple trait to include this behavior. You're free to
|
||||
| explore this trait and override any methods you wish to tweak.
|
||||
|
|
||||
*/
|
||||
|
||||
use ResetsPasswords;
|
||||
|
||||
|
||||
protected $redirectPath = '/';
|
||||
|
||||
/**
|
||||
* Create a new password controller instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Auth\Guard $auth
|
||||
* @param \Illuminate\Contracts\Auth\PasswordBroker $passwords
|
||||
*
|
||||
*/
|
||||
public function __construct(Guard $auth, PasswordBroker $passwords)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->passwords = $passwords;
|
||||
|
||||
|
||||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
}
|
240
app/Http/Controllers/BillController.php
Normal file
240
app/Http/Controllers/BillController.php
Normal file
@ -0,0 +1,240 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\BillFormRequest;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use URL;
|
||||
use View;
|
||||
|
||||
/**
|
||||
* Class BillController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class BillController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
View::share('title', 'Bills');
|
||||
View::share('mainTitleIcon', 'fa-calendar-o');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$periods = \Config::get('firefly.periods_to_text');
|
||||
|
||||
return view('bills.create')->with('periods', $periods)->with('subTitle', 'Create new');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function delete(Bill $bill)
|
||||
{
|
||||
return view('bills.delete')->with('bill', $bill)->with('subTitle', 'Delete "' . e($bill->name) . '"');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Bill $bill)
|
||||
{
|
||||
$bill->delete();
|
||||
Session::flash('success', 'The bill was deleted.');
|
||||
|
||||
return Redirect::route('bills.index');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function edit(Bill $bill)
|
||||
{
|
||||
$periods = \Config::get('firefly.periods_to_text');
|
||||
|
||||
return view('bills.edit')->with('periods', $periods)->with('bill', $bill)->with('subTitle', 'Edit "' . e($bill->name) . '"');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BillRepositoryInterface $repository
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index(BillRepositoryInterface $repository)
|
||||
{
|
||||
$bills = Auth::user()->bills()->get();
|
||||
$bills->each(
|
||||
function (Bill $bill) use ($repository) {
|
||||
$bill->nextExpectedMatch = $repository->nextExpectedMatch($bill);
|
||||
$last = $bill->transactionjournals()->orderBy('date', 'DESC')->first();
|
||||
$bill->lastFoundMatch = null;
|
||||
if ($last) {
|
||||
$bill->lastFoundMatch = $last->date;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return view('bills.index', compact('bills'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function rescan(Bill $bill, BillRepositoryInterface $repository)
|
||||
{
|
||||
if (intval($bill->active) == 0) {
|
||||
Session::flash('warning', 'Inactive bills cannot be scanned.');
|
||||
|
||||
return Redirect::intended('/');
|
||||
}
|
||||
|
||||
$set = \DB::table('transactions')->where('amount', '>', 0)->where('amount', '>=', $bill->amount_min)->where('amount', '<=', $bill->amount_max)->get(['transaction_journal_id']);
|
||||
$ids = [];
|
||||
|
||||
/** @var Transaction $entry */
|
||||
foreach ($set as $entry) {
|
||||
$ids[] = intval($entry->transaction_journal_id);
|
||||
}
|
||||
if (count($ids) > 0) {
|
||||
$journals = Auth::user()->transactionjournals()->whereIn('id',$ids)->get();
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$repository->scan($bill, $journal);
|
||||
}
|
||||
}
|
||||
|
||||
Session::flash('success', 'Rescanned everything.');
|
||||
|
||||
return Redirect::to(URL::previous());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function show(Bill $bill, BillRepositoryInterface $repository)
|
||||
{
|
||||
$journals = $bill->transactionjournals()->withRelevantData()->orderBy('date', 'DESC')->get();
|
||||
$bill->nextExpectedMatch = $repository->nextExpectedMatch($bill);
|
||||
$hideBill = true;
|
||||
|
||||
|
||||
return view('bills.show', compact('journals', 'hideBill', 'bill'))->with('subTitle', e($bill->name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function store(BillFormRequest $request, BillRepositoryInterface $repository)
|
||||
{
|
||||
|
||||
var_dump($request->all());
|
||||
|
||||
$billData = [
|
||||
'name' => $request->get('name'),
|
||||
'match' => $request->get('match'),
|
||||
'amount_min' => floatval($request->get('amount_min')),
|
||||
'amount_currency_id' => floatval($request->get('amount_currency_id')),
|
||||
'amount_max' => floatval($request->get('amount_max')),
|
||||
'date' => new Carbon($request->get('date')),
|
||||
'user' => Auth::user()->id,
|
||||
'repeat_freq' => $request->get('repeat_freq'),
|
||||
'skip' => intval($request->get('skip')),
|
||||
'automatch' => intval($request->get('automatch')) === 1,
|
||||
'active' => intval($request->get('active')) === 1,
|
||||
];
|
||||
|
||||
$bill = $repository->store($billData);
|
||||
Session::flash('success', 'Bill "' . e($bill->name) . '" stored.');
|
||||
|
||||
return Redirect::route('bills.index');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function update(Bill $bill, BillFormRequest $request, BillRepositoryInterface $repository)
|
||||
{
|
||||
$billData = [
|
||||
'name' => $request->get('name'),
|
||||
'match' => $request->get('match'),
|
||||
'amount_min' => floatval($request->get('amount_min')),
|
||||
'amount_currency_id' => floatval($request->get('amount_currency_id')),
|
||||
'amount_max' => floatval($request->get('amount_max')),
|
||||
'date' => new Carbon($request->get('date')),
|
||||
'user' => Auth::user()->id,
|
||||
'repeat_freq' => $request->get('repeat_freq'),
|
||||
'skip' => intval($request->get('skip')),
|
||||
'automatch' => intval($request->get('automatch')) === 1,
|
||||
'active' => intval($request->get('active')) === 1,
|
||||
];
|
||||
|
||||
$bill = $repository->update($bill, $billData);
|
||||
|
||||
Session::flash('success', 'Bill "' . e($bill->name) . '" updated.');
|
||||
|
||||
return Redirect::route('bills.index');
|
||||
|
||||
|
||||
// $data = Input::except('_token');
|
||||
// $data['active'] = intval(Input::get('active'));
|
||||
// $data['automatch'] = intval(Input::get('automatch'));
|
||||
// $data['user_id'] = Auth::user()->id;
|
||||
//
|
||||
// // always validate:
|
||||
// $messages = $this->_repository->validate($data);
|
||||
//
|
||||
// // flash messages:
|
||||
// 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 update bill: ' . $messages['errors']->first());
|
||||
//
|
||||
// return Redirect::route('bills.edit', $bill->id)->withInput();
|
||||
// }
|
||||
//
|
||||
// // return to update screen:
|
||||
// if ($data['post_submit_action'] == 'validate_only') {
|
||||
// return Redirect::route('bills.edit', $bill->id)->withInput();
|
||||
// }
|
||||
//
|
||||
// // update
|
||||
// $this->_repository->update($bill, $data);
|
||||
// Session::flash('success', 'Bill "' . e($data['name']) . '" updated.');
|
||||
//
|
||||
// // go back to list
|
||||
// if ($data['post_submit_action'] == 'update') {
|
||||
// return Redirect::route('bills.index');
|
||||
// }
|
||||
//
|
||||
// // go back to update screen.
|
||||
// return Redirect::route('bills.edit', $bill->id)->withInput(['post_submit_action' => 'return_to_edit']);
|
||||
|
||||
}
|
||||
|
||||
}
|
222
app/Http/Controllers/BudgetController.php
Normal file
222
app/Http/Controllers/BudgetController.php
Normal file
@ -0,0 +1,222 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\BudgetFormRequest;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use Input;
|
||||
use Preferences;
|
||||
use Redirect;
|
||||
use Response;
|
||||
use Session;
|
||||
use View;
|
||||
|
||||
/**
|
||||
* Class BudgetController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class BudgetController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
View::share('title', 'Budgets');
|
||||
View::share('mainTitleIcon', 'fa-tasks');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
public function amount(Budget $budget, BudgetRepositoryInterface $repository)
|
||||
{
|
||||
$amount = intval(Input::get('amount'));
|
||||
$date = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$limitRepetition = $repository->updateLimitAmount($budget, $date, $amount);
|
||||
|
||||
return Response::json(['name' => $budget->name, 'repetition' => $limitRepetition ? $limitRepetition->id : 0]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('budgets.create')->with('subTitle', 'Create a new budget');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function delete(Budget $budget)
|
||||
{
|
||||
$subTitle = 'Delete budget' . e($budget->name) . '"';
|
||||
|
||||
return view('budgets.delete', compact('budget', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Budget $budget, BudgetRepositoryInterface $repository)
|
||||
{
|
||||
|
||||
$name = $budget->name;
|
||||
$repository->destroy($budget);
|
||||
|
||||
Session::flash('success', 'The budget "' . e($name) . '" was deleted.');
|
||||
|
||||
return Redirect::route('budgets.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function edit(Budget $budget)
|
||||
{
|
||||
$subTitle = 'Edit budget "' . e($budget->name) . '"';
|
||||
|
||||
return view('budgets.edit', compact('budget', 'subTitle'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function index(BudgetRepositoryInterface $repository)
|
||||
{
|
||||
$budgets = Auth::user()->budgets()->get();
|
||||
|
||||
// loop the budgets:
|
||||
$budgets->each(
|
||||
function (Budget $budget) use ($repository) {
|
||||
$date = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$budget->spent = $repository->spentInMonth($budget, $date);
|
||||
$budget->currentRep = $budget->limitrepetitions()->where('limit_repetitions.startdate', $date)->first(['limit_repetitions.*']);
|
||||
}
|
||||
);
|
||||
|
||||
$date = Session::get('start', Carbon::now()->startOfMonth())->format('FY');
|
||||
$spent = $budgets->sum('spent');
|
||||
$amount = Preferences::get('budgetIncomeTotal' . $date, 1000)->data;
|
||||
$overspent = $spent > $amount;
|
||||
$spentPCT = $overspent ? ceil($amount / $spent * 100) : ceil($spent / $amount * 100);
|
||||
$budgetMax = Preferences::get('budgetMaximum', 1000);
|
||||
$budgetMaximum = $budgetMax->data;
|
||||
|
||||
return view('budgets.index', compact('budgetMaximum', 'budgets', 'spent', 'spentPCT', 'overspent', 'amount'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function noBudget()
|
||||
{
|
||||
$start = \Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = \Session::get('end', Carbon::now()->startOfMonth());
|
||||
$list = Auth::user()
|
||||
->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.*']);
|
||||
$subTitle = 'Transactions without a budget in ' . $start->format('F Y');
|
||||
|
||||
return view('budgets.noBudget', compact('list', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function postUpdateIncome()
|
||||
{
|
||||
|
||||
$date = Session::get('start', Carbon::now()->startOfMonth())->format('FY');
|
||||
Preferences::set('budgetIncomeTotal' . $date, intval(Input::get('amount')));
|
||||
|
||||
return Redirect::route('budgets.index');
|
||||
}
|
||||
|
||||
public function store(BudgetFormRequest $request, BudgetRepositoryInterface $repository)
|
||||
{
|
||||
$budgetData = [
|
||||
'name' => $request->input('name'),
|
||||
'user' => Auth::user()->id,
|
||||
];
|
||||
$budget = $repository->store($budgetData);
|
||||
|
||||
Session::flash('success', 'New budget "' . $budget->name . '" stored!');
|
||||
|
||||
return Redirect::route('budgets.index');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @param LimitRepetition $repetition
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function show(Budget $budget, LimitRepetition $repetition = null, BudgetRepositoryInterface $repository)
|
||||
{
|
||||
if (!is_null($repetition->id) && $repetition->budgetLimit->budget->id != $budget->id) {
|
||||
return view('error')->with('message', 'Invalid selection.');
|
||||
}
|
||||
|
||||
$hideBudget = true; // used in transaction list.
|
||||
$journals = $repository->getJournals($budget, $repetition);
|
||||
$limits = !is_null($repetition->id) ? [$repetition->budgetLimit] : $budget->budgetLimits()->orderBy('startdate', 'DESC')->get();
|
||||
$subTitle = !is_null($repetition->id) ? e($budget->name) . ' in ' . $repetition->startdate->format('F Y') : e($budget->name);
|
||||
|
||||
return view('budgets.show', compact('limits', 'budget', 'repetition', 'journals', 'subTitle', 'hideBudget'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
* @param BudgetFormRequest $request
|
||||
* @param BudgetRepositoryInterface $repository
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(Budget $budget, BudgetFormRequest $request, BudgetRepositoryInterface $repository)
|
||||
{
|
||||
$budgetData = [
|
||||
'name' => $request->input('name'),
|
||||
];
|
||||
|
||||
$repository->update($budget, $budgetData);
|
||||
|
||||
Session::flash('success', 'Budget "' . $budget->name . '" updated.');
|
||||
|
||||
return Redirect::route('budgets.index');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function updateIncome()
|
||||
{
|
||||
$date = Session::get('start', Carbon::now()->startOfMonth())->format('FY');
|
||||
$budgetAmount = Preferences::get('budgetIncomeTotal' . $date, 1000);
|
||||
|
||||
return view('budgets.income')->with('amount', $budgetAmount);
|
||||
}
|
||||
|
||||
}
|
172
app/Http/Controllers/CategoryController.php
Normal file
172
app/Http/Controllers/CategoryController.php
Normal file
@ -0,0 +1,172 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\CategoryFormRequest;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use View;
|
||||
use Input;
|
||||
|
||||
|
||||
/**
|
||||
* Class CategoryController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class CategoryController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
View::share('title', 'Categories');
|
||||
View::share('mainTitleIcon', 'fa-bar-chart');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('categories.create')->with('subTitle', 'Create a new category');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function show(Category $category, CategoryRepositoryInterface $repository)
|
||||
{
|
||||
$hideCategory = true; // used in list.
|
||||
$page = intval(Input::get('page'));
|
||||
$offset = $page > 0 ? $page * 50 : 0;
|
||||
$set = $category->transactionJournals()->withRelevantData()->take(50)->offset($offset)->orderBy('date', 'DESC')->get(['transaction_journals.*']);
|
||||
$count = $category->transactionJournals()->count();
|
||||
|
||||
$journals = new LengthAwarePaginator($set, $count, 50, $page);
|
||||
|
||||
return view('categories.show', compact('category', 'journals', 'hideCategory'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function noCategory()
|
||||
{
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->startOfMonth());
|
||||
$list = Auth::user()
|
||||
->transactionjournals()
|
||||
->leftJoin('category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->whereNull('category_transaction_journal.id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->orderBy('transaction_journals.date')
|
||||
->get(['transaction_journals.*']);
|
||||
$subTitle = 'Transactions without a category in ' . $start->format('F Y');
|
||||
|
||||
return view('categories.noCategory', compact('list', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function delete(Category $category)
|
||||
{
|
||||
$subTitle = 'Delete category' . e($category->name) . '"';
|
||||
|
||||
return view('categories.delete', compact('category', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Category $category, CategoryRepositoryInterface $repository)
|
||||
{
|
||||
|
||||
$name = $category->name;
|
||||
$repository->destroy($category);
|
||||
|
||||
Session::flash('success', 'The category "' . e($name) . '" was deleted.');
|
||||
|
||||
return Redirect::route('categories.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function edit(Category $category)
|
||||
{
|
||||
$subTitle = 'Edit category "' . e($category->name) . '"';
|
||||
|
||||
return view('categories.edit', compact('category', 'subTitle'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$categories = Auth::user()->categories()->get();
|
||||
|
||||
return view('categories.index', compact('categories'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CategoryFormRequest $request
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function store(CategoryFormRequest $request, CategoryRepositoryInterface $repository)
|
||||
{
|
||||
$categoryData = [
|
||||
'name' => $request->input('name'),
|
||||
'user' => Auth::user()->id,
|
||||
];
|
||||
$category = $repository->store($categoryData);
|
||||
|
||||
Session::flash('success', 'New category "' . $category->name . '" stored!');
|
||||
|
||||
return Redirect::route('categories.index');
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param CategoryFormRequest $request
|
||||
* @param CategoryRepositoryInterface $repository
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(Category $category, CategoryFormRequest $request, CategoryRepositoryInterface $repository)
|
||||
{
|
||||
$categoryData = [
|
||||
'name' => $request->input('name'),
|
||||
];
|
||||
|
||||
$repository->update($category, $categoryData);
|
||||
|
||||
Session::flash('success', 'Category "' . $category->name . '" updated.');
|
||||
|
||||
return Redirect::route('categories.index');
|
||||
|
||||
}
|
||||
|
||||
}
|
17
app/Http/Controllers/Controller.php
Normal file
17
app/Http/Controllers/Controller.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Bus\DispatchesCommands;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
/**
|
||||
* Class Controller
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
abstract class Controller extends BaseController
|
||||
{
|
||||
|
||||
use DispatchesCommands, ValidatesRequests;
|
||||
|
||||
}
|
172
app/Http/Controllers/CurrencyController.php
Normal file
172
app/Http/Controllers/CurrencyController.php
Normal file
@ -0,0 +1,172 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\CurrencyFormRequest;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use Preferences;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use View;
|
||||
use Cache;
|
||||
|
||||
/**
|
||||
* Class CurrencyController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class CurrencyController extends Controller
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
View::share('title', 'Currencies');
|
||||
View::share('mainTitleIcon', 'fa-usd');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$subTitleIcon = 'fa-plus';
|
||||
$subTitle = 'Create a new currency';
|
||||
|
||||
return view('currency.create', compact('subTitleIcon', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function defaultCurrency(TransactionCurrency $currency)
|
||||
{
|
||||
|
||||
$currencyPreference = Preferences::get('currencyPreference', 'EUR');
|
||||
$currencyPreference->data = $currency->code;
|
||||
$currencyPreference->save();
|
||||
|
||||
Session::flash('success', $currency->name . ' is now the default currency.');
|
||||
Cache::forget('FFCURRENCYSYMBOL');
|
||||
Cache::forget('FFCURRENCYCODE');
|
||||
|
||||
return Redirect::route('currency.index');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
|
||||
*/
|
||||
public function delete(TransactionCurrency $currency)
|
||||
{
|
||||
if ($currency->transactionJournals()->count() > 0) {
|
||||
Session::flash('error', 'Cannot delete ' . e($currency->name) . ' because there are still transactions attached to it.');
|
||||
|
||||
return Redirect::route('currency.index');
|
||||
}
|
||||
|
||||
|
||||
return view('currency.delete', compact('currency'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(TransactionCurrency $currency)
|
||||
{
|
||||
if ($currency->transactionJournals()->count() > 0) {
|
||||
Session::flash('error', 'Cannot delete ' . e($currency->name) . ' because there are still transactions attached to it.');
|
||||
|
||||
return Redirect::route('currency.index');
|
||||
}
|
||||
|
||||
Session::flash('success', 'Currency "' . e($currency->name) . '" deleted');
|
||||
|
||||
$currency->delete();
|
||||
|
||||
return Redirect::route('currency.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function edit(TransactionCurrency $currency)
|
||||
{
|
||||
$subTitleIcon = 'fa-pencil';
|
||||
$subTitle = 'Edit currency "' . e($currency->name) . '"';
|
||||
$currency->symbol = htmlentities($currency->symbol);
|
||||
|
||||
return view('currency.edit', compact('currency', 'subTitle', 'subTitleIcon'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$currencies = TransactionCurrency::get();
|
||||
$currencyPreference = Preferences::get('currencyPreference', 'EUR');
|
||||
$defaultCurrency = TransactionCurrency::whereCode($currencyPreference->data)->first();
|
||||
|
||||
|
||||
return view('currency.index', compact('currencies', 'defaultCurrency'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @return $this|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(CurrencyFormRequest $request)
|
||||
{
|
||||
|
||||
|
||||
// no repository, because the currency controller is relatively simple.
|
||||
$currency = TransactionCurrency::create(
|
||||
[
|
||||
'name' => $request->get('name'),
|
||||
'code' => $request->get('code'),
|
||||
'symbol' => $request->get('symbol'),
|
||||
]
|
||||
);
|
||||
|
||||
Session::flash('success', 'Currency "' . $currency->name . '" created');
|
||||
|
||||
return Redirect::route('currency.index');
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
*
|
||||
* @return $this|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(TransactionCurrency $currency, CurrencyFormRequest $request)
|
||||
{
|
||||
|
||||
$currency->code = $request->get('code');
|
||||
$currency->symbol = $request->get('symbol');
|
||||
$currency->name = $request->get('name');
|
||||
$currency->save();
|
||||
|
||||
Session::flash('success', 'Currency "' . e($currency->namename) . '" updated.');
|
||||
|
||||
return Redirect::route('currency.index');
|
||||
|
||||
}
|
||||
|
||||
}
|
635
app/Http/Controllers/GoogleChartController.php
Normal file
635
app/Http/Controllers/GoogleChartController.php
Normal file
@ -0,0 +1,635 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use App;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use Exception;
|
||||
use FireflyIII\Helpers\Report\ReportQueryInterface;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use Grumpydictator\Gchart\GChart;
|
||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Navigation;
|
||||
use Preferences;
|
||||
use Response;
|
||||
use Session;
|
||||
use DB;
|
||||
use Steam;
|
||||
|
||||
/**
|
||||
* Class GoogleChartController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class GoogleChartController extends Controller
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param string $view
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function accountBalanceChart(Account $account, $view = 'session', GChart $chart)
|
||||
{
|
||||
$chart->addColumn('Day of month', 'date');
|
||||
$chart->addColumn('Balance for ' . $account->name, 'number');
|
||||
$chart->addCertainty(1);
|
||||
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$count = $account->transactions()->count();
|
||||
|
||||
if ($view == 'all' && $count > 0) {
|
||||
$first = $account->transactions()->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->orderBy(
|
||||
'date', 'ASC'
|
||||
)->first(['transaction_journals.date']);
|
||||
$last = $account->transactions()->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')->orderBy(
|
||||
'date', 'DESC'
|
||||
)->first(['transaction_journals.date']);
|
||||
$start = new Carbon($first->date);
|
||||
$end = new Carbon($last->date);
|
||||
}
|
||||
|
||||
$current = clone $start;
|
||||
|
||||
while ($end >= $current) {
|
||||
$chart->addRow(clone $current, Steam::balance($account, $current), false);
|
||||
$current->addDay();
|
||||
}
|
||||
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return Response::json($chart->getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GChart $chart
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function allAccountsBalanceChart(GChart $chart)
|
||||
{
|
||||
$chart->addColumn('Day of the month', 'date');
|
||||
|
||||
$frontPage = Preferences::get('frontPageAccounts', []);
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
|
||||
if ($frontPage->data == []) {
|
||||
$accounts = Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']);
|
||||
} else {
|
||||
$accounts = Auth::user()->accounts()->whereIn('id', $frontPage->data)->get(['accounts.*']);
|
||||
}
|
||||
$index = 1;
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
$chart->addColumn('Balance for ' . $account->name, 'number');
|
||||
$chart->addCertainty($index);
|
||||
$index++;
|
||||
}
|
||||
$current = clone $start;
|
||||
$current->subDay();
|
||||
$today = Carbon::now();
|
||||
while ($end >= $current) {
|
||||
$row = [clone $current];
|
||||
$certain = $current < $today;
|
||||
foreach ($accounts as $account) {
|
||||
$row[] = Steam::balance($account, $current);
|
||||
$row[] = $certain;
|
||||
}
|
||||
$chart->addRowArray($row);
|
||||
$current->addDay();
|
||||
}
|
||||
$chart->generate();
|
||||
|
||||
return Response::json($chart->getData());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $year
|
||||
*
|
||||
* @return $this|\Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function allBudgetsAndSpending($year, GChart $chart, BudgetRepositoryInterface $repository)
|
||||
{
|
||||
try {
|
||||
new Carbon('01-01-' . $year);
|
||||
} catch (Exception $e) {
|
||||
return view('error')->with('message', 'Invalid year.');
|
||||
}
|
||||
$budgets = Auth::user()->budgets()->get();
|
||||
$budgets->sortBy('name');
|
||||
$chart->addColumn('Month', 'date');
|
||||
foreach ($budgets as $budget) {
|
||||
$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 = $repository->spentInMonth($budget, $start);
|
||||
$row[] = $spent;
|
||||
}
|
||||
$chart->addRowArray($row);
|
||||
$start->addMonth();
|
||||
}
|
||||
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return Response::json($chart->getData());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GChart $chart
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function allBudgetsHomeChart(GChart $chart)
|
||||
{
|
||||
$chart->addColumn('Budget', 'string');
|
||||
$chart->addColumn('Budgeted', 'number');
|
||||
$chart->addColumn('Spent', 'number');
|
||||
|
||||
$budgets = Auth::user()->budgets()->orderBy('name', 'DESC')->get();
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
|
||||
/** @var Budget $budget */
|
||||
foreach ($budgets as $budget) {
|
||||
|
||||
/** @var \LimitRepetition $repetition */
|
||||
$repetition = LimitRepetition::
|
||||
leftJoin('budget_limits', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')
|
||||
->where('limit_repetitions.startdate', $start->format('Y-m-d 00:00:00'))
|
||||
->where('budget_limits.budget_id', $budget->id)
|
||||
->first(['limit_repetitions.*']);
|
||||
if (is_null($repetition)) { // use the session start and end for our search query
|
||||
$searchStart = $start;
|
||||
$searchEnd = $end;
|
||||
$limit = 0; // the limit is zero:
|
||||
} else {
|
||||
// use the limit's start and end for our search query
|
||||
$searchStart = $repetition->startdate;
|
||||
$searchEnd = $repetition->enddate;
|
||||
$limit = floatval($repetition->amount); // the limit is the repetitions limit:
|
||||
}
|
||||
|
||||
$expenses = floatval($budget->transactionjournals()->before($searchEnd)->after($searchStart)->lessThan(0)->sum('amount')) * -1;
|
||||
if ($expenses > 0) {
|
||||
$chart->addRow($budget->name, $limit, $expenses);
|
||||
}
|
||||
}
|
||||
|
||||
$noBudgetSet = Auth::user()
|
||||
->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();
|
||||
$sum = $noBudgetSet->sum('amount') * -1;
|
||||
$chart->addRow('No budget', 0, $sum);
|
||||
$chart->generate();
|
||||
|
||||
return Response::json($chart->getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GChart $chart
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function allCategoriesHomeChart(GChart $chart)
|
||||
{
|
||||
$chart->addColumn('Category', 'string');
|
||||
$chart->addColumn('Spent', 'number');
|
||||
|
||||
// query!
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
$set = TransactionJournal::leftJoin(
|
||||
'transactions',
|
||||
function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'category_transaction_journal', 'category_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'
|
||||
)
|
||||
->leftJoin('categories', 'categories.id', '=', 'category_transaction_journal.category_id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
|
||||
->before($end)
|
||||
->after($start)
|
||||
->where('transaction_types.type', 'Withdrawal')
|
||||
->groupBy('categories.id')
|
||||
->orderBy('sum', 'DESC')
|
||||
->get(['categories.id', 'categories.name', \DB::Raw('SUM(`transactions`.`amount`) AS `sum`')]);
|
||||
|
||||
foreach ($set as $entry) {
|
||||
$entry->name = strlen($entry->name) == 0 ? '(no category)' : $entry->name;
|
||||
$chart->addRow($entry->name, floatval($entry->sum));
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return Response::json($chart->getData());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function billOverview(Bill $bill, GChart $chart)
|
||||
{
|
||||
|
||||
$chart->addColumn('Date', 'date');
|
||||
$chart->addColumn('Max amount', 'number');
|
||||
$chart->addColumn('Min amount', 'number');
|
||||
$chart->addColumn('Current entry', 'number');
|
||||
|
||||
// get first transaction or today for start:
|
||||
$first = $bill->transactionjournals()->orderBy('date', 'ASC')->first();
|
||||
if ($first) {
|
||||
$start = $first->date;
|
||||
} else {
|
||||
$start = new Carbon;
|
||||
}
|
||||
$end = new Carbon;
|
||||
while ($start <= $end) {
|
||||
$result = $bill->transactionjournals()->before($end)->after($start)->first();
|
||||
if ($result) {
|
||||
/** @var Transaction $tr */
|
||||
foreach ($result->transactions()->get() as $tr) {
|
||||
if (floatval($tr->amount) > 0) {
|
||||
$amount = floatval($tr->amount);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$amount = 0;
|
||||
}
|
||||
unset($result);
|
||||
$chart->addRow(clone $start, $bill->amount_max, $bill->amount_min, $amount);
|
||||
$start = Navigation::addPeriod($start, $bill->repeat_freq, 0);
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return Response::json($chart->getData());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param GChart $chart
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function billsOverview(GChart $chart)
|
||||
{
|
||||
$paid = ['items' => [], 'amount' => 0];
|
||||
$unpaid = ['items' => [], 'amount' => 0];
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
|
||||
$chart->addColumn('Name', 'string');
|
||||
$chart->addColumn('Amount', 'number');
|
||||
|
||||
$set = Bill::
|
||||
leftJoin(
|
||||
'transaction_journals', function (JoinClause $join) use ($start, $end) {
|
||||
$join->on('bills.id', '=', 'transaction_journals.bill_id')
|
||||
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
|
||||
->where('transaction_journals.date', '<=', $end->format('Y-m-d'));
|
||||
}
|
||||
)
|
||||
->leftJoin(
|
||||
'transactions', function (JoinClause $join) {
|
||||
$join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transactions.amount', '>', 0);
|
||||
}
|
||||
)
|
||||
->where('active', 1)
|
||||
->groupBy('bills.id')
|
||||
->get(
|
||||
['bills.id', 'bills.name', 'transaction_journals.description',
|
||||
'transaction_journals.encrypted',
|
||||
'transaction_journals.id as journalId',
|
||||
\DB::Raw('SUM(`bills`.`amount_min` + `bills`.`amount_max`) / 2 as `averageAmount`'),
|
||||
'transactions.amount AS actualAmount']
|
||||
);
|
||||
|
||||
foreach ($set as $entry) {
|
||||
if (intval($entry->journalId) == 0) {
|
||||
$unpaid['items'][] = $entry->name;
|
||||
$unpaid['amount'] += floatval($entry->averageAmount);
|
||||
} else {
|
||||
$description = intval($entry->encrypted) == 1 ? Crypt::decrypt($entry->description) : $entry->description;
|
||||
$paid['items'][] = $description;
|
||||
$paid['amount'] += floatval($entry->actualAmount);
|
||||
}
|
||||
}
|
||||
$chart->addRow('Unpaid: ' . join(', ', $unpaid['items']), $unpaid['amount']);
|
||||
$chart->addRow('Paid: ' . join(', ', $paid['items']), $paid['amount']);
|
||||
$chart->generate();
|
||||
|
||||
return Response::json($chart->getData());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @param LimitRepetition $repetition
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function budgetLimitSpending(Budget $budget, LimitRepetition $repetition, GChart $chart)
|
||||
{
|
||||
$start = clone $repetition->startdate;
|
||||
$end = $repetition->enddate;
|
||||
|
||||
$chart->addColumn('Day', 'date');
|
||||
$chart->addColumn('Left', 'number');
|
||||
|
||||
|
||||
$amount = $repetition->amount;
|
||||
|
||||
while ($start <= $end) {
|
||||
/*
|
||||
* Sum of expenses on this day:
|
||||
*/
|
||||
$sum = floatval($budget->transactionjournals()->lessThan(0)->transactionTypes(['Withdrawal'])->onDate($start)->sum('amount'));
|
||||
$amount += $sum;
|
||||
$chart->addRow(clone $start, $amount);
|
||||
$start->addDay();
|
||||
}
|
||||
$chart->generate();
|
||||
|
||||
return Response::json($chart->getData());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @param int $year
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function budgetsAndSpending(Budget $budget, $year = 0)
|
||||
{
|
||||
|
||||
$chart = App::make('Grumpydictator\Gchart\GChart');
|
||||
$repository = App::make('FireflyIII\Repositories\Budget\BudgetRepository');
|
||||
$chart->addColumn('Month', 'date');
|
||||
$chart->addColumn('Budgeted', 'number');
|
||||
$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();
|
||||
}
|
||||
|
||||
while ($start <= $end) {
|
||||
$spent = $repository->spentInMonth($budget, $start);
|
||||
$repetition = LimitRepetition::leftJoin('budget_limits', 'limit_repetitions.budget_limit_id', '=', 'budget_limits.id')
|
||||
->where('limit_repetitions.startdate', $start->format('Y-m-d 00:00:00'))
|
||||
->where('budget_limits.budget_id', $budget->id)
|
||||
->first(['limit_repetitions.*']);
|
||||
|
||||
if ($repetition) {
|
||||
$budgeted = floatval($repetition->amount);
|
||||
\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);
|
||||
$budgeted = null;
|
||||
}
|
||||
$chart->addRow(clone $start, $budgeted, $spent);
|
||||
$start->addMonth();
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return Response::json($chart->getData());
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Category $category
|
||||
* @param $year
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function categoriesAndSpending(Category $category, $year, GChart $chart)
|
||||
{
|
||||
try {
|
||||
new Carbon('01-01-' . $year);
|
||||
} catch (Exception $e) {
|
||||
return view('error')->with('message', 'Invalid year.');
|
||||
}
|
||||
|
||||
$chart->addColumn('Month', 'date');
|
||||
$chart->addColumn('Budgeted', 'number');
|
||||
$chart->addColumn('Spent', 'number');
|
||||
|
||||
$start = new Carbon('01-01-' . $year);
|
||||
$end = clone $start;
|
||||
$end->endOfYear();
|
||||
while ($start <= $end) {
|
||||
|
||||
$currentEnd = clone $start;
|
||||
$currentEnd->endOfMonth();
|
||||
$spent = floatval($category->transactionjournals()->before($end)->after($start)->lessThan(0)->sum('amount')) * -1;
|
||||
$budgeted = null;
|
||||
|
||||
$chart->addRow(clone $start, $budgeted, $spent);
|
||||
|
||||
$start->addMonth();
|
||||
}
|
||||
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return Response::json($chart->getData());
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBank $piggyBank
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function piggyBankHistory(PiggyBank $piggyBank, GChart $chart)
|
||||
{
|
||||
$chart->addColumn('Date', 'date');
|
||||
$chart->addColumn('Balance', 'number');
|
||||
|
||||
$set = \DB::table('piggy_bank_events')->where('piggy_bank_id', $piggyBank->id)->groupBy('date')->get(['date', DB::Raw('SUM(`amount`) AS `sum`')]);
|
||||
|
||||
foreach ($set as $entry) {
|
||||
$chart->addRow(new Carbon($entry->date), floatval($entry->sum));
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return Response::json($chart->getData());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param $year
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function yearInExp($year, GChart $chart, ReportQueryInterface $query)
|
||||
{
|
||||
try {
|
||||
$start = new Carbon('01-01-' . $year);
|
||||
} catch (Exception $e) {
|
||||
return view('error')->with('message', 'Invalid year.');
|
||||
}
|
||||
$chart->addColumn('Month', 'date');
|
||||
$chart->addColumn('Income', 'number');
|
||||
$chart->addColumn('Expenses', 'number');
|
||||
|
||||
// get report query interface.
|
||||
|
||||
$end = clone $start;
|
||||
$end->endOfYear();
|
||||
while ($start < $end) {
|
||||
$currentEnd = clone $start;
|
||||
$currentEnd->endOfMonth();
|
||||
// total income:
|
||||
$income = $query->incomeByPeriod($start, $currentEnd);
|
||||
$incomeSum = 0;
|
||||
foreach ($income as $entry) {
|
||||
$incomeSum += floatval($entry->amount);
|
||||
}
|
||||
|
||||
// total expenses:
|
||||
$expense = $query->journalsByExpenseAccount($start, $currentEnd);
|
||||
$expenseSum = 0;
|
||||
foreach ($expense as $entry) {
|
||||
$expenseSum += floatval($entry->amount);
|
||||
}
|
||||
|
||||
$chart->addRow(clone $start, $incomeSum, $expenseSum);
|
||||
$start->addMonth();
|
||||
}
|
||||
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return Response::json($chart->getData());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param $year
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function yearInExpSum($year, GChart $chart, ReportQueryInterface $query)
|
||||
{
|
||||
try {
|
||||
$start = new Carbon('01-01-' . $year);
|
||||
} catch (Exception $e) {
|
||||
return view('error')->with('message', 'Invalid year.');
|
||||
}
|
||||
$chart->addColumn('Summary', 'string');
|
||||
$chart->addColumn('Income', 'number');
|
||||
$chart->addColumn('Expenses', 'number');
|
||||
|
||||
$income = 0;
|
||||
$expense = 0;
|
||||
$count = 0;
|
||||
|
||||
$end = clone $start;
|
||||
$end->endOfYear();
|
||||
while ($start < $end) {
|
||||
$currentEnd = clone $start;
|
||||
$currentEnd->endOfMonth();
|
||||
// total income:
|
||||
$incomeResult = $query->incomeByPeriod($start, $currentEnd);
|
||||
$incomeSum = 0;
|
||||
foreach ($incomeResult as $entry) {
|
||||
$incomeSum += floatval($entry->amount);
|
||||
}
|
||||
|
||||
// total expenses:
|
||||
$expenseResult = $query->journalsByExpenseAccount($start, $currentEnd);
|
||||
$expenseSum = 0;
|
||||
foreach ($expenseResult as $entry) {
|
||||
$expenseSum += floatval($entry->amount);
|
||||
}
|
||||
|
||||
$income += $incomeSum;
|
||||
$expense += $expenseSum;
|
||||
$count++;
|
||||
$start->addMonth();
|
||||
}
|
||||
|
||||
|
||||
$chart->addRow('Sum', $income, $expense);
|
||||
$count = $count > 0 ? $count : 1;
|
||||
$chart->addRow('Average', ($income / $count), ($expense / $count));
|
||||
|
||||
$chart->generate();
|
||||
|
||||
return Response::json($chart->getData());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,13 +1,22 @@
|
||||
<?php
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use ErrorException;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use League\CommonMark\CommonMarkConverter;
|
||||
use Route;
|
||||
use Response;
|
||||
use Cache;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
*
|
||||
* Class HelpController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class HelpController extends BaseController
|
||||
{
|
||||
class HelpController extends Controller {
|
||||
|
||||
/**
|
||||
* @param $route
|
||||
*
|
||||
@ -74,11 +83,12 @@ class HelpController extends BaseController
|
||||
if (strlen(trim($content['text'])) == 0) {
|
||||
$content['text'] = '<p>There is no help for this route.</p>';
|
||||
}
|
||||
$content['text'] = \Michelf\Markdown::defaultTransform($content['text']);
|
||||
$converter = new CommonMarkConverter();
|
||||
$content['text'] = $converter->convertToHtml($content['text']);
|
||||
|
||||
return $content;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
124
app/Http/Controllers/HomeController.php
Normal file
124
app/Http/Controllers/HomeController.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Cache;
|
||||
use Carbon\Carbon;
|
||||
use Navigation;
|
||||
use Preferences;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use URL;
|
||||
|
||||
/**
|
||||
* Class HomeController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class HomeController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function flush()
|
||||
{
|
||||
Cache::flush();
|
||||
|
||||
return Redirect::route('index');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$count = Auth::user()->accounts()->accountTypeIn(['Asset account', 'Default account'])->count();
|
||||
$title = 'Firefly';
|
||||
$subTitle = 'What\'s playing?';
|
||||
$mainTitleIcon = 'fa-fire';
|
||||
$transactions = [];
|
||||
$frontPage = Preferences::get('frontPageAccounts', []);
|
||||
$start = Session::get('start', Carbon::now()->startOfMonth());
|
||||
$end = Session::get('end', Carbon::now()->endOfMonth());
|
||||
|
||||
if ($frontPage->data == []) {
|
||||
$accounts = Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']);
|
||||
} else {
|
||||
$accounts = Auth::user()->accounts()->whereIn('id', $frontPage->data)->get(['accounts.*']);
|
||||
}
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$set = Auth::user()
|
||||
->transactionjournals()
|
||||
->with(['transactions', 'transactioncurrency', 'transactiontype'])
|
||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')->where('accounts.id', $account->id)
|
||||
->where('date', '>=', $start->format('Y-m-d'))
|
||||
->where('date', '<=', $end->format('Y-m-d'))
|
||||
->orderBy('transaction_journals.date', 'DESC')
|
||||
->orderBy('transaction_journals.id', 'DESC')
|
||||
->take(10)
|
||||
->get(['transaction_journals.*']);
|
||||
if (count($set) > 0) {
|
||||
$transactions[] = [$set, $account];
|
||||
}
|
||||
}
|
||||
|
||||
// var_dump($transactions);
|
||||
|
||||
return view('index', compact('count', 'title', 'subTitle', 'mainTitleIcon', 'transactions'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $range
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function rangeJump($range)
|
||||
{
|
||||
|
||||
$valid = ['1D', '1W', '1M', '3M', '6M', '1Y',];
|
||||
|
||||
if (in_array($range, $valid)) {
|
||||
Preferences::set('viewRange', $range);
|
||||
Session::forget('range');
|
||||
}
|
||||
|
||||
return Redirect::to(URL::previous());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function sessionNext()
|
||||
{
|
||||
$range = Session::get('range');
|
||||
$start = Session::get('start');
|
||||
|
||||
Session::put('start', Navigation::jumpToNext($range, clone $start));
|
||||
|
||||
return Redirect::to(URL::previous());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function sessionPrev()
|
||||
{
|
||||
$range = Session::get('range');
|
||||
$start = Session::get('start');
|
||||
|
||||
Session::put('start', Navigation::jumpToPrevious($range, clone $start));
|
||||
|
||||
return Redirect::to(URL::previous());
|
||||
}
|
||||
|
||||
}
|
@ -1,11 +1,19 @@
|
||||
<?php
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Response;
|
||||
use Auth;
|
||||
|
||||
/**
|
||||
* Class JsonController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class JsonController extends BaseController
|
||||
{
|
||||
class JsonController extends Controller {
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of categories.
|
||||
@ -14,9 +22,7 @@ class JsonController extends BaseController
|
||||
*/
|
||||
public function categories()
|
||||
{
|
||||
/** @var \FireflyIII\Database\Category\Category $categories */
|
||||
$categories = App::make('FireflyIII\Database\Category\Category');
|
||||
$list = $categories->get();
|
||||
$list = Auth::user()->categories()->orderBy('name','ASC')->get();
|
||||
$return = [];
|
||||
foreach ($list as $entry) {
|
||||
$return[] = $entry->name;
|
||||
@ -34,9 +40,7 @@ class JsonController extends BaseController
|
||||
*/
|
||||
public function expenseAccounts()
|
||||
{
|
||||
/** @var \FireflyIII\Database\Account\Account $accounts */
|
||||
$accounts = App::make('FireflyIII\Database\Account\Account');
|
||||
$list = $accounts->getAccountsByType(['Expense account', 'Beneficiary account']);
|
||||
$list = Auth::user()->accounts()->accountTypeIn(['Expense account', 'Beneficiary account'])->get();
|
||||
$return = [];
|
||||
foreach ($list as $entry) {
|
||||
$return[] = $entry->name;
|
||||
@ -51,9 +55,7 @@ class JsonController extends BaseController
|
||||
*/
|
||||
public function revenueAccounts()
|
||||
{
|
||||
/** @var \FireflyIII\Database\Account\Account $accounts */
|
||||
$accounts = App::make('FireflyIII\Database\Account\Account');
|
||||
$list = $accounts->getAccountsByType(['Revenue account']);
|
||||
$list = Auth::user()->accounts()->accountTypeIn(['Revenue account'])->get();
|
||||
$return = [];
|
||||
foreach ($list as $entry) {
|
||||
$return[] = $entry->name;
|
||||
@ -62,4 +64,5 @@ class JsonController extends BaseController
|
||||
return Response::json($return);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,30 +1,36 @@
|
||||
<?php
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Amount;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Database\PiggyBank\PiggyBank as Repository;
|
||||
use FireflyIII\Exception\FireflyException;
|
||||
use Config;
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\PiggyBankFormRequest;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Input;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use Steam;
|
||||
use View;
|
||||
|
||||
/**
|
||||
*
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
*
|
||||
*
|
||||
* Class PiggyBankController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class PiggyBankController extends BaseController
|
||||
class PiggyBankController extends Controller
|
||||
{
|
||||
|
||||
/** @var Repository */
|
||||
protected $_repository;
|
||||
|
||||
/**
|
||||
* @param Repository $repository
|
||||
*
|
||||
*/
|
||||
public function __construct(Repository $repository)
|
||||
public function __construct()
|
||||
{
|
||||
$this->_repository = $repository;
|
||||
View::share('title', 'Piggy banks');
|
||||
View::share('mainTitleIcon', 'fa-sort-amount-asc');
|
||||
}
|
||||
@ -36,9 +42,9 @@ class PiggyBankController extends BaseController
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function add(PiggyBank $piggyBank)
|
||||
public function add(PiggyBank $piggyBank, AccountRepositoryInterface $repository)
|
||||
{
|
||||
$leftOnAccount = $this->_repository->leftOnAccount($piggyBank->account);
|
||||
$leftOnAccount = $repository->leftOnAccount($piggyBank->account);
|
||||
$savedSoFar = $piggyBank->currentRelevantRep()->currentamount;
|
||||
$leftToSave = $piggyBank->targetamount - $savedSoFar;
|
||||
$maxAmount = min($leftOnAccount, $leftToSave);
|
||||
@ -46,7 +52,7 @@ class PiggyBankController extends BaseController
|
||||
|
||||
\Log::debug('Now going to view for piggy bank #' . $piggyBank->id . ' (' . $piggyBank->name . ')');
|
||||
|
||||
return View::make('piggy_banks.add', compact('piggyBank', 'maxAmount'));
|
||||
return view('piggy-banks.add', compact('piggyBank', 'maxAmount'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,15 +61,12 @@ class PiggyBankController extends BaseController
|
||||
public function create()
|
||||
{
|
||||
|
||||
/** @var \FireflyIII\Database\Account\Account $acct */
|
||||
$acct = App::make('FireflyIII\Database\Account\Account');
|
||||
|
||||
$periods = Config::get('firefly.piggy_bank_periods');
|
||||
$accounts = FFForm::makeSelectList($acct->getAccountsByType(['Default account', 'Asset account']));
|
||||
$accounts = ExpandedForm::makeSelectList(Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']));
|
||||
$subTitle = 'Create new piggy bank';
|
||||
$subTitleIcon = 'fa-plus';
|
||||
|
||||
return View::make('piggy_banks.create', compact('accounts', 'periods', 'subTitle', 'subTitleIcon'));
|
||||
return view('piggy-banks.create', compact('accounts', 'periods', 'subTitle', 'subTitleIcon'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,7 +78,7 @@ class PiggyBankController extends BaseController
|
||||
{
|
||||
$subTitle = 'Delete "' . e($piggyBank->name) . '"';
|
||||
|
||||
return View::make('piggy_banks.delete', compact('piggyBank', 'subTitle'));
|
||||
return view('piggy_banks.delete', compact('piggyBank', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,11 +105,8 @@ class PiggyBankController extends BaseController
|
||||
public function edit(PiggyBank $piggyBank)
|
||||
{
|
||||
|
||||
/** @var \FireflyIII\Database\Account\Account $acct */
|
||||
$acct = App::make('FireflyIII\Database\Account\Account');
|
||||
|
||||
$periods = Config::get('firefly.piggy_bank_periods');
|
||||
$accounts = FFForm::makeSelectList($acct->getAccountsByType(['Default account', 'Asset account']));
|
||||
$accounts = ExpandedForm::makeSelectList(Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']));
|
||||
$subTitle = 'Edit piggy bank "' . e($piggyBank->name) . '"';
|
||||
$subTitleIcon = 'fa-pencil';
|
||||
|
||||
@ -128,16 +128,17 @@ class PiggyBankController extends BaseController
|
||||
];
|
||||
Session::flash('preFilled', $preFilled);
|
||||
|
||||
return View::make('piggy_banks.edit', compact('subTitle', 'subTitleIcon', 'piggyBank', 'accounts', 'periods', 'preFilled'));
|
||||
return view('piggy-banks.edit', compact('subTitle', 'subTitleIcon', 'piggyBank', 'accounts', 'periods', 'preFilled'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function index()
|
||||
public function index(AccountRepositoryInterface $repository)
|
||||
{
|
||||
/** @var Collection $piggyBanks */
|
||||
$piggyBanks = $this->_repository->get();
|
||||
$piggyBanks = Auth::user()->piggyBanks()->where('repeats', 0)->get();
|
||||
|
||||
$accounts = [];
|
||||
/** @var PiggyBank $piggyBank */
|
||||
@ -154,7 +155,7 @@ class PiggyBankController extends BaseController
|
||||
$accounts[$account->id] = [
|
||||
'name' => $account->name,
|
||||
'balance' => Steam::balance($account),
|
||||
'leftForPiggyBanks' => $this->_repository->leftOnAccount($account),
|
||||
'leftForPiggyBanks' => $repository->leftOnAccount($account),
|
||||
'sumOfSaved' => $piggyBank->savedSoFar,
|
||||
'sumOfTargets' => floatval($piggyBank->targetamount),
|
||||
'leftToSave' => $piggyBank->leftToSave
|
||||
@ -166,9 +167,10 @@ class PiggyBankController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
return View::make('piggy_banks.index', compact('piggyBanks', 'accounts'));
|
||||
return view('piggy-banks.index', compact('piggyBanks', 'accounts'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* POST add money to piggy bank
|
||||
*
|
||||
@ -176,14 +178,10 @@ class PiggyBankController extends BaseController
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postAdd(PiggyBank $piggyBank)
|
||||
public function postAdd(PiggyBank $piggyBank, PiggyBankRepositoryInterface $repository, AccountRepositoryInterface $accounts)
|
||||
{
|
||||
$amount = round(floatval(Input::get('amount')), 2);
|
||||
|
||||
/** @var \FireflyIII\Database\PiggyBank\PiggyBank $acct */
|
||||
$piggyRepository = App::make('FireflyIII\Database\PiggyBank\PiggyBank');
|
||||
|
||||
$leftOnAccount = $piggyRepository->leftOnAccount($piggyBank->account);
|
||||
$amount = round(floatval(Input::get('amount')), 2);
|
||||
$leftOnAccount = $accounts->leftOnAccount($piggyBank->account);
|
||||
$savedSoFar = $piggyBank->currentRelevantRep()->currentamount;
|
||||
$leftToSave = $piggyBank->targetamount - $savedSoFar;
|
||||
$maxAmount = round(min($leftOnAccount, $leftToSave), 2);
|
||||
@ -196,14 +194,14 @@ class PiggyBankController extends BaseController
|
||||
/*
|
||||
* Create event!
|
||||
*/
|
||||
Event::fire('piggy_bank.addMoney', [$piggyBank, $amount]); // new and used.
|
||||
//Event::fire('piggy_bank.addMoney', [$piggyBank, $amount]); // new and used.
|
||||
|
||||
Session::flash('success', 'Added ' . Amount::format($amount, false) . ' to "' . e($piggyBank->name) . '".');
|
||||
} else {
|
||||
Session::flash('error', 'Could not add ' . Amount::format($amount, false) . ' to "' . e($piggyBank->name) . '".');
|
||||
}
|
||||
|
||||
return Redirect::route('piggy_banks.index');
|
||||
return Redirect::route('piggy-banks.index');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -225,14 +223,14 @@ class PiggyBankController extends BaseController
|
||||
/*
|
||||
* Create event!
|
||||
*/
|
||||
Event::fire('piggy_bank.removeMoney', [$piggyBank, $amount]); // new and used.
|
||||
//Event::fire('piggy_bank.removeMoney', [$piggyBank, $amount]); // new and used.
|
||||
|
||||
Session::flash('success', 'Removed ' . Amount::format($amount, false) . ' from "' . e($piggyBank->name) . '".');
|
||||
} else {
|
||||
Session::flash('error', 'Could not remove ' . Amount::format($amount, false) . ' from "' . e($piggyBank->name) . '".');
|
||||
}
|
||||
|
||||
return Redirect::route('piggy_banks.index');
|
||||
return Redirect::route('piggy-banks.index');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -244,7 +242,7 @@ class PiggyBankController extends BaseController
|
||||
*/
|
||||
public function remove(PiggyBank $piggyBank)
|
||||
{
|
||||
return View::make('piggy_banks.remove', compact('piggyBank'));
|
||||
return view('piggy-banks.remove', compact('piggyBank'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -263,51 +261,30 @@ class PiggyBankController extends BaseController
|
||||
|
||||
$subTitle = e($piggyBank->name);
|
||||
|
||||
return View::make('piggy_banks.show', compact('piggyBank', 'events', 'subTitle'));
|
||||
return view('piggy-banks.show', compact('piggyBank', 'events', 'subTitle'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function store()
|
||||
public function store(PiggyBankFormRequest $request, PiggyBankRepositoryInterface $repository)
|
||||
{
|
||||
$data = Input::all();
|
||||
$data['repeats'] = 0;
|
||||
$data['user_id'] = Auth::user()->id;
|
||||
$data['rep_every'] = 0;
|
||||
$data['reminder_skip'] = 0;
|
||||
$data['remind_me'] = intval(Input::get('remind_me'));
|
||||
$data['order'] = 0;
|
||||
$piggyBankData = [
|
||||
'repeats' => false,
|
||||
'name' => $request->get('name'),
|
||||
'startdate' => new Carbon,
|
||||
'account_id' => intval($request->get('account_id')),
|
||||
'targetamount' => floatval($request->get('targetamount')),
|
||||
'targetdate' => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null,
|
||||
'reminder' => $request->get('reminder'),
|
||||
];
|
||||
|
||||
$piggyBank = $repository->store($piggyBankData);
|
||||
|
||||
// always validate:
|
||||
$messages = $this->_repository->validate($data);
|
||||
Session::flash('success', 'Stored piggy bank "' . e($piggyBank->name) . '".');
|
||||
|
||||
// flash messages:
|
||||
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 piggy bank: ' . $messages['errors']->first());
|
||||
return Redirect::route('piggy_banks.create')->withInput();
|
||||
}
|
||||
|
||||
|
||||
// return to create screen:
|
||||
if ($data['post_submit_action'] == 'validate_only') {
|
||||
return Redirect::route('piggy_banks.create')->withInput();
|
||||
}
|
||||
|
||||
// store
|
||||
$piggyBank = $this->_repository->store($data);
|
||||
Event::fire('piggy_bank.store', [$piggyBank]); // new and used.
|
||||
Session::flash('success', 'Piggy bank "' . e($data['name']) . '" stored.');
|
||||
if ($data['post_submit_action'] == 'store') {
|
||||
return Redirect::route('piggy_banks.index');
|
||||
}
|
||||
|
||||
return Redirect::route('piggy_banks.create')->withInput();
|
||||
return Redirect::route('piggy-banks.index');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -316,45 +293,27 @@ class PiggyBankController extends BaseController
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @return $this
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function update(PiggyBank $piggyBank)
|
||||
public function update(PiggyBank $piggyBank, PiggyBankRepositoryInterface $repository, PiggyBankFormRequest $request)
|
||||
{
|
||||
$piggyBankData = [
|
||||
'repeats' => false,
|
||||
'name' => $request->get('name'),
|
||||
'account_id' => intval($request->get('account_id')),
|
||||
'targetamount' => floatval($request->get('targetamount')),
|
||||
'targetdate' => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null,
|
||||
'reminder' => $request->get('reminder'),
|
||||
];
|
||||
|
||||
$data = Input::except('_token');
|
||||
$data['rep_every'] = 0;
|
||||
$data['reminder_skip'] = 0;
|
||||
$data['order'] = 0;
|
||||
$data['remind_me'] = isset($data['remind_me']) ? 1 : 0;
|
||||
$data['user_id'] = Auth::user()->id;
|
||||
$data['repeats'] = 0;
|
||||
$piggyBank = $repository->update($piggyBank, $piggyBankData);
|
||||
|
||||
$messages = $this->_repository->validate($data);
|
||||
Session::flash('success', 'Updated piggy bank "' . e($piggyBank->name) . '".');
|
||||
|
||||
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 update piggy bank: ' . $messages['errors']->first());
|
||||
return Redirect::route('piggy_banks.edit', $piggyBank->id)->withInput();
|
||||
}
|
||||
return Redirect::route('piggy-banks.index');
|
||||
|
||||
// return to update screen:
|
||||
if ($data['post_submit_action'] == 'validate_only') {
|
||||
return Redirect::route('piggy_banks.edit', $piggyBank->id)->withInput();
|
||||
}
|
||||
|
||||
// update
|
||||
$this->_repository->update($piggyBank, $data);
|
||||
Session::flash('success', 'Piggy bank "' . e($data['name']) . '" updated.');
|
||||
|
||||
// go back to list
|
||||
if ($data['post_submit_action'] == 'update') {
|
||||
return Redirect::route('piggy_banks.index');
|
||||
}
|
||||
|
||||
// go back to update screen.
|
||||
return Redirect::route('piggy_banks.edit', $piggyBank->id)->withInput(['post_submit_action' => 'return_to_edit']);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
76
app/Http/Controllers/PreferencesController.php
Normal file
76
app/Http/Controllers/PreferencesController.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use View;
|
||||
use Auth;
|
||||
use Preferences;
|
||||
use Input;
|
||||
use Session;
|
||||
use Redirect;
|
||||
/**
|
||||
* Class PreferencesController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class PreferencesController extends Controller {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
View::share('title', 'Preferences');
|
||||
View::share('mainTitleIcon', 'fa-gear');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this|\Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$accounts = Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']);
|
||||
$viewRange = Preferences::get('viewRange', '1M');
|
||||
$viewRangeValue = $viewRange->data;
|
||||
$frontPage = Preferences::get('frontPageAccounts', []);
|
||||
$budgetMax = Preferences::get('budgetMaximum', 1000);
|
||||
$budgetMaximum = $budgetMax->data;
|
||||
|
||||
return view('preferences.index', compact('budgetMaximum'))->with('accounts', $accounts)->with('frontPageAccounts', $frontPage)->with(
|
||||
'viewRange', $viewRangeValue
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postIndex()
|
||||
{
|
||||
// front page accounts
|
||||
$frontPageAccounts = [];
|
||||
foreach (Input::get('frontPageAccounts') as $id) {
|
||||
$frontPageAccounts[] = intval($id);
|
||||
}
|
||||
Preferences::set('frontPageAccounts', $frontPageAccounts);
|
||||
|
||||
// view range:
|
||||
Preferences::set('viewRange', Input::get('viewRange'));
|
||||
// forget session values:
|
||||
Session::forget('start');
|
||||
Session::forget('end');
|
||||
Session::forget('range');
|
||||
|
||||
// budget maximum:
|
||||
$budgetMaximum = intval(Input::get('budgetMaximum'));
|
||||
Preferences::set('budgetMaximum', $budgetMaximum);
|
||||
|
||||
|
||||
Session::flash('success', 'Preferences saved!');
|
||||
|
||||
return Redirect::route('preferences');
|
||||
}
|
||||
|
||||
}
|
@ -1,10 +1,18 @@
|
||||
<?php
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\ProfileFormRequest;
|
||||
use Hash;
|
||||
use Redirect;
|
||||
use Session;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
* Class ProfileController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class ProfileController extends BaseController
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
@ -12,7 +20,7 @@ class ProfileController extends BaseController
|
||||
*/
|
||||
public function changePassword()
|
||||
{
|
||||
return View::make('profile.change-password')->with('title', Auth::user()->email)->with('subTitle', 'Change your password')->with(
|
||||
return view('profile.change-password')->with('title', Auth::user()->email)->with('subTitle', 'Change your password')->with(
|
||||
'mainTitleIcon', 'fa-user'
|
||||
);
|
||||
}
|
||||
@ -23,32 +31,30 @@ class ProfileController extends BaseController
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return View::make('profile.index')->with('title', 'Profile')->with('subTitle', Auth::user()->email)->with('mainTitleIcon', 'fa-user');
|
||||
return view('profile.index')->with('title', 'Profile')->with('subTitle', Auth::user()->email)->with('mainTitleIcon', 'fa-user');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
|
||||
*/
|
||||
public function postChangePassword()
|
||||
public function postChangePassword(ProfileFormRequest $request)
|
||||
{
|
||||
|
||||
// old, new1, new2
|
||||
if (!Hash::check(Input::get('old'), Auth::user()->password)) {
|
||||
if (!Hash::check($request->get('current_password'), Auth::user()->password)) {
|
||||
Session::flash('error', 'Invalid current password!');
|
||||
|
||||
return View::make('profile.change-password');
|
||||
return Redirect::route('change-password');
|
||||
}
|
||||
$result = $this->_validatePassword(Input::get('old'), Input::get('new1'), Input::get('new2'));
|
||||
$result = $this->_validatePassword($request->get('current_password'), $request->get('new_password'), $request->get('new_password_confirmation'));
|
||||
if (!($result === true)) {
|
||||
Session::flash('error', $result);
|
||||
|
||||
return View::make('profile.change-password');
|
||||
return Redirect::route('change-password');
|
||||
}
|
||||
|
||||
// update the user with the new password.
|
||||
/** @var \FireflyIII\Database\User\User $repository */
|
||||
$repository = \App::make('FireflyIII\Database\User\User');
|
||||
$repository->updatePassword(Auth::user(), Input::get('new1'));
|
||||
Auth::user()->password = $request->get('new_password');
|
||||
Auth::user()->save();
|
||||
|
||||
Session::flash('success', 'Password changed!');
|
||||
|
||||
@ -81,5 +87,4 @@ class ProfileController extends BaseController
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,28 +1,25 @@
|
||||
<?php
|
||||
use FireflyIII\Helper\Related\RelatedInterface;
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Amount;
|
||||
use Auth;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionGroup;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
use Response;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CamelCase") // I'm fine with this.
|
||||
*
|
||||
* Class RelatedController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class RelatedController extends BaseController
|
||||
class RelatedController extends Controller
|
||||
{
|
||||
|
||||
protected $_repository;
|
||||
|
||||
/**
|
||||
* @param RelatedInterface $repository
|
||||
*/
|
||||
public function __construct(RelatedInterface $repository)
|
||||
{
|
||||
$this->_repository = $repository;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
@ -43,10 +40,16 @@ class RelatedController extends BaseController
|
||||
$unique = array_unique($ids);
|
||||
if (count($unique) > 0) {
|
||||
|
||||
$set = $this->_repository->getJournalsByIds($unique);
|
||||
$set = Auth::user()->transactionjournals()->whereIn('id', $unique)->get();
|
||||
$set->each(
|
||||
function (TransactionJournal $journal) {
|
||||
$journal->amount = Amount::format($journal->getAmount());
|
||||
/** @var Transaction $t */
|
||||
foreach ($journal->transactions()->get() as $t) {
|
||||
if ($t->amount > 0) {
|
||||
$journal->amount = $t->amount;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
@ -66,7 +69,7 @@ class RelatedController extends BaseController
|
||||
{
|
||||
$group = new TransactionGroup;
|
||||
$group->relation = 'balance';
|
||||
$group->user_id = $this->_repository->getUser()->id;
|
||||
$group->user_id = Auth::user()->id;
|
||||
$group->save();
|
||||
$group->transactionjournals()->save($parentJournal);
|
||||
$group->transactionjournals()->save($childJournal);
|
||||
@ -94,7 +97,7 @@ class RelatedController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
return View::make('related.relate', compact('journal', 'members'));
|
||||
return view('related.relate', compact('journal', 'members'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -130,15 +133,20 @@ class RelatedController extends BaseController
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function search(TransactionJournal $journal)
|
||||
public function search(TransactionJournal $journal, JournalRepositoryInterface $repository)
|
||||
{
|
||||
|
||||
$search = e(trim(Input::get('searchValue')));
|
||||
|
||||
$result = $this->_repository->search($search, $journal);
|
||||
$result = $repository->searchRelated($search, $journal);
|
||||
$result->each(
|
||||
function (TransactionJournal $j) {
|
||||
$j->amount = Amount::format($j->getAmount());
|
||||
function (TransactionJournal $journal) {
|
||||
/** @var Transaction $t */
|
||||
foreach ($journal->transactions()->get() as $t) {
|
||||
if ($t->amount > 0) {
|
||||
$journal->amount = $t->amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
199
app/Http/Controllers/RepeatedExpenseController.php
Normal file
199
app/Http/Controllers/RepeatedExpenseController.php
Normal file
@ -0,0 +1,199 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\PiggyBankFormRequest;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use View;
|
||||
|
||||
/**
|
||||
* Class RepeatedExpenseController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class RepeatedExpenseController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
View::share('title', 'Repeated expenses');
|
||||
View::share('mainTitleIcon', 'fa-rotate-left');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$periods = Config::get('firefly.piggy_bank_periods');
|
||||
$accounts = ExpandedForm::makeSelectList(Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']));
|
||||
|
||||
return view('repeatedExpense.create', compact('accounts', 'periods'))->with('subTitle', 'Create new repeated expense')->with(
|
||||
'subTitleIcon', 'fa-plus'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBank $repeatedExpense
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function delete(PiggyBank $repeatedExpense)
|
||||
{
|
||||
$subTitle = 'Delete "' . e($repeatedExpense->name) . '"';
|
||||
|
||||
return view('repeatedExpense.delete', compact('repeatedExpense', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBank $repeatedExpense
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(PiggyBank $repeatedExpense)
|
||||
{
|
||||
|
||||
Session::flash('success', 'Repeated expense "' . e($repeatedExpense->name) . '" deleted.');
|
||||
|
||||
$repeatedExpense->delete();
|
||||
|
||||
return Redirect::route('repeated.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBank $repeatedExpense
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function edit(PiggyBank $repeatedExpense)
|
||||
{
|
||||
|
||||
$periods = Config::get('firefly.piggy_bank_periods');
|
||||
$accounts = ExpandedForm::makeSelectList(Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']));
|
||||
$subTitle = 'Edit repeated expense "' . e($repeatedExpense->name) . '"';
|
||||
$subTitleIcon = 'fa-pencil';
|
||||
|
||||
/*
|
||||
* Flash some data to fill the form.
|
||||
*/
|
||||
$preFilled = ['name' => $repeatedExpense->name,
|
||||
'account_id' => $repeatedExpense->account_id,
|
||||
'targetamount' => $repeatedExpense->targetamount,
|
||||
'reminder_skip' => $repeatedExpense->reminder_skip,
|
||||
'rep_every' => $repeatedExpense->rep_every,
|
||||
'rep_times' => $repeatedExpense->rep_times,
|
||||
'targetdate' => $repeatedExpense->targetdate->format('Y-m-d'),
|
||||
'reminder' => $repeatedExpense->reminder,
|
||||
'remind_me' => intval($repeatedExpense->remind_me) == 1 || !is_null($repeatedExpense->reminder) ? true : false
|
||||
];
|
||||
Session::flash('preFilled', $preFilled);
|
||||
|
||||
return view('repeatedExpense.edit', compact('subTitle', 'subTitleIcon', 'repeatedExpense', 'accounts', 'periods', 'preFilled'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
||||
$subTitle = 'Overview';
|
||||
|
||||
$expenses = Auth::user()->piggyBanks()->where('repeats', 1)->get();
|
||||
$expenses->each(
|
||||
function (PiggyBank $piggyBank) {
|
||||
$piggyBank->currentRelevantRep();
|
||||
}
|
||||
);
|
||||
|
||||
return view('repeatedExpense.index', compact('expenses', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBank $repeatedExpense
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function show(PiggyBank $repeatedExpense, PiggyBankRepositoryInterface $repository)
|
||||
{
|
||||
$subTitle = $repeatedExpense->name;
|
||||
$today = Carbon::now();
|
||||
$repetitions = $repeatedExpense->piggyBankRepetitions()->get();
|
||||
|
||||
$repetitions->each(
|
||||
function (PiggyBankRepetition $repetition) use ($repository) {
|
||||
$repetition->bars = $repository->calculateParts($repetition);
|
||||
}
|
||||
);
|
||||
|
||||
return view('repeatedExpense.show', compact('repetitions', 'repeatedExpense', 'today', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*/
|
||||
public function store(PiggyBankFormRequest $request, PiggyBankRepositoryInterface $repository)
|
||||
{
|
||||
|
||||
$piggyBankData = [
|
||||
'repeats' => true,
|
||||
'name' => $request->get('name'),
|
||||
'startdate' => new Carbon,
|
||||
'account_id' => intval($request->get('account_id')),
|
||||
'targetamount' => floatval($request->get('targetamount')),
|
||||
'targetdate' => new Carbon($request->get('targetdate')),
|
||||
'reminder' => $request->get('reminder'),
|
||||
'skip' => intval($request->get('skip')),
|
||||
'rep_every' => intval($request->get('rep_every')),
|
||||
'rep_times' => intval($request->get('rep_times')),
|
||||
];
|
||||
|
||||
$piggyBank = $repository->store($piggyBankData);
|
||||
|
||||
Session::flash('success', 'Stored repeated expense "' . e($piggyBank->name) . '".');
|
||||
|
||||
return Redirect::route('repeated.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param PiggyBank $repeatedExpense
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function update(PiggyBank $repeatedExpense, PiggyBankFormRequest $request, PiggyBankRepositoryInterface $repository)
|
||||
{
|
||||
$piggyBankData = [
|
||||
'repeats' => false,
|
||||
'name' => $request->get('name'),
|
||||
'account_id' => intval($request->get('account_id')),
|
||||
'targetamount' => floatval($request->get('targetamount')),
|
||||
'targetdate' => strlen($request->get('targetdate')) > 0 ? new Carbon($request->get('targetdate')) : null,
|
||||
'rep_length' => $request->get('rep_length'),
|
||||
'rep_every' => intval($request->get('rep_every')),
|
||||
'rep_times' => intval($request->get('rep_times')),
|
||||
'remind_me' => intval($request->get('remind_me')) == 1 ? true : false ,
|
||||
'reminder' => $request->get('reminder'),
|
||||
];
|
||||
|
||||
|
||||
$piggyBank = $repository->update($repeatedExpense, $piggyBankData);
|
||||
|
||||
Session::flash('success', 'Updated repeated expense "' . e($piggyBank->name) . '".');
|
||||
|
||||
return Redirect::route('repeated.index');
|
||||
|
||||
}
|
||||
|
||||
}
|
284
app/Http/Controllers/ReportController.php
Normal file
284
app/Http/Controllers/ReportController.php
Normal file
@ -0,0 +1,284 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use FireflyIII\Helpers\Report\ReportHelperInterface;
|
||||
use FireflyIII\Helpers\Report\ReportQueryInterface;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Models\Account;
|
||||
use Illuminate\Database\Query\JoinClause;
|
||||
use Steam;
|
||||
use View;
|
||||
|
||||
/**
|
||||
* Class ReportController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class ReportController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
View::share('title', 'Reports');
|
||||
View::share('mainTitleIcon', 'fa-line-chart');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $year
|
||||
* @param string $month
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function budget($year = '2014', $month = '1', ReportQueryInterface $query)
|
||||
{
|
||||
try {
|
||||
new Carbon($year . '-' . $month . '-01');
|
||||
} catch (Exception $e) {
|
||||
return view('error')->with('message', 'Invalid date');
|
||||
}
|
||||
$date = new Carbon($year . '-' . $month . '-01');
|
||||
$start = clone $date;
|
||||
$start->startOfMonth();
|
||||
$end = clone $date;
|
||||
$end->endOfMonth();
|
||||
$start->subDay();
|
||||
|
||||
$dayEarly = clone $date;
|
||||
$subTitle = 'Budget report for ' . $date->format('F Y');
|
||||
$subTitleIcon = 'fa-calendar';
|
||||
$dayEarly = $dayEarly->subDay();
|
||||
$accounts = $query->getAllAccounts($start, $end);
|
||||
$start->addDay();
|
||||
|
||||
$accounts->each(
|
||||
function (Account $account) use ($start, $end, $query) {
|
||||
$budgets = $query->getBudgetSummary($account, $start, $end);
|
||||
$balancedAmount = $query->balancedTransactionsList($account, $start, $end);
|
||||
$array = [];
|
||||
foreach ($budgets as $budget) {
|
||||
$id = intval($budget->id);
|
||||
$data = $budget->toArray();
|
||||
$array[$id] = $data;
|
||||
}
|
||||
|
||||
$account->budgetInformation = $array;
|
||||
$account->balancedAmount = $balancedAmount;
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
$start = clone $date;
|
||||
$start->startOfMonth();
|
||||
|
||||
/**
|
||||
* Start getBudgetsForMonth DONE
|
||||
*/
|
||||
$set = Auth::user()->budgets()->orderBy('budgets.name', 'ASC')
|
||||
->leftJoin(
|
||||
'budget_limits', function (JoinClause $join) use ($date) {
|
||||
$join->on('budget_limits.budget_id', '=', 'budgets.id')->where('budget_limits.startdate', '=', $date->format('Y-m-d'));
|
||||
}
|
||||
)
|
||||
->get(['budgets.*', 'budget_limits.amount as amount']);
|
||||
$budgets = Steam::makeArray($set);
|
||||
$amountSet = $query->journalsByBudget($start, $end);
|
||||
$amounts = Steam::makeArray($amountSet);
|
||||
$budgets = Steam::mergeArrays($budgets, $amounts);
|
||||
$budgets[0]['spent'] = isset($budgets[0]['spent']) ? $budgets[0]['spent'] : 0.0;
|
||||
$budgets[0]['amount'] = isset($budgets[0]['amount']) ? $budgets[0]['amount'] : 0.0;
|
||||
$budgets[0]['name'] = 'No budget';
|
||||
|
||||
// find transactions to shared expense accounts, which are without a budget by default:
|
||||
$transfers = $query->sharedExpenses($start, $end);
|
||||
foreach ($transfers as $transfer) {
|
||||
$budgets[0]['spent'] += floatval($transfer->amount) * -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* End getBudgetsForMonth DONE
|
||||
*/
|
||||
|
||||
return view('reports.budget', compact('subTitle', 'subTitleIcon', 'date', 'accounts', 'budgets', 'dayEarly'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ReportHelperInterface $helper
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function index(ReportHelperInterface $helper)
|
||||
{
|
||||
$start = $helper->firstDate();
|
||||
$months = $helper->listOfMonths($start);
|
||||
$years = $helper->listOfYears($start);
|
||||
$title = 'Reports';
|
||||
$mainTitleIcon = 'fa-line-chart';
|
||||
|
||||
return view('reports.index', compact('years', 'months', 'title', 'mainTitleIcon'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $year
|
||||
* @param string $month
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function month($year = '2014', $month = '1', ReportQueryInterface $query)
|
||||
{
|
||||
try {
|
||||
new Carbon($year . '-' . $month . '-01');
|
||||
} catch (Exception $e) {
|
||||
return view('error')->with('message', 'Invalid date.');
|
||||
}
|
||||
$date = new Carbon($year . '-' . $month . '-01');
|
||||
$subTitle = 'Report for ' . $date->format('F Y');
|
||||
$subTitleIcon = 'fa-calendar';
|
||||
$displaySum = true; // to show sums in report.
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* get income for month (date)
|
||||
*
|
||||
*/
|
||||
|
||||
$start = clone $date;
|
||||
$start->startOfMonth();
|
||||
$end = clone $date;
|
||||
$end->endOfMonth();
|
||||
|
||||
/**
|
||||
* Start getIncomeForMonth DONE
|
||||
*/
|
||||
$income = $query->incomeByPeriod($start, $end);
|
||||
/**
|
||||
* End getIncomeForMonth DONE
|
||||
*/
|
||||
/**
|
||||
* Start getExpenseGroupedForMonth DONE
|
||||
*/
|
||||
$set = $query->journalsByExpenseAccount($start, $end);
|
||||
$expenses = Steam::makeArray($set);
|
||||
$expenses = Steam::sortArray($expenses);
|
||||
$expenses = Steam::limitArray($expenses, 10);
|
||||
/**
|
||||
* End getExpenseGroupedForMonth DONE
|
||||
*/
|
||||
/**
|
||||
* Start getBudgetsForMonth DONE
|
||||
*/
|
||||
$set = Auth::user()->budgets()
|
||||
->leftJoin(
|
||||
'budget_limits', function (JoinClause $join) use ($date) {
|
||||
$join->on('budget_limits.budget_id', '=', 'budgets.id')->where('budget_limits.startdate', '=', $date->format('Y-m-d'));
|
||||
}
|
||||
)
|
||||
->get(['budgets.*', 'budget_limits.amount as amount']);
|
||||
$budgets = Steam::makeArray($set);
|
||||
$amountSet = $query->journalsByBudget($start, $end);
|
||||
$amounts = Steam::makeArray($amountSet);
|
||||
$budgets = Steam::mergeArrays($budgets, $amounts);
|
||||
$budgets[0]['spent'] = isset($budgets[0]['spent']) ? $budgets[0]['spent'] : 0.0;
|
||||
$budgets[0]['amount'] = isset($budgets[0]['amount']) ? $budgets[0]['amount'] : 0.0;
|
||||
$budgets[0]['name'] = 'No budget';
|
||||
|
||||
// find transactions to shared expense accounts, which are without a budget by default:
|
||||
$transfers = $query->sharedExpenses($start, $end);
|
||||
foreach ($transfers as $transfer) {
|
||||
$budgets[0]['spent'] += floatval($transfer->amount) * -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* End getBudgetsForMonth DONE
|
||||
*/
|
||||
/**
|
||||
* Start getCategoriesForMonth DONE
|
||||
*/
|
||||
// all categories.
|
||||
$result = $query->journalsByCategory($start, $end);
|
||||
$categories = Steam::makeArray($result);
|
||||
|
||||
// all transfers
|
||||
$result = $query->sharedExpensesByCategory($start, $end);
|
||||
$transfers = Steam::makeArray($result);
|
||||
$merged = Steam::mergeArrays($categories, $transfers);
|
||||
|
||||
// sort.
|
||||
$sorted = Steam::sortNegativeArray($merged);
|
||||
|
||||
// limit to $limit:
|
||||
$categories = Steam::limitArray($sorted, 10);
|
||||
/**
|
||||
* End getCategoriesForMonth DONE
|
||||
*/
|
||||
/**
|
||||
* Start getAccountsForMonth
|
||||
*/
|
||||
$list = $query->accountList();
|
||||
$accounts = [];
|
||||
/** @var Account $account */
|
||||
foreach ($list as $account) {
|
||||
$id = intval($account->id);
|
||||
/** @noinspection PhpParamsInspection */
|
||||
$accounts[$id] = [
|
||||
'name' => $account->name,
|
||||
'startBalance' => Steam::balance($account, $start),
|
||||
'endBalance' => Steam::balance($account, $end)
|
||||
];
|
||||
|
||||
$accounts[$id]['difference'] = $accounts[$id]['endBalance'] - $accounts[$id]['startBalance'];
|
||||
}
|
||||
|
||||
/**
|
||||
* End getAccountsForMonth
|
||||
*/
|
||||
|
||||
|
||||
return view(
|
||||
'reports.month',
|
||||
compact(
|
||||
'income', 'expenses', 'budgets', 'accounts', 'categories',
|
||||
'date', 'subTitle', 'displaySum', 'subTitleIcon'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $year
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function year($year, ReportHelperInterface $helper, ReportQueryInterface $query)
|
||||
{
|
||||
try {
|
||||
new Carbon('01-01-' . $year);
|
||||
} catch (Exception $e) {
|
||||
return view('error')->with('message', 'Invalid date.');
|
||||
}
|
||||
$date = new Carbon('01-01-' . $year);
|
||||
$end = clone $date;
|
||||
$end->endOfYear();
|
||||
$title = 'Reports';
|
||||
$subTitle = $year;
|
||||
$subTitleIcon = 'fa-bar-chart';
|
||||
$mainTitleIcon = 'fa-line-chart';
|
||||
$balances = $helper->yearBalanceReport($date);
|
||||
$groupedIncomes = $query->journalsByRevenueAccount($date, $end);
|
||||
$groupedExpenses = $query->journalsByExpenseAccount($date, $end);
|
||||
|
||||
//$groupedExpenses = $helper-> expensesGroupedByAccount($date, $end, 15);
|
||||
|
||||
return view(
|
||||
'reports.year', compact('date', 'groupedIncomes', 'groupedExpenses', 'year', 'balances', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,19 +1,24 @@
|
||||
<?php
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
|
||||
use FireflyIII\Support\Search\SearchInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
* Class SearchController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class SearchController extends BaseController
|
||||
{
|
||||
class SearchController extends Controller {
|
||||
/**
|
||||
* Results always come in the form of an array [results, count, fullCount]
|
||||
*/
|
||||
public function index()
|
||||
public function index(SearchInterface $searcher)
|
||||
{
|
||||
|
||||
/** @var \FireflyIII\Search\Search $searcher */
|
||||
$searcher = App::make('FireflyIII\Search\Search');
|
||||
|
||||
$subTitle = null;
|
||||
$rawQuery = null;
|
||||
$result = [];
|
||||
@ -31,8 +36,9 @@ class SearchController extends BaseController
|
||||
|
||||
}
|
||||
|
||||
return View::make('search.index')->with('title', 'Search')->with('subTitle', $subTitle)->with(
|
||||
return view('search.index')->with('title', 'Search')->with('subTitle', $subTitle)->with(
|
||||
'mainTitleIcon', 'fa-search'
|
||||
)->with('query', $rawQuery)->with('result', $result);
|
||||
}
|
||||
|
||||
}
|
307
app/Http/Controllers/TransactionController.php
Normal file
307
app/Http/Controllers/TransactionController.php
Normal file
@ -0,0 +1,307 @@
|
||||
<?php namespace FireflyIII\Http\Controllers;
|
||||
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use ExpandedForm;
|
||||
use FireflyIII\Http\Requests;
|
||||
use FireflyIII\Http\Requests\JournalFormRequest;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Input;
|
||||
use Redirect;
|
||||
use Session;
|
||||
use View;
|
||||
|
||||
|
||||
/**
|
||||
* Class TransactionController
|
||||
*
|
||||
* @package FireflyIII\Http\Controllers
|
||||
*/
|
||||
class TransactionController extends Controller
|
||||
{
|
||||
/**
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
View::share('title', 'Transactions');
|
||||
View::share('mainTitleIcon', 'fa-repeat');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the view helping the user to create a new transaction journal.
|
||||
*
|
||||
* @param string $what
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create($what = 'deposit')
|
||||
{
|
||||
$accounts = ExpandedForm::makeSelectList(
|
||||
Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->where('active', 1)->orderBy('name', 'DESC')->get(['accounts.*'])
|
||||
);
|
||||
$budgets = ExpandedForm::makeSelectList(Auth::user()->budgets()->get());
|
||||
$budgets[0] = '(no budget)';
|
||||
$piggies = ExpandedForm::makeSelectList(Auth::user()->piggyBanks()->get());
|
||||
$piggies[0] = '(no piggy bank)';
|
||||
$preFilled = Session::has('preFilled') ? Session::get('preFilled') : [];
|
||||
$respondTo = ['account_id', 'account_from_id'];
|
||||
$subTitle = 'Add a new ' . e($what);
|
||||
|
||||
foreach ($respondTo as $r) {
|
||||
if (!is_null(Input::get($r))) {
|
||||
$preFilled[$r] = Input::get($r);
|
||||
}
|
||||
}
|
||||
Session::put('preFilled', $preFilled);
|
||||
|
||||
asort($piggies);
|
||||
|
||||
|
||||
return view('transactions.create', compact('accounts', 'budgets', 'what', 'piggies', 'subTitle'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the form that allows a user to delete a transaction journal.
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function delete(TransactionJournal $journal)
|
||||
{
|
||||
$type = strtolower($journal->transactionType->type);
|
||||
$subTitle = 'Delete ' . e($type) . ' "' . e($journal->description) . '"';
|
||||
|
||||
return View::make('transactions.delete', compact('journal', 'subTitle'));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $transactionJournal
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(TransactionJournal $transactionJournal)
|
||||
{
|
||||
$type = $transactionJournal->transactionType->type;
|
||||
$return = 'withdrawal';
|
||||
|
||||
Session::flash('success', 'Transaction "' . e($transactionJournal->description) . '" destroyed.');
|
||||
|
||||
$transactionJournal->delete();
|
||||
|
||||
switch ($type) {
|
||||
case 'Deposit':
|
||||
$return = 'deposit';
|
||||
break;
|
||||
case 'Transfer':
|
||||
$return = 'transfers';
|
||||
break;
|
||||
}
|
||||
|
||||
return Redirect::route('transactions.index', $return);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the view to edit a transaction.
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function edit(TransactionJournal $journal, JournalRepositoryInterface $repository)
|
||||
{
|
||||
$what = strtolower($journal->transactiontype->type);
|
||||
$accounts = ExpandedForm::makeSelectList(
|
||||
Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->where('active', 1)->orderBy('name', 'DESC')->get(['accounts.*'])
|
||||
);
|
||||
$budgets = ExpandedForm::makeSelectList(Auth::user()->budgets()->get());
|
||||
$budgets[0] = '(no budget)';
|
||||
$transactions = $journal->transactions()->orderBy('amount', 'DESC')->get();
|
||||
$piggies = ExpandedForm::makeSelectList(Auth::user()->piggyBanks()->get());
|
||||
$piggies[0] = '(no piggy bank)';
|
||||
$preFilled = [
|
||||
'date' => $journal->date->format('Y-m-d'),
|
||||
'category' => '',
|
||||
'budget_id' => 0,
|
||||
'piggy_bank_id' => 0
|
||||
];
|
||||
|
||||
$category = $journal->categories()->first();
|
||||
if (!is_null($category)) {
|
||||
$preFilled['category'] = $category->name;
|
||||
}
|
||||
|
||||
$budget = $journal->budgets()->first();
|
||||
if (!is_null($budget)) {
|
||||
$preFilled['budget_id'] = $budget->id;
|
||||
}
|
||||
|
||||
if ($journal->piggyBankEvents()->count() > 0) {
|
||||
$preFilled['piggy_bank_id'] = $journal->piggyBankEvents()->first()->piggy_bank_id;
|
||||
}
|
||||
|
||||
$preFilled['amount'] = 0;
|
||||
/** @var Transaction $t */
|
||||
foreach ($transactions as $t) {
|
||||
if (floatval($t->amount) > 0) {
|
||||
$preFilled['amount'] = floatval($t->amount);
|
||||
}
|
||||
}
|
||||
$preFilled['account_id'] = $repository->getAssetAccount($journal);
|
||||
$preFilled['expense_account'] = $transactions[0]->account->name;
|
||||
$preFilled['revenue_account'] = $transactions[1]->account->name;
|
||||
$preFilled['account_from_id'] = $transactions[1]->account->id;
|
||||
$preFilled['account_to_id'] = $transactions[0]->account->id;
|
||||
|
||||
|
||||
return View::make('transactions.edit', compact('journal', 'accounts', 'what', 'budgets', 'piggies', 'subTitle'))->with('data', $preFilled);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $what
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function index($what)
|
||||
{
|
||||
switch ($what) {
|
||||
case 'expenses':
|
||||
case 'withdrawal':
|
||||
$subTitleIcon = 'fa-long-arrow-left';
|
||||
$subTitle = 'Expenses';
|
||||
//$journals = $this->_repository->getWithdrawalsPaginated(50);
|
||||
$types = ['Withdrawal'];
|
||||
break;
|
||||
case 'revenue':
|
||||
case 'deposit':
|
||||
$subTitleIcon = 'fa-long-arrow-right';
|
||||
$subTitle = 'Revenue, income and deposits';
|
||||
// $journals = $this->_repository->getDepositsPaginated(50);
|
||||
$types = ['Deposit'];
|
||||
break;
|
||||
case 'transfer':
|
||||
case 'transfers':
|
||||
$subTitleIcon = 'fa-arrows-h';
|
||||
$subTitle = 'Transfers';
|
||||
//$journals = $this->_repository->getTransfersPaginated(50);
|
||||
$types = ['Transfer'];
|
||||
break;
|
||||
}
|
||||
|
||||
$page = intval(\Input::get('page'));
|
||||
$offset = $page > 0 ? ($page - 1) * 50 : 0;
|
||||
|
||||
$set = Auth::user()->transactionJournals()->transactionTypes($types)->withRelevantData()->take(50)->offset($offset)->orderBy('date', 'DESC')->get(
|
||||
['transaction_journals.*']
|
||||
);
|
||||
$count = Auth::user()->transactionJournals()->transactionTypes($types)->count();
|
||||
$journals = new LengthAwarePaginator($set, $count, 50, $page);
|
||||
$journals->setPath('transactions/' . $what);
|
||||
|
||||
return view('transactions.index', compact('subTitle', 'what', 'subTitleIcon', 'journals'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function show(TransactionJournal $journal)
|
||||
{
|
||||
$journal->transactions->each(
|
||||
function (Transaction $t) use ($journal) {
|
||||
$t->before = floatval(
|
||||
$t->account->transactions()->leftJoin(
|
||||
'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id'
|
||||
)->where('transaction_journals.date', '<=', $journal->date->format('Y-m-d'))->where(
|
||||
'transaction_journals.created_at', '<=', $journal->created_at->format('Y-m-d H:i:s')
|
||||
)->where('transaction_journals.id', '!=', $journal->id)->sum('transactions.amount')
|
||||
);
|
||||
$t->after = $t->before + $t->amount;
|
||||
}
|
||||
);
|
||||
$members = new Collection;
|
||||
/** @var TransactionGroup $group */
|
||||
foreach ($journal->transactiongroups()->get() as $group) {
|
||||
/** @var TransactionJournal $loopJournal */
|
||||
foreach ($group->transactionjournals()->get() as $loopJournal) {
|
||||
if ($loopJournal->id != $journal->id) {
|
||||
$members->push($loopJournal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return view('transactions.show', compact('journal', 'members'))->with(
|
||||
'subTitle', e($journal->transactiontype->type) . ' "' . e($journal->description) . '"'
|
||||
);
|
||||
}
|
||||
|
||||
public function store(JournalFormRequest $request, JournalRepositoryInterface $repository)
|
||||
{
|
||||
|
||||
$journalData = [
|
||||
'what' => $request->get('what'),
|
||||
'description' => $request->get('description'),
|
||||
'account_id' => intval($request->get('account_id')),
|
||||
'account_from_id' => intval($request->get('account_from_id')),
|
||||
'account_to_id' => intval($request->get('account_to_id')),
|
||||
'expense_account' => $request->get('expense_account'),
|
||||
'revenue_account' => $request->get('revenue_account'),
|
||||
'amount' => floatval($request->get('amount')),
|
||||
'user' => Auth::user()->id,
|
||||
'amount_currency_id' => intval($request->get('amount_currency_id')),
|
||||
'date' => new Carbon($request->get('date')),
|
||||
'budget_id' => intval($request->get('budget_id')),
|
||||
'category' => $request->get('category'),
|
||||
];
|
||||
|
||||
$journal = $repository->store($journalData);
|
||||
|
||||
Session::flash('success', 'New transaction "' . $journal->description . '" stored!');
|
||||
|
||||
return Redirect::route('transactions.index', $request->input('what'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @return $this
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function update(TransactionJournal $journal, JournalFormRequest $request, JournalRepositoryInterface $repository)
|
||||
{
|
||||
|
||||
$journalData = [
|
||||
'what' => $request->get('what'),
|
||||
'description' => $request->get('description'),
|
||||
'account_id' => intval($request->get('account_id')),
|
||||
'account_from_id' => intval($request->get('account_from_id')),
|
||||
'account_to_id' => intval($request->get('account_to_id')),
|
||||
'expense_account' => $request->get('expense_account'),
|
||||
'revenue_account' => $request->get('revenue_account'),
|
||||
'amount' => floatval($request->get('amount')),
|
||||
'user' => Auth::user()->id,
|
||||
'amount_currency_id' => intval($request->get('amount_currency_id')),
|
||||
'date' => new Carbon($request->get('date')),
|
||||
'budget_id' => intval($request->get('budget_id')),
|
||||
'category' => $request->get('category'),
|
||||
];
|
||||
|
||||
$repository->update($journal, $journalData);
|
||||
Session::flash('success', 'Transaction "' . e($journalData['description']) . '" updated.');
|
||||
|
||||
return Redirect::route('transactions.index', $journalData['what']);
|
||||
|
||||
}
|
||||
|
||||
}
|
41
app/Http/Kernel.php
Normal file
41
app/Http/Kernel.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php namespace FireflyIII\Http;
|
||||
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
/**
|
||||
* Class Kernel
|
||||
*
|
||||
* @package FireflyIII\Http
|
||||
*/
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middleware
|
||||
= [
|
||||
'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
|
||||
'Illuminate\Cookie\Middleware\EncryptCookies',
|
||||
'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
|
||||
'Illuminate\Session\Middleware\StartSession',
|
||||
'Illuminate\View\Middleware\ShareErrorsFromSession',
|
||||
'FireflyIII\Http\Middleware\VerifyCsrfToken',
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $routeMiddleware
|
||||
= [
|
||||
'auth' => 'FireflyIII\Http\Middleware\Authenticate',
|
||||
'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
|
||||
'guest' => 'FireflyIII\Http\Middleware\RedirectIfAuthenticated',
|
||||
'range' => 'FireflyIII\Http\Middleware\Range',
|
||||
];
|
||||
|
||||
}
|
53
app/Http/Middleware/Authenticate.php
Normal file
53
app/Http/Middleware/Authenticate.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
|
||||
/**
|
||||
* Class Authenticate
|
||||
*
|
||||
* @package FireflyIII\Http\Middleware
|
||||
*/
|
||||
class Authenticate
|
||||
{
|
||||
|
||||
/**
|
||||
* The Guard implementation.
|
||||
*
|
||||
* @var Guard
|
||||
*/
|
||||
protected $auth;
|
||||
|
||||
/**
|
||||
* Create a new filter instance.
|
||||
*
|
||||
* @param Guard $auth
|
||||
*
|
||||
*/
|
||||
public function __construct(Guard $auth)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if ($this->auth->guest()) {
|
||||
if ($request->ajax()) {
|
||||
return response('Unauthorized.', 401);
|
||||
} else {
|
||||
return redirect()->guest('auth/login');
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
}
|
75
app/Http/Middleware/Range.php
Normal file
75
app/Http/Middleware/Range.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Navigation;
|
||||
use Preferences;
|
||||
use Session;
|
||||
|
||||
/**
|
||||
* Class SessionFilter
|
||||
*
|
||||
* @package FireflyIII\Http\Middleware
|
||||
*/
|
||||
class Range
|
||||
{
|
||||
/**
|
||||
* The Guard implementation.
|
||||
*
|
||||
* @var Guard
|
||||
*/
|
||||
protected $auth;
|
||||
|
||||
/**
|
||||
* Create a new filter instance.
|
||||
*
|
||||
* @param Guard $auth
|
||||
*
|
||||
*/
|
||||
public function __construct(Guard $auth)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $theNext
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $theNext)
|
||||
{
|
||||
if ($this->auth->check()) {
|
||||
// user's view range comes from preferences, gets set in session:
|
||||
/** @var \FireflyIII\Models\Preference $viewRange */
|
||||
$viewRange = Preferences::get('viewRange', '1M');
|
||||
|
||||
|
||||
// the start and end date are checked and stored:
|
||||
$start = Session::has('start') ? Session::get('start') : new Carbon;
|
||||
$start = Navigation::updateStartDate($viewRange->data, $start);
|
||||
$end = Navigation::updateEndDate($viewRange->data, $start);
|
||||
$period = Navigation::periodName($viewRange->data, $start);
|
||||
$prev = Navigation::jumpToPrevious($viewRange->data, clone $start);
|
||||
$next = Navigation::jumpToNext($viewRange->data, clone $start);
|
||||
|
||||
Session::put('range', $viewRange->data);
|
||||
Session::put('start', $start);
|
||||
Session::put('end', $end);
|
||||
Session::put('period', $period);
|
||||
Session::put('prev', Navigation::periodName($viewRange->data, $prev));
|
||||
Session::put('next', Navigation::periodName($viewRange->data, $next));
|
||||
|
||||
}
|
||||
|
||||
return $theNext($request);
|
||||
|
||||
}
|
||||
|
||||
}
|
50
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
50
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
|
||||
/**
|
||||
* Class RedirectIfAuthenticated
|
||||
*
|
||||
* @package FireflyIII\Http\Middleware
|
||||
*/
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
|
||||
/**
|
||||
* The Guard implementation.
|
||||
*
|
||||
* @var Guard
|
||||
*/
|
||||
protected $auth;
|
||||
|
||||
/**
|
||||
* Create a new filter instance.
|
||||
*
|
||||
* @param Guard $auth
|
||||
*
|
||||
*/
|
||||
public function __construct(Guard $auth)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if ($this->auth->check()) {
|
||||
return new RedirectResponse(url('/'));
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
}
|
27
app/Http/Middleware/VerifyCsrfToken.php
Normal file
27
app/Http/Middleware/VerifyCsrfToken.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php namespace FireflyIII\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
|
||||
|
||||
/**
|
||||
* Class VerifyCsrfToken
|
||||
*
|
||||
* @package FireflyIII\Http\Middleware
|
||||
*/
|
||||
class VerifyCsrfToken extends BaseVerifier
|
||||
{
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
return parent::handle($request, $next);
|
||||
}
|
||||
|
||||
}
|
49
app/Http/Requests/AccountFormRequest.php
Normal file
49
app/Http/Requests/AccountFormRequest.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use Config;
|
||||
use FireflyIII\Models\Account;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
* Class AccountFormRequest
|
||||
*
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
class AccountFormRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
// Only allow logged in users
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$accountRoles = join(',', array_keys(Config::get('firefly.accountRoles')));
|
||||
$types = join(',', array_keys(Config::get('firefly.subTitlesByIdentifier')));
|
||||
|
||||
$nameRule = 'required|between:1,100|uniqueForUser:accounts,name';
|
||||
if (Account::find(Input::get('id'))) {
|
||||
$nameRule = 'required|between:1,100';
|
||||
}
|
||||
|
||||
return [
|
||||
'name' => $nameRule,
|
||||
'openingBalance' => 'numeric',
|
||||
'openingBalanceDate' => 'date',
|
||||
'accountRole' => 'in:' . $accountRoles,
|
||||
'active' => 'boolean',
|
||||
'balance_currency_id' => 'exists:transaction_currencies,id',
|
||||
'what' => 'in:' . $types
|
||||
];
|
||||
}
|
||||
}
|
55
app/Http/Requests/BillFormRequest.php
Normal file
55
app/Http/Requests/BillFormRequest.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: sander
|
||||
* Date: 25/02/15
|
||||
* Time: 12:29
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
* Class BillFormRequest
|
||||
*
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
class BillFormRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
// Only allow logged in users
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$nameRule = 'required|between:1,255|uniqueForUser:bills,name';
|
||||
if(intval(Input::get('id')) > 0) {
|
||||
$nameRule .= ','.intval(Input::get('id'));
|
||||
}
|
||||
|
||||
$rules = [
|
||||
'name' => $nameRule,
|
||||
'match' => 'required|between:1,255',
|
||||
'amount_min' => 'required|numeric|min:0.01',
|
||||
'amount_max' => 'required|numeric|min:0.01',
|
||||
'amount_currency_id' => 'required|exists:transaction_currencies,id',
|
||||
'date' => 'required|date',
|
||||
'repeat_freq' => 'required|in:weekly,monthly,quarterly,half-year,yearly',
|
||||
'skip' => 'required|between:0,31',
|
||||
'automatch' => 'in:1',
|
||||
'active' => 'in:1',
|
||||
];
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
40
app/Http/Requests/BudgetFormRequest.php
Normal file
40
app/Http/Requests/BudgetFormRequest.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Budget;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
* Class BudgetFormRequest
|
||||
*
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
class BudgetFormRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
// Only allow logged in users
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
|
||||
$nameRule = 'required|between:1,100|uniqueForUser:budgets,name';
|
||||
if (Budget::find(Input::get('id'))) {
|
||||
$nameRule = 'required|between:1,100';
|
||||
}
|
||||
|
||||
return [
|
||||
'name' => $nameRule,
|
||||
];
|
||||
}
|
||||
}
|
40
app/Http/Requests/CategoryFormRequest.php
Normal file
40
app/Http/Requests/CategoryFormRequest.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Category;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
* Class CategoryFormRequest
|
||||
*
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
class CategoryFormRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
// Only allow logged in users
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
|
||||
$nameRule = 'required|between:1,100|uniqueForUser:categories,name';
|
||||
if (Category::find(Input::get('id'))) {
|
||||
$nameRule = 'required|between:1,100';
|
||||
}
|
||||
|
||||
return [
|
||||
'name' => $nameRule,
|
||||
];
|
||||
}
|
||||
}
|
51
app/Http/Requests/CurrencyFormRequest.php
Normal file
51
app/Http/Requests/CurrencyFormRequest.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: sander
|
||||
* Date: 25/02/15
|
||||
* Time: 12:29
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
* Class BillFormRequest
|
||||
*
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
class CurrencyFormRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
// Only allow logged in users
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
|
||||
$rules = [
|
||||
'code' => 'required|min:3|max:3|unique:transaction_currencies,code',
|
||||
'name' => 'required|max:48|min:1|unique:transaction_currencies,name',
|
||||
'symbol' => 'required|min:1|max:8|unique:transaction_currencies,symbol',
|
||||
];
|
||||
if (intval(Input::get('id')) > 0) {
|
||||
$rules = [
|
||||
'code' => 'required|min:3|max:3',
|
||||
'name' => 'required|max:48|min:1',
|
||||
'symbol' => 'required|min:1|max:8',
|
||||
];
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
72
app/Http/Requests/JournalFormRequest.php
Normal file
72
app/Http/Requests/JournalFormRequest.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
* Class JournalFormRequest
|
||||
*
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
class JournalFormRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
// Only allow logged in users
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
// can we switch on the "what"?
|
||||
$what = Input::get('what');
|
||||
|
||||
$rules = [
|
||||
'description' => 'required|min:1,max:255',
|
||||
'what' => 'required|in:withdrawal,deposit,transfer|exists:transaction_types,type',
|
||||
'amount' => 'numeric|required|min:0.01',
|
||||
'date' => 'required|date',
|
||||
'amount_currency_id' => 'required|exists:transaction_currencies,id',
|
||||
|
||||
];
|
||||
|
||||
switch ($what) {
|
||||
case 'withdrawal':
|
||||
$rules['account_id'] = 'required|exists:accounts,id|belongsToUser:accounts';
|
||||
$rules['expense_account'] = 'between:1,255';
|
||||
$rules['category'] = 'between:1,255';
|
||||
if (intval(Input::get('budget_id')) != 0) {
|
||||
$rules['budget_id'] = 'exists:budgets,id|belongsToUser:budgets';
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case 'deposit':
|
||||
$rules['category'] = 'between:1,255';
|
||||
$rules['account_id'] = 'required|exists:accounts,id|belongsToUser:accounts';
|
||||
$rules['revenue_account'] = 'between:1,255';
|
||||
break;
|
||||
case 'transfer':
|
||||
$rules['account_from_id'] = 'required|exists:accounts,id|belongsToUser:accounts|different:account_to_id';
|
||||
$rules['account_to_id'] = 'required|exists:accounts,id|belongsToUser:accounts|different:account_from_id';
|
||||
$rules['category'] = 'between:1,255';
|
||||
break;
|
||||
default:
|
||||
die('Cannot handle ' . $what);
|
||||
break;
|
||||
}
|
||||
|
||||
return $rules;
|
||||
|
||||
|
||||
}
|
||||
}
|
61
app/Http/Requests/PiggyBankFormRequest.php
Normal file
61
app/Http/Requests/PiggyBankFormRequest.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
use Input;
|
||||
|
||||
/**
|
||||
* Class PiggyBankFormRequest
|
||||
*
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
class PiggyBankFormRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
// Only allow logged in users
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
|
||||
$nameRule = 'required|between:1,255|uniqueForUser:piggy_banks,name';
|
||||
$targetDateRule = 'date';
|
||||
if (intval(Input::get('id'))) {
|
||||
$nameRule = 'required|between:1,255';
|
||||
}
|
||||
|
||||
if (intval(Input::get('repeats')) == 1) {
|
||||
$targetDateRule = 'required|date|after:' . date('Y-m-d');
|
||||
}
|
||||
|
||||
$rules = [
|
||||
'repeats' => 'required|boolean',
|
||||
'name' => $nameRule,
|
||||
'account_id' => 'required|belongsToUser:accounts',
|
||||
'targetamount' => 'required|min:0.01',
|
||||
'amount_currency_id' => 'exists:transaction_currencies,id',
|
||||
'startdate' => 'date',
|
||||
'targetdate' => $targetDateRule,
|
||||
'rep_length' => 'in:day,week,quarter,month,year',
|
||||
'rep_every' => 'integer|min:0|max:31',
|
||||
'rep_times' => 'integer|min:0|max:99',
|
||||
'reminder' => 'in:day,week,quarter,month,year',
|
||||
'reminder_skip' => 'integer|min:0|max:99',
|
||||
'remind_me' => 'boolean',
|
||||
'order' => 'integer|min:1',
|
||||
|
||||
];
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
35
app/Http/Requests/ProfileFormRequest.php
Normal file
35
app/Http/Requests/ProfileFormRequest.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
|
||||
/**
|
||||
* Class ProfileFormRequest
|
||||
*
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
class ProfileFormRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
// Only allow logged in users
|
||||
return Auth::check();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'current_password' => 'required',
|
||||
'new_password' => 'required|confirmed',
|
||||
'new_password_confirmation' => 'required',
|
||||
];
|
||||
}
|
||||
}
|
15
app/Http/Requests/Request.php
Normal file
15
app/Http/Requests/Request.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php namespace FireflyIII\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
/**
|
||||
* Class Request
|
||||
*
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
abstract class Request extends FormRequest
|
||||
{
|
||||
|
||||
//
|
||||
|
||||
}
|
@ -1,7 +1,14 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
use DaveJamesMiller\Breadcrumbs\Generator;
|
||||
use FireflyIII\Exception\FireflyException;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
|
||||
/*
|
||||
* Back home.
|
||||
@ -22,7 +29,7 @@ Breadcrumbs::register(
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'accounts.show', function (Generator $breadcrumbs, \Account $account) {
|
||||
'accounts.show', function (Generator $breadcrumbs, Account $account) {
|
||||
switch ($account->accountType->type) {
|
||||
default:
|
||||
throw new FireflyException('Cannot handle account type "' . e($account->accountType->type) . '"');
|
||||
@ -47,14 +54,14 @@ Breadcrumbs::register(
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'accounts.delete', function (Generator $breadcrumbs, \Account $account) {
|
||||
'accounts.delete', function (Generator $breadcrumbs, Account $account) {
|
||||
$breadcrumbs->parent('accounts.show', $account);
|
||||
$breadcrumbs->push('Delete ' . e($account->name), route('accounts.delete', $account->id));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'accounts.edit', function (Generator $breadcrumbs, \Account $account) {
|
||||
'accounts.edit', function (Generator $breadcrumbs, Account $account) {
|
||||
$breadcrumbs->parent('accounts.show', $account);
|
||||
$breadcrumbs->push('Edit ' . e($account->name), route('accounts.edit', $account->id));
|
||||
}
|
||||
@ -91,9 +98,9 @@ Breadcrumbs::register(
|
||||
'budgets.show', function (Generator $breadcrumbs, Budget $budget, LimitRepetition $repetition = null) {
|
||||
$breadcrumbs->parent('budgets.index');
|
||||
$breadcrumbs->push(e($budget->name), route('budgets.show', $budget->id));
|
||||
if (!is_null($repetition)) {
|
||||
if (!is_null($repetition) && !is_null($repetition->id)) {
|
||||
$breadcrumbs->push(
|
||||
DateKit::periodShow($repetition->startdate, $repetition->budgetlimit->repeat_freq), route('budgets.show', $budget->id, $repetition->id)
|
||||
Navigation::periodShow($repetition->startdate, $repetition->budgetlimit->repeat_freq), route('budgets.show', $budget->id, $repetition->id)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -137,35 +144,35 @@ Breadcrumbs::register(
|
||||
|
||||
// piggy banks
|
||||
Breadcrumbs::register(
|
||||
'piggyBanks.index', function (Generator $breadcrumbs) {
|
||||
'piggy-banks.index', function (Generator $breadcrumbs) {
|
||||
$breadcrumbs->parent('home');
|
||||
$breadcrumbs->push('Piggy banks', route('piggyBanks.index'));
|
||||
$breadcrumbs->push('Piggy banks', route('piggy-banks.index'));
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'piggyBanks.create', function (Generator $breadcrumbs) {
|
||||
$breadcrumbs->parent('piggyBanks.index');
|
||||
$breadcrumbs->push('Create new piggy bank', route('piggyBanks.create'));
|
||||
'piggy-banks.create', function (Generator $breadcrumbs) {
|
||||
$breadcrumbs->parent('piggy-banks.index');
|
||||
$breadcrumbs->push('Create new piggy bank', route('piggy-banks.create'));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'piggyBanks.edit', function (Generator $breadcrumbs, PiggyBank $piggyBank) {
|
||||
$breadcrumbs->parent('piggyBanks.show', $piggyBank);
|
||||
$breadcrumbs->push('Edit ' . e($piggyBank->name), route('piggyBanks.edit', $piggyBank->id));
|
||||
'piggy-banks.edit', function (Generator $breadcrumbs, PiggyBank $piggyBank) {
|
||||
$breadcrumbs->parent('piggy-banks.show', $piggyBank);
|
||||
$breadcrumbs->push('Edit ' . e($piggyBank->name), route('piggy-banks.edit', $piggyBank->id));
|
||||
}
|
||||
);
|
||||
Breadcrumbs::register(
|
||||
'piggyBanks.delete', function (Generator $breadcrumbs, PiggyBank $piggyBank) {
|
||||
$breadcrumbs->parent('piggyBanks.show', $piggyBank);
|
||||
$breadcrumbs->push('Delete ' . e($piggyBank->name), route('piggyBanks.delete', $piggyBank->id));
|
||||
'piggy-banks.delete', function (Generator $breadcrumbs, PiggyBank $piggyBank) {
|
||||
$breadcrumbs->parent('piggy-banks.show', $piggyBank);
|
||||
$breadcrumbs->push('Delete ' . e($piggyBank->name), route('piggy-banks.delete', $piggyBank->id));
|
||||
}
|
||||
);
|
||||
|
||||
Breadcrumbs::register(
|
||||
'piggyBanks.show', function (Generator $breadcrumbs, PiggyBank $piggyBank) {
|
||||
$breadcrumbs->parent('piggyBanks.index');
|
||||
$breadcrumbs->push(e($piggyBank->name), route('piggyBanks.show', $piggyBank->id));
|
||||
'piggy-banks.show', function (Generator $breadcrumbs, PiggyBank $piggyBank) {
|
||||
$breadcrumbs->parent('piggy-banks.index');
|
||||
$breadcrumbs->push(e($piggyBank->name), route('piggy-banks.show', $piggyBank->id));
|
||||
|
||||
}
|
||||
);
|
||||
@ -342,7 +349,7 @@ Breadcrumbs::register(
|
||||
Breadcrumbs::register(
|
||||
'transactions.create', function (Generator $breadcrumbs, $what) {
|
||||
$breadcrumbs->parent('transactions.index', $what);
|
||||
$breadcrumbs->push('Create new ' .e($what), route('transactions.create', $what));
|
||||
$breadcrumbs->push('Create new ' . e($what), route('transactions.create', $what));
|
||||
}
|
||||
);
|
||||
|
@ -1,12 +1,20 @@
|
||||
<?php
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
|
||||
|
||||
// models
|
||||
Route::bind(
|
||||
'account',
|
||||
function ($value, $route) {
|
||||
if (Auth::check()) {
|
||||
$account = Account::
|
||||
leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
$account = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->where('account_types.editable', 1)
|
||||
->where('accounts.id', $value)
|
||||
->where('user_id', Auth::user()->id)
|
||||
@ -20,34 +28,13 @@ Route::bind(
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'accountname', function ($value, $route) {
|
||||
'repeatedExpense', function ($value, $route) {
|
||||
if (Auth::check()) {
|
||||
return Account::
|
||||
leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')->where('account_types.editable', 1)->where('name', $value)->where(
|
||||
'user_id', Auth::user()->id
|
||||
)->first();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
Route::bind(
|
||||
'bill', function ($value, $route) {
|
||||
if (Auth::check()) {
|
||||
return Bill::
|
||||
where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
Route::bind(
|
||||
'budget', function ($value, $route) {
|
||||
if (Auth::check()) {
|
||||
return Budget::
|
||||
where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
return PiggyBank::
|
||||
where('piggy_banks.id', $value)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
|
||||
->where('accounts.user_id', Auth::user()->id)
|
||||
->where('repeats', 1)->first(['piggy_banks.*']);
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -55,31 +42,9 @@ Route::bind(
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'component', function ($value, $route) {
|
||||
'tjSecond', function ($value, $route) {
|
||||
if (Auth::check()) {
|
||||
return Component::
|
||||
where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'reminder', function ($value, $route) {
|
||||
if (Auth::check()) {
|
||||
return Reminder::
|
||||
where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'category', function ($value, $route) {
|
||||
if (Auth::check()) {
|
||||
return Category::
|
||||
return TransactionJournal::
|
||||
where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
}
|
||||
|
||||
@ -97,11 +62,17 @@ Route::bind(
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'tjSecond', function ($value, $route) {
|
||||
'currency', function ($value, $route) {
|
||||
return TransactionCurrency::find($value);
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'bill', function ($value, $route) {
|
||||
if (Auth::check()) {
|
||||
return TransactionJournal::
|
||||
where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
return Bill::where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -109,8 +80,12 @@ Route::bind(
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'currency', function ($value, $route) {
|
||||
return TransactionCurrency::find($value);
|
||||
'budget', function ($value, $route) {
|
||||
if (Auth::check()) {
|
||||
return Budget::where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
@ -143,132 +118,56 @@ Route::bind(
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'repeatedExpense', function ($value, $route) {
|
||||
'category', function ($value, $route) {
|
||||
if (Auth::check()) {
|
||||
return PiggyBank::
|
||||
where('piggy_banks.id', $value)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
|
||||
->where('accounts.user_id', Auth::user()->id)
|
||||
->where('repeats', 1)->first(['piggy_banks.*']);
|
||||
return Category::where('id', $value)->where('user_id', Auth::user()->id)->first();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
Route::bind(
|
||||
'repeated', function ($value, $route) {
|
||||
if (Auth::check()) {
|
||||
return PiggyBank::
|
||||
where('piggy_banks.id', $value)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
|
||||
->where('accounts.user_id', Auth::user()->id)
|
||||
->where('repeats', 1)->first(['piggy_banks.*']);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Auth\AuthController
|
||||
*/
|
||||
Route::get('/register', ['uses' => 'Auth\AuthController@getRegister', 'as' => 'register']);
|
||||
|
||||
Route::controllers(
|
||||
[
|
||||
'auth' => 'Auth\AuthController',
|
||||
'password' => 'Auth\PasswordController',
|
||||
]
|
||||
);
|
||||
|
||||
// protected routes:
|
||||
|
||||
/**
|
||||
* Home Controller
|
||||
*/
|
||||
Route::group(
|
||||
['before' => 'auth'], function () {
|
||||
|
||||
|
||||
// some date routes used for (well duh) date-based navigation.
|
||||
['middleware' => ['auth', 'range']], function () {
|
||||
Route::get('/', ['uses' => 'HomeController@index', 'as' => 'index']);
|
||||
Route::get('/home', ['uses' => 'HomeController@index', 'as' => 'home']);
|
||||
Route::get('/prev', ['uses' => 'HomeController@sessionPrev', 'as' => 'sessionPrev']);
|
||||
Route::get('/next', ['uses' => 'HomeController@sessionNext', 'as' => 'sessionNext']);
|
||||
Route::get('/jump/{range}', ['uses' => 'HomeController@rangeJump', 'as' => 'rangeJump']);
|
||||
|
||||
|
||||
// account controller:
|
||||
Route::get('/flush', ['uses' => 'HomeController@flush', 'as' => 'flush']);
|
||||
/**
|
||||
* Account Controller
|
||||
*/
|
||||
Route::get('/accounts/{what}', ['uses' => 'AccountController@index', 'as' => 'accounts.index'])->where('what', 'revenue|asset|expense');
|
||||
Route::get('/accounts/create/{what}', ['uses' => 'AccountController@create', 'as' => 'accounts.create'])->where('what', 'revenue|asset|expense');
|
||||
Route::get('/accounts/edit/{account}', ['uses' => 'AccountController@edit', 'as' => 'accounts.edit']);
|
||||
Route::get('/accounts/delete/{account}', ['uses' => 'AccountController@delete', 'as' => 'accounts.delete']);
|
||||
Route::get('/accounts/show/{account}/{view?}', ['uses' => 'AccountController@show', 'as' => 'accounts.show']);
|
||||
|
||||
Route::post('/accounts/store', ['uses' => 'AccountController@store', 'as' => 'accounts.store']);
|
||||
Route::post('/accounts/update/{account}', ['uses' => 'AccountController@update', 'as' => 'accounts.update']);
|
||||
Route::post('/accounts/destroy/{account}', ['uses' => 'AccountController@destroy', 'as' => 'accounts.destroy']);
|
||||
|
||||
// budget controller:
|
||||
Route::get('/budgets', ['uses' => 'BudgetController@index', 'as' => 'budgets.index']);
|
||||
Route::get('/budgets/income', ['uses' => 'BudgetController@updateIncome', 'as' => 'budgets.income']); # extra.
|
||||
Route::get('/budgets/create', ['uses' => 'BudgetController@create', 'as' => 'budgets.create']);
|
||||
Route::get('/budgets/edit/{budget}', ['uses' => 'BudgetController@edit', 'as' => 'budgets.edit']);
|
||||
Route::get('/budgets/delete/{budget}', ['uses' => 'BudgetController@delete', 'as' => 'budgets.delete']);
|
||||
Route::get('/budgets/show/{budget}/{limitrepetition?}', ['uses' => 'BudgetController@show', 'as' => 'budgets.show']);
|
||||
Route::get('/budgets/list/noBudget', ['uses' => 'BudgetController@noBudget', 'as' => 'budgets.noBudget']);
|
||||
|
||||
// category controller:
|
||||
Route::get('/categories', ['uses' => 'CategoryController@index', 'as' => 'categories.index']);
|
||||
Route::get('/categories/create', ['uses' => 'CategoryController@create', 'as' => 'categories.create']);
|
||||
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.noCategory']);
|
||||
|
||||
// currency controller
|
||||
Route::get('/currency', ['uses' => 'CurrencyController@index', 'as' => 'currency.index']);
|
||||
Route::get('/currency/create', ['uses' => 'CurrencyController@create', 'as' => 'currency.create']);
|
||||
Route::get('/currency/edit/{currency}', ['uses' => 'CurrencyController@edit', 'as' => 'currency.edit']);
|
||||
Route::get('/currency/delete/{currency}', ['uses' => 'CurrencyController@delete', 'as' => 'currency.delete']);
|
||||
Route::get('/currency/default/{currency}', ['uses' => 'CurrencyController@defaultCurrency', 'as' => 'currency.default']);
|
||||
|
||||
// google chart controller
|
||||
Route::get('/chart/home/account', ['uses' => 'GoogleChartController@allAccountsBalanceChart']);
|
||||
Route::get('/chart/home/budgets', ['uses' => 'GoogleChartController@allBudgetsHomeChart']);
|
||||
Route::get('/chart/home/categories', ['uses' => 'GoogleChartController@allCategoriesHomeChart']);
|
||||
Route::get('/chart/home/bills', ['uses' => 'GoogleChartController@billsOverview']);
|
||||
Route::get('/chart/account/{account}/{view?}', ['uses' => 'GoogleChartController@accountBalanceChart']);
|
||||
Route::get('/chart/reports/income-expenses/{year}', ['uses' => 'GoogleChartController@yearInExp']);
|
||||
Route::get('/chart/reports/income-expenses-sum/{year}', ['uses' => 'GoogleChartController@yearInExpSum']);
|
||||
Route::get('/chart/bills/{bill}', ['uses' => 'GoogleChartController@billOverview']);
|
||||
|
||||
Route::get('/chart/piggy_history/{piggyBank}', ['uses' => 'GoogleChartController@piggyBankHistory']);
|
||||
|
||||
// google chart for components (categories + budgets combined)
|
||||
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
|
||||
Route::get('/help/{route}', ['uses' => 'HelpController@show', 'as' => 'help.show']);
|
||||
|
||||
// home controller
|
||||
Route::get('/', ['uses' => 'HomeController@index', 'as' => 'index']);
|
||||
Route::get('/flush', ['uses' => 'HomeController@flush', 'as' => 'flush']); # even though nothing is cached.
|
||||
|
||||
// JSON controller
|
||||
Route::get('/json/expense-accounts', ['uses' => 'JsonController@expenseAccounts', 'as' => 'json.expense-accounts']);
|
||||
Route::get('/json/revenue-accounts', ['uses' => 'JsonController@revenueAccounts', 'as' => 'json.revenue-accounts']);
|
||||
Route::get('/json/categories', ['uses' => 'JsonController@categories', 'as' => 'json.categories']);
|
||||
|
||||
|
||||
// piggy bank controller
|
||||
Route::get('/piggy_banks', ['uses' => 'PiggyBankController@index', 'as' => 'piggy_banks.index']);
|
||||
Route::get('/piggy_banks/add/{piggyBank}', ['uses' => 'PiggyBankController@add']); # add money
|
||||
Route::get('/piggy_banks/remove/{piggyBank}', ['uses' => 'PiggyBankController@remove']); #remove money
|
||||
|
||||
Route::get('/piggy_banks/create', ['uses' => 'PiggyBankController@create', 'as' => 'piggy_banks.create']);
|
||||
Route::get('/piggy_banks/edit/{piggyBank}', ['uses' => 'PiggyBankController@edit', 'as' => 'piggy_banks.edit']);
|
||||
Route::get('/piggy_banks/delete/{piggyBank}', ['uses' => 'PiggyBankController@delete', 'as' => 'piggy_banks.delete']);
|
||||
Route::get('/piggy_banks/show/{piggyBank}', ['uses' => 'PiggyBankController@show', 'as' => 'piggy_banks.show']);
|
||||
|
||||
// preferences controller
|
||||
Route::get('/preferences', ['uses' => 'PreferencesController@index', 'as' => 'preferences']);
|
||||
|
||||
//profile controller
|
||||
Route::get('/profile', ['uses' => 'ProfileController@index', 'as' => 'profile']);
|
||||
Route::get('/profile/change-password', ['uses' => 'ProfileController@changePassword', 'as' => 'change-password']);
|
||||
|
||||
// related controller:
|
||||
Route::get('/related/alreadyRelated/{tj}', ['uses' => 'RelatedController@alreadyRelated', 'as' => 'related.alreadyRelated']);
|
||||
Route::post('/related/relate/{tj}/{tjSecond}', ['uses' => 'RelatedController@relate', 'as' => 'related.relate']);
|
||||
Route::get('/related/removeRelation/{tj}/{tjSecond}', ['uses' => 'RelatedController@removeRelation', 'as' => 'related.removeRelation']);
|
||||
Route::get('/related/related/{tj}', ['uses' => 'RelatedController@related', 'as' => 'related.related']);
|
||||
Route::post('/related/search/{tj}', ['uses' => 'RelatedController@search', 'as' => 'related.search']);
|
||||
|
||||
// bills controller
|
||||
/**
|
||||
* Bills Controller
|
||||
*/
|
||||
Route::get('/bills', ['uses' => 'BillController@index', 'as' => 'bills.index']);
|
||||
Route::get('/bills/rescan/{bill}', ['uses' => 'BillController@rescan', 'as' => 'bills.rescan']); # rescan for matching.
|
||||
Route::get('/bills/create', ['uses' => 'BillController@create', 'as' => 'bills.create']);
|
||||
@ -276,29 +175,148 @@ Route::group(
|
||||
Route::get('/bills/delete/{bill}', ['uses' => 'BillController@delete', 'as' => 'bills.delete']);
|
||||
Route::get('/bills/show/{bill}', ['uses' => 'BillController@show', 'as' => 'bills.show']);
|
||||
|
||||
// repeated expenses controller:
|
||||
Route::get('/repeatedexpenses', ['uses' => 'RepeatedExpenseController@index', 'as' => 'repeated.index']);
|
||||
Route::get('/repeatedexpenses/create', ['uses' => 'RepeatedExpenseController@create', 'as' => 'repeated.create']);
|
||||
Route::get('/repeatedexpenses/edit/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@edit', 'as' => 'repeated.edit']);
|
||||
Route::get('/repeatedexpenses/delete/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@delete', 'as' => 'repeated.delete']);
|
||||
Route::get('/repeatedexpenses/show/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@show', 'as' => 'repeated.show']);
|
||||
Route::post('/bills/store', ['uses' => 'BillController@store', 'as' => 'bills.store']);
|
||||
Route::post('/bills/update/{bill}', ['uses' => 'BillController@update', 'as' => 'bills.update']);
|
||||
Route::post('/bills/destroy/{bill}', ['uses' => 'BillController@destroy', 'as' => 'bills.destroy']);
|
||||
|
||||
// report controller:
|
||||
/**
|
||||
* Budget Controller
|
||||
*/
|
||||
Route::get('/budgets', ['uses' => 'BudgetController@index', 'as' => 'budgets.index']);
|
||||
Route::get('/budgets/income', ['uses' => 'BudgetController@updateIncome', 'as' => 'budgets.income']); # extra.
|
||||
Route::get('/budgets/create', ['uses' => 'BudgetController@create', 'as' => 'budgets.create']);
|
||||
Route::get('/budgets/edit/{budget}', ['uses' => 'BudgetController@edit', 'as' => 'budgets.edit']);
|
||||
Route::get('/budgets/delete/{budget}', ['uses' => 'BudgetController@delete', 'as' => 'budgets.delete']);
|
||||
Route::get('/budgets/show/{budget}/{limitrepetition?}', ['uses' => 'BudgetController@show', 'as' => 'budgets.show']);
|
||||
Route::get('/budgets/list/noBudget', ['uses' => 'BudgetController@noBudget', 'as' => 'budgets.noBudget']);
|
||||
Route::post('/budgets/income', ['uses' => 'BudgetController@postUpdateIncome', 'as' => 'budgets.postIncome']);
|
||||
Route::post('/budgets/store', ['uses' => 'BudgetController@store', 'as' => 'budgets.store']);
|
||||
Route::post('/budgets/update/{budget}', ['uses' => 'BudgetController@update', 'as' => 'budgets.update']);
|
||||
Route::post('/budgets/destroy/{budget}', ['uses' => 'BudgetController@destroy', 'as' => 'budgets.destroy']);
|
||||
Route::post('budgets/amount/{budget}', ['uses' => 'BudgetController@amount']);
|
||||
|
||||
/**
|
||||
* Category Controller
|
||||
*/
|
||||
Route::get('/categories', ['uses' => 'CategoryController@index', 'as' => 'categories.index']);
|
||||
Route::get('/categories/create', ['uses' => 'CategoryController@create', 'as' => 'categories.create']);
|
||||
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.noCategory']);
|
||||
Route::post('/categories/store', ['uses' => 'CategoryController@store', 'as' => 'categories.store']);
|
||||
Route::post('/categories/update/{category}', ['uses' => 'CategoryController@update', 'as' => 'categories.update']);
|
||||
Route::post('/categories/destroy/{category}', ['uses' => 'CategoryController@destroy', 'as' => 'categories.destroy']);
|
||||
|
||||
/**
|
||||
* Currency Controller
|
||||
*/
|
||||
Route::get('/currency', ['uses' => 'CurrencyController@index', 'as' => 'currency.index']);
|
||||
Route::get('/currency/create', ['uses' => 'CurrencyController@create', 'as' => 'currency.create']);
|
||||
Route::get('/currency/edit/{currency}', ['uses' => 'CurrencyController@edit', 'as' => 'currency.edit']);
|
||||
Route::get('/currency/delete/{currency}', ['uses' => 'CurrencyController@delete', 'as' => 'currency.delete']);
|
||||
Route::get('/currency/default/{currency}', ['uses' => 'CurrencyController@defaultCurrency', 'as' => 'currency.default']);
|
||||
Route::post('/currency/store', ['uses' => 'CurrencyController@store', 'as' => 'currency.store']);
|
||||
Route::post('/currency/update/{currency}', ['uses' => 'CurrencyController@update', 'as' => 'currency.update']);
|
||||
Route::post('/currency/destroy/{currency}', ['uses' => 'CurrencyController@destroy', 'as' => 'currency.destroy']);
|
||||
|
||||
|
||||
/**
|
||||
* Google Chart Controller
|
||||
*/
|
||||
Route::get('/chart/home/account', ['uses' => 'GoogleChartController@allAccountsBalanceChart']);
|
||||
Route::get('/chart/home/budgets', ['uses' => 'GoogleChartController@allBudgetsHomeChart']);
|
||||
Route::get('/chart/home/categories', ['uses' => 'GoogleChartController@allCategoriesHomeChart']);
|
||||
Route::get('/chart/home/bills', ['uses' => 'GoogleChartController@billsOverview']);
|
||||
Route::get('/chart/account/{account}/{view?}', ['uses' => 'GoogleChartController@accountBalanceChart']);
|
||||
Route::get('/chart/budget/{budget}/spending/{year?}', ['uses' => 'GoogleChartController@budgetsAndSpending']);
|
||||
Route::get('/chart/budgets/spending/{year?}', ['uses' => 'GoogleChartController@allBudgetsAndSpending']);
|
||||
Route::get('/chart/budget/{budget}/{limitrepetition}', ['uses' => 'GoogleChartController@budgetLimitSpending']);
|
||||
Route::get('/chart/category/{category}/spending/{year}', ['uses' => 'GoogleChartController@categoriesAndSpending']);
|
||||
Route::get('/chart/reports/income-expenses/{year}', ['uses' => 'GoogleChartController@yearInExp']);
|
||||
Route::get('/chart/reports/income-expenses-sum/{year}', ['uses' => 'GoogleChartController@yearInExpSum']);
|
||||
Route::get('/chart/bills/{bill}', ['uses' => 'GoogleChartController@billOverview']);
|
||||
Route::get('/chart/piggy-history/{piggyBank}', ['uses' => 'GoogleChartController@piggyBankHistory']);
|
||||
|
||||
/**
|
||||
* Help Controller
|
||||
*/
|
||||
Route::get('/help/{route}', ['uses' => 'HelpController@show', 'as' => 'help.show']);
|
||||
|
||||
/**
|
||||
* JSON Controller
|
||||
*/
|
||||
Route::get('/json/expense-accounts', ['uses' => 'JsonController@expenseAccounts', 'as' => 'json.expense-accounts']);
|
||||
Route::get('/json/revenue-accounts', ['uses' => 'JsonController@revenueAccounts', 'as' => 'json.revenue-accounts']);
|
||||
Route::get('/json/categories', ['uses' => 'JsonController@categories', 'as' => 'json.categories']);
|
||||
|
||||
|
||||
/**
|
||||
* Piggy Bank Controller
|
||||
*/
|
||||
Route::get('/piggy-banks', ['uses' => 'PiggyBankController@index', 'as' => 'piggy-banks.index']);
|
||||
Route::get('/piggy-banks/add/{piggyBank}', ['uses' => 'PiggyBankController@add']); # add money
|
||||
Route::get('/piggy-banks/remove/{piggyBank}', ['uses' => 'PiggyBankController@remove']); #remove money
|
||||
Route::get('/piggy-banks/create', ['uses' => 'PiggyBankController@create', 'as' => 'piggy-banks.create']);
|
||||
Route::get('/piggy-banks/edit/{piggyBank}', ['uses' => 'PiggyBankController@edit', 'as' => 'piggy-banks.edit']);
|
||||
Route::get('/piggy-banks/delete/{piggyBank}', ['uses' => 'PiggyBankController@delete', 'as' => 'piggy-banks.delete']);
|
||||
Route::get('/piggy-banks/show/{piggyBank}', ['uses' => 'PiggyBankController@show', 'as' => 'piggy-banks.show']);
|
||||
Route::post('/piggy-banks/store', ['uses' => 'PiggyBankController@store', 'as' => 'piggy-banks.store']);
|
||||
Route::post('/piggy-banks/update/{piggyBank}', ['uses' => 'PiggyBankController@update', 'as' => 'piggy-banks.update']);
|
||||
Route::post('/piggy-banks/destroy/{piggyBank}', ['uses' => 'PiggyBankController@destroy', 'as' => 'piggy-banks.destroy']);
|
||||
Route::post('/piggy-banks/add/{piggyBank}', ['uses' => 'PiggyBankController@postAdd', 'as' => 'piggy-banks.add']); # add money
|
||||
Route::post('/piggy-banks/remove/{piggyBank}', ['uses' => 'PiggyBankController@postRemove', 'as' => 'piggy-banks.remove']); # remove money.
|
||||
|
||||
/**
|
||||
* Preferences Controller
|
||||
*/
|
||||
Route::get('/preferences', ['uses' => 'PreferencesController@index', 'as' => 'preferences']);
|
||||
Route::post('/preferences', ['uses' => 'PreferencesController@postIndex']);
|
||||
|
||||
/**
|
||||
* Profile Controller
|
||||
*/
|
||||
Route::get('/profile', ['uses' => 'ProfileController@index', 'as' => 'profile']);
|
||||
Route::get('/profile/change-password', ['uses' => 'ProfileController@changePassword', 'as' => 'change-password']);
|
||||
Route::post('/profile/change-password', ['uses' => 'ProfileController@postChangePassword','as' => 'change-password-post']);
|
||||
|
||||
/**
|
||||
* Related transactions controller
|
||||
*/
|
||||
Route::get('/related/alreadyRelated/{tj}', ['uses' => 'RelatedController@alreadyRelated', 'as' => 'related.alreadyRelated']);
|
||||
Route::post('/related/relate/{tj}/{tjSecond}', ['uses' => 'RelatedController@relate', 'as' => 'related.relate']);
|
||||
Route::post('/related/removeRelation/{tj}/{tjSecond}', ['uses' => 'RelatedController@removeRelation', 'as' => 'related.removeRelation']);
|
||||
Route::get('/related/related/{tj}', ['uses' => 'RelatedController@related', 'as' => 'related.related']);
|
||||
Route::post('/related/search/{tj}', ['uses' => 'RelatedController@search', 'as' => 'related.search']);
|
||||
|
||||
/**
|
||||
* Repeated Expenses Controller
|
||||
*/
|
||||
Route::get('/repeated-expenses', ['uses' => 'RepeatedExpenseController@index', 'as' => 'repeated.index']);
|
||||
Route::get('/repeated-expenses/create', ['uses' => 'RepeatedExpenseController@create', 'as' => 'repeated.create']);
|
||||
Route::get('/repeated-expenses/edit/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@edit', 'as' => 'repeated.edit']);
|
||||
Route::get('/repeated-expenses/delete/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@delete', 'as' => 'repeated.delete']);
|
||||
Route::get('/repeated-expenses/show/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@show', 'as' => 'repeated.show']);
|
||||
Route::post('/repeated-expense/store', ['uses' => 'RepeatedExpenseController@store', 'as' => 'repeated.store']);
|
||||
Route::post('/repeated-expense/update/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@update', 'as' => 'repeated.update']);
|
||||
Route::post('/repeated-expense/destroy/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@destroy', 'as' => 'repeated.destroy']);
|
||||
|
||||
/**
|
||||
* Report Controller
|
||||
*/
|
||||
Route::get('/reports', ['uses' => 'ReportController@index', 'as' => 'reports.index']);
|
||||
Route::get('/reports/{year}', ['uses' => 'ReportController@year', 'as' => 'reports.year']);
|
||||
Route::get('/reports/{year}/{month}', ['uses' => 'ReportController@month', 'as' => 'reports.month']);
|
||||
Route::get('/reports/budget/{year}/{month}', ['uses' => 'ReportController@budget', 'as' => 'reports.budget']);
|
||||
|
||||
// reminder controller
|
||||
Route::get('/reminders/{reminder}', ['uses' => 'ReminderController@show', 'as' => 'reminders.show']);
|
||||
Route::get('/reminders/{reminder}/dismiss', ['uses' => 'ReminderController@dismiss', 'as' => 'reminders.dismiss']);
|
||||
Route::get('/reminders/{reminder}/notNow', ['uses' => 'ReminderController@notNow', 'as' => 'reminders.notNow']);
|
||||
Route::get('/reminders/{reminder}/act', ['uses' => 'ReminderController@act', 'as' => 'reminders.act']);
|
||||
|
||||
// search controller:
|
||||
/**
|
||||
* Search Controller
|
||||
*/
|
||||
Route::get('/search', ['uses' => 'SearchController@index', 'as' => 'search']);
|
||||
|
||||
// transaction controller:
|
||||
/**
|
||||
* Transaction Controller
|
||||
*/
|
||||
Route::get('/transactions/{what}', ['uses' => 'TransactionController@index', 'as' => 'transactions.index'])->where(
|
||||
['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers']
|
||||
);
|
||||
@ -308,68 +326,6 @@ Route::group(
|
||||
Route::get('/transaction/edit/{tj}', ['uses' => 'TransactionController@edit', 'as' => 'transactions.edit']);
|
||||
Route::get('/transaction/delete/{tj}', ['uses' => 'TransactionController@delete', 'as' => 'transactions.delete']);
|
||||
Route::get('/transaction/show/{tj}', ['uses' => 'TransactionController@show', 'as' => 'transactions.show']);
|
||||
Route::get('/transaction/relate/{tj}', ['uses' => 'TransactionController@relate', 'as' => 'transactions.relate']);
|
||||
Route::post('/transactions/relatedSearch/{tj}', ['uses' => 'TransactionController@relatedSearch', 'as' => 'transactions.relatedSearch']);
|
||||
Route::post('/transactions/alreadyRelated/{tj}', ['uses' => 'TransactionController@alreadyRelated', 'as' => 'transactions.alreadyRelated']);
|
||||
Route::post('/transactions/doRelate', ['uses' => 'TransactionController@doRelate', 'as' => 'transactions.doRelate']);
|
||||
Route::any('/transactions/unrelate/{tj}', ['uses' => 'TransactionController@unrelate', 'as' => 'transactions.unrelate']);
|
||||
|
||||
// user controller
|
||||
Route::get('/logout', ['uses' => 'UserController@logout', 'as' => 'logout']);
|
||||
|
||||
Route::post('budgets/amount/{budget}', ['uses' => 'BudgetController@amount']);
|
||||
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
// protected + csrf routes (POST)
|
||||
Route::group(
|
||||
['before' => 'csrf|auth'], function () {
|
||||
// account controller:
|
||||
Route::post('/accounts/store', ['uses' => 'AccountController@store', 'as' => 'accounts.store']);
|
||||
Route::post('/accounts/update/{account}', ['uses' => 'AccountController@update', 'as' => 'accounts.update']);
|
||||
Route::post('/accounts/destroy/{account}', ['uses' => 'AccountController@destroy', 'as' => 'accounts.destroy']);
|
||||
|
||||
// budget controller:
|
||||
Route::post('/budgets/income', ['uses' => 'BudgetController@postUpdateIncome', 'as' => 'budgets.postIncome']);
|
||||
Route::post('/budgets/store', ['uses' => 'BudgetController@store', 'as' => 'budgets.store']);
|
||||
Route::post('/budgets/update/{budget}', ['uses' => 'BudgetController@update', 'as' => 'budgets.update']);
|
||||
Route::post('/budgets/destroy/{budget}', ['uses' => 'BudgetController@destroy', 'as' => 'budgets.destroy']);
|
||||
|
||||
// category controller
|
||||
Route::post('/categories/store', ['uses' => 'CategoryController@store', 'as' => 'categories.store']);
|
||||
Route::post('/categories/update/{category}', ['uses' => 'CategoryController@update', 'as' => 'categories.update']);
|
||||
Route::post('/categories/destroy/{category}', ['uses' => 'CategoryController@destroy', 'as' => 'categories.destroy']);
|
||||
|
||||
// currency controller
|
||||
Route::post('/currency/store', ['uses' => 'CurrencyController@store', 'as' => 'currency.store']);
|
||||
Route::post('/currency/update/{currency}', ['uses' => 'CurrencyController@update', 'as' => 'currency.update']);
|
||||
Route::post('/currency/destroy/{currency}', ['uses' => 'CurrencyController@destroy', 'as' => 'currency.destroy']);
|
||||
|
||||
// piggy bank controller
|
||||
Route::post('/piggy_banks/store', ['uses' => 'PiggyBankController@store', 'as' => 'piggy_banks.store']);
|
||||
Route::post('/piggy_banks/update/{piggyBank}', ['uses' => 'PiggyBankController@update', 'as' => 'piggy_banks.update']);
|
||||
Route::post('/piggy_banks/destroy/{piggyBank}', ['uses' => 'PiggyBankController@destroy', 'as' => 'piggy_banks.destroy']);
|
||||
Route::post('/piggy_banks/add/{piggyBank}', ['uses' => 'PiggyBankController@postAdd', 'as' => 'piggy_banks.add']); # add money
|
||||
Route::post('/piggy_banks/remove/{piggyBank}', ['uses' => 'PiggyBankController@postRemove', 'as' => 'piggy_banks.remove']); # remove money.
|
||||
|
||||
// repeated expense controller
|
||||
Route::post('/repeatedexpense/store', ['uses' => 'RepeatedExpenseController@store', 'as' => 'repeated.store']);
|
||||
Route::post('/repeatedexpense/update/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@update', 'as' => 'repeated.update']);
|
||||
Route::post('/repeatedexpense/destroy/{repeatedExpense}', ['uses' => 'RepeatedExpenseController@destroy', 'as' => 'repeated.destroy']);
|
||||
|
||||
// preferences controller
|
||||
Route::post('/preferences', ['uses' => 'PreferencesController@postIndex']);
|
||||
|
||||
// profile controller
|
||||
Route::post('/profile/change-password', ['uses' => 'ProfileController@postChangePassword']);
|
||||
|
||||
// bills controller
|
||||
Route::post('/bills/store', ['uses' => 'BillController@store', 'as' => 'bills.store']);
|
||||
Route::post('/bills/update/{bill}', ['uses' => 'BillController@update', 'as' => 'bills.update']);
|
||||
Route::post('/bills/destroy/{bill}', ['uses' => 'BillController@destroy', 'as' => 'bills.destroy']);
|
||||
|
||||
// transaction controller:
|
||||
Route::post('/transactions/store/{what}', ['uses' => 'TransactionController@store', 'as' => 'transactions.store'])->where(
|
||||
['what' => 'expenses|revenue|withdrawal|deposit|transfer|transfers']
|
||||
@ -377,32 +333,12 @@ Route::group(
|
||||
Route::post('/transaction/update/{tj}', ['uses' => 'TransactionController@update', 'as' => 'transactions.update']);
|
||||
Route::post('/transaction/destroy/{tj}', ['uses' => 'TransactionController@destroy', 'as' => 'transactions.destroy']);
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
// guest routes:
|
||||
Route::group(
|
||||
['before' => 'guest'], function () {
|
||||
// user controller
|
||||
Route::get('/login', ['uses' => 'UserController@login', 'as' => 'login']);
|
||||
Route::get('/register', ['uses' => 'UserController@register', 'as' => 'register', 'before' => 'allow-register']);
|
||||
Route::get('/reset/{reset}', ['uses' => 'UserController@reset', 'as' => 'reset']);
|
||||
Route::get('/remindMe', ['uses' => 'UserController@remindMe', 'as' => 'remindMe']);
|
||||
|
||||
Route::get('/oauth2callback', ['uses' => 'HomeController@marauder', 'as' => 'marauder']);
|
||||
/**
|
||||
* Auth\Auth Controller
|
||||
*/
|
||||
Route::get('/logout', ['uses' => 'Auth\AuthController@getLogout', 'as' => 'logout']);
|
||||
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// guest + csrf routes:
|
||||
Route::group(
|
||||
['before' => 'csrf|guest'], function () {
|
||||
|
||||
// user controller
|
||||
Route::post('/login', ['uses' => 'UserController@postLogin', 'as' => 'login.post']);
|
||||
Route::post('/register', ['uses' => 'UserController@postRegister', 'as' => 'register.post', 'before' => 'allow-register']);
|
||||
Route::post('/remindMe', ['uses' => 'UserController@postRemindMe', 'as' => 'remindMe.post']);
|
||||
}
|
||||
);
|
@ -1,35 +1,35 @@
|
||||
<?php
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
use \Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
|
||||
/**
|
||||
* Class AccountMeta
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
*/
|
||||
class AccountMeta extends Eloquent
|
||||
class AccountMeta extends Model
|
||||
{
|
||||
|
||||
use ValidatingTrait;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $rules
|
||||
= [
|
||||
'account_id' => 'numeric|required|exists:accounts,id',
|
||||
'name' => 'required|between:1,250',
|
||||
protected $fillable = ['account_id', 'name', 'data'];
|
||||
protected $rules
|
||||
= [
|
||||
'account_id' => 'required|exists:accounts,id',
|
||||
'name' => 'required|between:1,100',
|
||||
'data' => 'required'
|
||||
];
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['account_id', 'name', 'date'];
|
||||
protected $table = 'account_meta';
|
||||
protected $table = 'account_meta';
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function account()
|
||||
{
|
||||
return $this->belongsTo('Account');
|
||||
return $this->belongsTo('FireflyIII\Models\Account');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*
|
||||
@ -40,6 +40,14 @@ class AccountMeta extends Eloquent
|
||||
return json_decode($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDates()
|
||||
{
|
||||
return ['created_at', 'updated_at'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*/
|
||||
@ -48,4 +56,4 @@ class AccountMeta extends Eloquent
|
||||
$this->attributes['data'] = json_encode($value);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,46 +1,33 @@
|
||||
<?php
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingTrait;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
/**
|
||||
* Class PiggyBank
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
*/
|
||||
class PiggyBank extends Eloquent
|
||||
class PiggyBank extends Model
|
||||
{
|
||||
use ValidatingTrait, SoftDeletingTrait;
|
||||
public $fillable
|
||||
= ['account_id', 'name', 'targetamount', 'startdate', 'targetdate', 'repeats', 'rep_length', 'rep_every', 'rep_times', 'reminder', 'reminder_skip',
|
||||
'remind_me', 'order'];
|
||||
protected $rules
|
||||
= ['account_id' => 'required|exists:accounts,id', // link to Account
|
||||
'name' => 'required|between:1,255', // name
|
||||
'targetamount' => 'required|min:0.01|numeric', // amount you want to save
|
||||
'startdate' => 'date', // when you started
|
||||
'targetdate' => 'date', // when its due
|
||||
'repeats' => 'required|boolean', // does it repeat?
|
||||
'rep_length' => 'in:day,week,month,quarter,year', // how long is the period?
|
||||
'rep_every' => 'required|min:1|max:100', // how often does it repeat? every 3 years.
|
||||
'rep_times' => 'min:1|max:100', // how many times do you want to save this amount? eg. 3 times
|
||||
'reminder' => 'in:day,week,quarter,month,year', // want a reminder to put money in this?
|
||||
'reminder_skip' => 'required|min:0|max:100', // every week? every 2 months?
|
||||
'remind_me' => 'required|boolean', 'order' => 'required:min:1', // not yet used.
|
||||
];
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = ['repeats', 'name', 'account_id','rep_every', 'rep_times', 'reminder_skip', 'targetamount', 'startdate', 'targetdate', 'reminder',];
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function account()
|
||||
{
|
||||
return $this->belongsTo('Account');
|
||||
return $this->belongsTo('FireflyIII\Models\Account');
|
||||
}
|
||||
|
||||
/**
|
||||
* Grabs the PiggyBankRepetition that's currently relevant / active
|
||||
*
|
||||
* @returns \PiggyBankRepetition
|
||||
* @returns PiggyBankRepetition
|
||||
*/
|
||||
public function currentRelevantRep()
|
||||
{
|
||||
@ -53,7 +40,7 @@ class PiggyBank extends Eloquent
|
||||
|
||||
return $rep;
|
||||
} else {
|
||||
$query = $this->piggyBankRepetitions()->where(
|
||||
$query = $this->piggyBankRepetitions()->where(
|
||||
function (EloquentBuilder $q) {
|
||||
|
||||
$q->where(
|
||||
@ -83,9 +70,8 @@ class PiggyBank extends Eloquent
|
||||
|
||||
}
|
||||
)->orderBy('startdate', 'ASC');
|
||||
$result = $query->first(['piggy_bank_repetitions.*']);
|
||||
$result = $query->first(['piggy_bank_repetitions.*']);
|
||||
$this->currentRep = $result;
|
||||
\Log::debug('Found relevant rep in currentRelevantRep(): ' . $result->id);
|
||||
|
||||
return $result;
|
||||
}
|
||||
@ -98,7 +84,7 @@ class PiggyBank extends Eloquent
|
||||
*/
|
||||
public function piggyBankRepetitions()
|
||||
{
|
||||
return $this->hasMany('PiggyBankRepetition');
|
||||
return $this->hasMany('FireflyIII\Models\PiggyBankRepetition');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,7 +92,7 @@ class PiggyBank extends Eloquent
|
||||
*/
|
||||
public function getDates()
|
||||
{
|
||||
return ['created_at', 'updated_at', 'targetdate', 'startdate'];
|
||||
return ['created_at', 'updated_at', 'deleted_at', 'startdate', 'targetdate'];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,7 +100,7 @@ class PiggyBank extends Eloquent
|
||||
*/
|
||||
public function piggyBankEvents()
|
||||
{
|
||||
return $this->hasMany('PiggyBankEvent');
|
||||
return $this->hasMany('FireflyIII\Models\PiggyBankEvent');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,6 +108,6 @@ class PiggyBank extends Eloquent
|
||||
*/
|
||||
public function reminders()
|
||||
{
|
||||
return $this->morphMany('Reminder', 'remindersable');
|
||||
return $this->morphMany('FireflyIII\Models\Reminder', 'remindersable');
|
||||
}
|
||||
}
|
@ -1,16 +1,16 @@
|
||||
<?php
|
||||
use Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Class Preference
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
*/
|
||||
class Preference extends Eloquent
|
||||
class Preference extends Model
|
||||
{
|
||||
use ValidatingTrait;
|
||||
protected $fillable = ['name', 'data', 'user_id'];
|
||||
protected $rules
|
||||
= ['user_id' => 'required|exists:users,id', 'name' => 'required|between:1,255', 'data' => 'required'];
|
||||
|
||||
protected $fillable = ['user_id', 'data', 'name'];
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
@ -22,6 +22,14 @@ class Preference extends Eloquent
|
||||
return json_decode($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDates()
|
||||
{
|
||||
return ['created_at', 'updated_at'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*/
|
||||
@ -35,7 +43,7 @@ class Preference extends Eloquent
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('User');
|
||||
return $this->belongsTo('FireflyIII\User');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,35 +1,42 @@
|
||||
<?php
|
||||
<?php namespace FireflyIII\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Crypt;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use Illuminate\Database\Eloquent\Model as Eloquent;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingTrait;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
/**
|
||||
* Class TransactionJournal
|
||||
*
|
||||
* @package FireflyIII\Models
|
||||
*/
|
||||
class TransactionJournal extends Eloquent
|
||||
class TransactionJournal extends Model
|
||||
{
|
||||
use SoftDeletingTrait, ValidatingTrait;
|
||||
use SoftDeletes, ValidatingTrait;
|
||||
|
||||
protected $fillable = ['user_id', 'transaction_type_id', 'bill_id', 'transaction_currency_id', 'description', 'completed', 'date', 'encrypted'];
|
||||
|
||||
protected $fillable
|
||||
= ['transaction_type_id', 'transaction_currency_id', 'user_id',
|
||||
'description', 'date', 'completed'];
|
||||
protected $rules
|
||||
= ['transaction_type_id' => 'required|exists:transaction_types,id',
|
||||
'transaction_currency_id' => 'required|exists:transaction_currencies,id',
|
||||
'description' => 'required|between:1,1024',
|
||||
'date' => 'required|date',
|
||||
'completed' => 'required|between:0,1'];
|
||||
= [
|
||||
'user_id' => 'required|exists:users,id',
|
||||
'transaction_type_id' => 'required|exists:transaction_types,id',
|
||||
'bill_id' => 'exists:bills,id',
|
||||
'transaction_currency_id' => 'required|exists:transaction_currencies,id',
|
||||
'description' => 'required|between:1,1024',
|
||||
'completed' => 'required|boolean',
|
||||
'date' => 'required|date',
|
||||
'encrypted' => 'required|boolean'
|
||||
];
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function bill()
|
||||
{
|
||||
return $this->belongsTo('Bill');
|
||||
return $this->belongsTo('FireflyIII\Models\Bill');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -37,9 +44,7 @@ class TransactionJournal extends Eloquent
|
||||
*/
|
||||
public function budgets()
|
||||
{
|
||||
return $this->belongsToMany(
|
||||
'Budget'
|
||||
);
|
||||
return $this->belongsToMany('FireflyIII\Models\Budget');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,31 +52,7 @@ class TransactionJournal extends Eloquent
|
||||
*/
|
||||
public function categories()
|
||||
{
|
||||
return $this->belongsToMany(
|
||||
'Category'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getAmount(\Account $account = null)
|
||||
{
|
||||
$amount = 0;
|
||||
foreach ($this->transactions as $t) {
|
||||
if (!is_null($account) && $account->id == $t->account_id) {
|
||||
$amount = floatval($t->amount);
|
||||
break;
|
||||
}
|
||||
if (floatval($t->amount) > 0) {
|
||||
$amount = floatval($t->amount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $amount;
|
||||
return $this->belongsToMany('FireflyIII\Models\Category');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,7 +60,7 @@ class TransactionJournal extends Eloquent
|
||||
*/
|
||||
public function getDates()
|
||||
{
|
||||
return ['created_at', 'updated_at', 'date'];
|
||||
return ['created_at', 'updated_at', 'date', 'deleted_at'];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -92,6 +73,7 @@ class TransactionJournal extends Eloquent
|
||||
if ($this->encrypted) {
|
||||
return Crypt::decrypt($value);
|
||||
}
|
||||
|
||||
// @codeCoverageIgnoreStart
|
||||
return $value;
|
||||
// @codeCoverageIgnoreEnd
|
||||
@ -102,14 +84,14 @@ class TransactionJournal extends Eloquent
|
||||
*/
|
||||
public function piggyBankEvents()
|
||||
{
|
||||
return $this->hasMany('PiggyBankEvent');
|
||||
return $this->hasMany('FireflyIII\Models\PiggyBankEvent');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EloquentBuilder $query
|
||||
* @param Account $account
|
||||
*/
|
||||
public function scopeAccountIs(EloquentBuilder $query, \Account $account)
|
||||
public function scopeAccountIs(EloquentBuilder $query, Account $account)
|
||||
{
|
||||
if (!isset($this->joinedTransactions)) {
|
||||
$query->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id');
|
||||
@ -156,22 +138,6 @@ class TransactionJournal extends Eloquent
|
||||
$query->where('transactions.amount', '<=', $amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EloquentBuilder $query
|
||||
* @param $amount
|
||||
*/
|
||||
public function scopeMoreThan(EloquentBuilder $query, $amount)
|
||||
{
|
||||
if (is_null($this->joinedTransactions)) {
|
||||
$query->leftJoin(
|
||||
'transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id'
|
||||
);
|
||||
$this->joinedTransactions = true;
|
||||
}
|
||||
|
||||
$query->where('transactions.amount', '>=', $amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EloquentBuilder $query
|
||||
* @param Carbon $date
|
||||
@ -209,7 +175,7 @@ class TransactionJournal extends Eloquent
|
||||
$query->with(
|
||||
['transactions' => function (HasMany $q) {
|
||||
$q->orderBy('amount', 'ASC');
|
||||
}, 'transactiontype', 'budgets', 'categories', 'transactions.account.accounttype', 'bill', 'budgets', 'categories']
|
||||
}, 'transactiontype', 'transactioncurrency', 'budgets', 'categories', 'transactions.account.accounttype', 'bill', 'budgets', 'categories']
|
||||
);
|
||||
}
|
||||
|
||||
@ -218,7 +184,7 @@ class TransactionJournal extends Eloquent
|
||||
*/
|
||||
public function setDescriptionAttribute($value)
|
||||
{
|
||||
$this->attributes['description'] = Crypt::encrypt($value);
|
||||
$this->attributes['description'] = \Crypt::encrypt($value);
|
||||
$this->attributes['encrypted'] = true;
|
||||
}
|
||||
|
||||
@ -227,7 +193,7 @@ class TransactionJournal extends Eloquent
|
||||
*/
|
||||
public function transactionCurrency()
|
||||
{
|
||||
return $this->belongsTo('TransactionCurrency');
|
||||
return $this->belongsTo('FireflyIII\Models\TransactionCurrency');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -235,7 +201,7 @@ class TransactionJournal extends Eloquent
|
||||
*/
|
||||
public function transactionType()
|
||||
{
|
||||
return $this->belongsTo('TransactionType');
|
||||
return $this->belongsTo('FireflyIII\Models\TransactionType');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -243,7 +209,7 @@ class TransactionJournal extends Eloquent
|
||||
*/
|
||||
public function transactiongroups()
|
||||
{
|
||||
return $this->belongsToMany('TransactionGroup');
|
||||
return $this->belongsToMany('FireflyIII\Models\TransactionGroup');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -251,17 +217,15 @@ class TransactionJournal extends Eloquent
|
||||
*/
|
||||
public function transactions()
|
||||
{
|
||||
return $this->hasMany('Transaction');
|
||||
return $this->hasMany('FireflyIII\Models\Transaction');
|
||||
}
|
||||
|
||||
/**
|
||||
* User
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('User');
|
||||
return $this->belongsTo('FireflyIII\User');
|
||||
}
|
||||
|
||||
}
|
40
app/Providers/AppServiceProvider.php
Normal file
40
app/Providers/AppServiceProvider.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php namespace FireflyIII\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
/**
|
||||
* Class AppServiceProvider
|
||||
*
|
||||
* @package FireflyIII\Providers
|
||||
*/
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* This service provider is a great spot to register your various container
|
||||
* bindings with the application. As you can see, we are registering our
|
||||
* "Registrar" implementation here. You can add your own bindings too!
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->app->bind(
|
||||
'Illuminate\Contracts\Auth\Registrar',
|
||||
'FireflyIII\Services\Registrar'
|
||||
);
|
||||
}
|
||||
|
||||
}
|
42
app/Providers/BusServiceProvider.php
Normal file
42
app/Providers/BusServiceProvider.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php namespace FireflyIII\Providers;
|
||||
|
||||
use Illuminate\Bus\Dispatcher;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
/**
|
||||
* Class BusServiceProvider
|
||||
*
|
||||
* @package FireflyIII\Providers
|
||||
*/
|
||||
class BusServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @param \Illuminate\Bus\Dispatcher $dispatcher
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot(Dispatcher $dispatcher)
|
||||
{
|
||||
$dispatcher->mapUsing(
|
||||
function ($command) {
|
||||
return Dispatcher::simpleMapping(
|
||||
$command, 'FireflyIII\Commands', 'FireflyIII\Handlers\Commands'
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
}
|
31
app/Providers/ConfigServiceProvider.php
Normal file
31
app/Providers/ConfigServiceProvider.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php namespace FireflyIII\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
/**
|
||||
* Class ConfigServiceProvider
|
||||
*
|
||||
* @package FireflyIII\Providers
|
||||
*/
|
||||
class ConfigServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
/**
|
||||
* Overwrite any vendor / package configuration.
|
||||
*
|
||||
* This service provider is intended to provide a convenient location for you
|
||||
* to overwrite any "vendor" or package configuration that you may want to
|
||||
* modify before the application handles the incoming request / command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
config(
|
||||
[
|
||||
//
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
122
app/Providers/EventServiceProvider.php
Normal file
122
app/Providers/EventServiceProvider.php
Normal file
@ -0,0 +1,122 @@
|
||||
<?php namespace FireflyIII\Providers;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use FireflyIII\Support\Facades\Navigation;
|
||||
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
|
||||
|
||||
/**
|
||||
* Class EventServiceProvider
|
||||
*
|
||||
* @package FireflyIII\Providers
|
||||
*/
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
/**
|
||||
* The event handler mappings for the application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $listen
|
||||
= [
|
||||
'event.name' => [
|
||||
'EventListener',
|
||||
],
|
||||
'App\Events\JournalDeleted' => [
|
||||
'App\Handlers\Events\JournalDeletedHandler@handle',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any other events for your application.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Events\Dispatcher $events
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot(DispatcherContract $events)
|
||||
{
|
||||
parent::boot($events);
|
||||
|
||||
TransactionJournal::deleted(
|
||||
function (TransactionJournal $journal) {
|
||||
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($journal->transactions()->get() as $transaction) {
|
||||
$transaction->delete();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
Account::deleted(
|
||||
function (Account $account) {
|
||||
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($account->transactions()->get() as $transaction) {
|
||||
$journal = $transaction->transactionJournal()->first();
|
||||
$journal->delete();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
PiggyBank::created(function(PiggyBank $piggyBank) {
|
||||
$repetition = new PiggyBankRepetition;
|
||||
$repetition->piggyBank()->associate($piggyBank);
|
||||
$repetition->startdate = $piggyBank->startdate;
|
||||
$repetition->targetdate = $piggyBank->targetdate;
|
||||
$repetition->currentamount = 0;
|
||||
$repetition->save();
|
||||
});
|
||||
|
||||
BudgetLimit::saved(
|
||||
function (BudgetLimit $budgetLimit) {
|
||||
|
||||
$end = Navigation::addPeriod(clone $budgetLimit->startdate, $budgetLimit->repeat_freq, 0);
|
||||
$end->subDay();
|
||||
|
||||
$set = $budgetLimit->limitrepetitions()->where('startdate', $budgetLimit->startdate->format('Y-m-d'))->where('enddate', $end->format('Y-m-d'))
|
||||
->get();
|
||||
/*
|
||||
* Create new LimitRepetition:
|
||||
*/
|
||||
if ($set->count() == 0) {
|
||||
|
||||
$repetition = new LimitRepetition;
|
||||
$repetition->startdate = $budgetLimit->startdate;
|
||||
$repetition->enddate = $end;
|
||||
$repetition->amount = $budgetLimit->amount;
|
||||
$repetition->budgetLimit()->associate($budgetLimit);
|
||||
|
||||
try {
|
||||
$repetition->save();
|
||||
} catch (QueryException $e) {
|
||||
\Log::error('Trying to save new LimitRepetition failed!');
|
||||
\Log::error($e->getMessage());
|
||||
}
|
||||
} else {
|
||||
if ($set->count() == 1) {
|
||||
/*
|
||||
* Update existing one.
|
||||
*/
|
||||
$repetition = $set->first();
|
||||
$repetition->amount = $budgetLimit->amount;
|
||||
$repetition->save();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
72
app/Providers/FireflyServiceProvider.php
Normal file
72
app/Providers/FireflyServiceProvider.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Providers;
|
||||
|
||||
use FireflyIII\Support\Amount;
|
||||
use FireflyIII\Support\ExpandedForm;
|
||||
use FireflyIII\Support\Navigation;
|
||||
use FireflyIII\Support\Preferences;
|
||||
use FireflyIII\Support\Steam;
|
||||
use FireflyIII\Validation\FireflyValidator;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Validator;
|
||||
|
||||
/**
|
||||
* Class FireflyServiceProvider
|
||||
*
|
||||
* @package FireflyIII\Providers
|
||||
*/
|
||||
class FireflyServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function boot()
|
||||
{
|
||||
Validator::resolver(
|
||||
function ($translator, $data, $rules, $messages) {
|
||||
return new FireflyValidator($translator, $data, $rules, $messages);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function register()
|
||||
{
|
||||
$this->app->bind(
|
||||
'preferences', function () {
|
||||
return new Preferences;
|
||||
}
|
||||
);
|
||||
$this->app->bind(
|
||||
'navigation', function () {
|
||||
return new Navigation;
|
||||
}
|
||||
);
|
||||
$this->app->bind(
|
||||
'amount', function () {
|
||||
return new Amount;
|
||||
}
|
||||
);
|
||||
|
||||
$this->app->bind(
|
||||
'steam', function () {
|
||||
return new Steam;
|
||||
}
|
||||
);
|
||||
$this->app->bind(
|
||||
'expandedform', function () {
|
||||
return new ExpandedForm;
|
||||
}
|
||||
);
|
||||
|
||||
$this->app->bind('FireflyIII\Repositories\Account\AccountRepositoryInterface', 'FireflyIII\Repositories\Account\AccountRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Budget\BudgetRepositoryInterface', 'FireflyIII\Repositories\Budget\BudgetRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Category\CategoryRepositoryInterface', 'FireflyIII\Repositories\Category\CategoryRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Journal\JournalRepositoryInterface', 'FireflyIII\Repositories\Journal\JournalRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\Bill\BillRepositoryInterface', 'FireflyIII\Repositories\Bill\BillRepository');
|
||||
$this->app->bind('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface', 'FireflyIII\Repositories\PiggyBank\PiggyBankRepository');
|
||||
$this->app->bind('FireflyIII\Support\Search\SearchInterface', 'FireflyIII\Support\Search\Search');
|
||||
|
||||
$this->app->bind('FireflyIII\Helpers\Report\ReportHelperInterface', 'FireflyIII\Helpers\Report\ReportHelper');
|
||||
$this->app->bind('FireflyIII\Helpers\Report\ReportQueryInterface', 'FireflyIII\Helpers\Report\ReportQuery');
|
||||
|
||||
}
|
||||
|
||||
}
|
70
app/Providers/RouteServiceProvider.php
Normal file
70
app/Providers/RouteServiceProvider.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php namespace FireflyIII\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Router;
|
||||
|
||||
/**
|
||||
* Class RouteServiceProvider
|
||||
*
|
||||
* @package FireflyIII\Providers
|
||||
*/
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
/**
|
||||
* This namespace is applied to the controller routes in your routes file.
|
||||
*
|
||||
* In addition, it is set as the URL generator's root namespace.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = 'FireflyIII\Http\Controllers';
|
||||
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, etc.
|
||||
*
|
||||
* @param \Illuminate\Routing\Router $router
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot(Router $router)
|
||||
{
|
||||
parent::boot($router);
|
||||
|
||||
$router->before(
|
||||
function (Request $request) {
|
||||
|
||||
// put IP in session if not already there.
|
||||
|
||||
$reminders = [];
|
||||
|
||||
if ($request->user()) {
|
||||
//Filter::setSessionDateRange();
|
||||
//Reminders::updateReminders();
|
||||
//Steam::removeEmptyBudgetLimits();
|
||||
//$reminders = Reminders::getReminders();
|
||||
}
|
||||
// View::share('reminders', $reminders);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the routes for the application.
|
||||
*
|
||||
* @param \Illuminate\Routing\Router $router
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function map(Router $router)
|
||||
{
|
||||
$router->group(
|
||||
['namespace' => $this->namespace], function ($router) {
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
require app_path('Http/routes.php');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
28
app/Providers/TestingServiceProvider.php
Normal file
28
app/Providers/TestingServiceProvider.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Providers;
|
||||
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
/**
|
||||
* Class TestingServiceProvider
|
||||
*
|
||||
* @package FireflyIII\Providers
|
||||
*/
|
||||
class TestingServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
if ($this->app->environment() == 'testing') {
|
||||
$this->app['config']['session.driver'] = 'native';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
330
app/Repositories/Account/AccountRepository.php
Normal file
330
app/Repositories/Account/AccountRepository.php
Normal file
@ -0,0 +1,330 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Repositories\Account;
|
||||
|
||||
use App;
|
||||
use Auth;
|
||||
use Carbon\Carbon;
|
||||
use Config;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountMeta;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Log;
|
||||
use Session;
|
||||
|
||||
/**
|
||||
* Class AccountRepository
|
||||
*
|
||||
* @package FireflyIII\Repositories\Account
|
||||
*/
|
||||
class AccountRepository implements AccountRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function destroy(Account $account)
|
||||
{
|
||||
$account->delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param int $page
|
||||
* @param string $range
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getJournals(Account $account, $page, $range = 'session')
|
||||
{
|
||||
$offset = $page * 50;
|
||||
$query = Auth::user()
|
||||
->transactionJournals()
|
||||
->withRelevantData()
|
||||
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||
->where('transactions.account_id', $account->id)
|
||||
->orderBy('date', 'DESC');
|
||||
|
||||
if ($range == 'session') {
|
||||
$query->before(Session::get('end', Carbon::now()->startOfMonth()));
|
||||
$query->after(Session::get('start', Carbon::now()->startOfMonth()));
|
||||
}
|
||||
$count = $query->count();
|
||||
$set = $query->take(50)->offset($offset)->get(['transaction_journals.*']);
|
||||
$paginator = new LengthAwarePaginator($set, $count, 50, $page);
|
||||
|
||||
return $paginator;
|
||||
|
||||
//return Paginator::make($items, $count, 50);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return TransactionJournal|null
|
||||
*/
|
||||
public function openingBalanceTransaction(Account $account)
|
||||
{
|
||||
return TransactionJournal::accountIs($account)
|
||||
->orderBy('transaction_journals.date', 'ASC')
|
||||
->orderBy('created_at', 'ASC')
|
||||
->first(['transaction_journals.*']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account;
|
||||
*/
|
||||
public function store(array $data)
|
||||
{
|
||||
$newAccount = $this->_store($data);
|
||||
$this->_storeMetadata($newAccount, $data);
|
||||
|
||||
|
||||
// continue with the opposing account:
|
||||
if ($data['openingBalance'] != 0) {
|
||||
$type = $data['openingBalance'] < 0 ? 'expense' : 'revenue';
|
||||
$opposingData = [
|
||||
'user' => $data['user'],
|
||||
'accountType' => $type,
|
||||
'name' => $data['name'] . ' initial balance',
|
||||
'active' => false,
|
||||
];
|
||||
$opposing = $this->_store($opposingData);
|
||||
$this->_storeInitialBalance($newAccount, $opposing, $data);
|
||||
|
||||
}
|
||||
|
||||
return $newAccount;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*/
|
||||
public function update(Account $account, array $data)
|
||||
{
|
||||
// update the account:
|
||||
$account->name = $data['name'];
|
||||
$account->active = $data['active'] == '1' ? true : false;
|
||||
$account->save();
|
||||
|
||||
// update meta data:
|
||||
/** @var AccountMeta $meta */
|
||||
foreach ($account->accountMeta()->get() as $meta) {
|
||||
if ($meta->name == 'accountRole') {
|
||||
$meta->data = $data['accountRole'];
|
||||
$meta->save();
|
||||
}
|
||||
}
|
||||
|
||||
$openingBalance = $this->openingBalanceTransaction($account);
|
||||
|
||||
// if has openingbalance?
|
||||
if ($data['openingBalance'] != 0) {
|
||||
// if opening balance, do an update:
|
||||
if ($openingBalance) {
|
||||
// update existing opening balance.
|
||||
$this->_updateInitialBalance($account, $openingBalance, $data);
|
||||
} else {
|
||||
// create new opening balance.
|
||||
$type = $data['openingBalance'] < 0 ? 'expense' : 'revenue';
|
||||
$opposingData = [
|
||||
'user' => $data['user'],
|
||||
'accountType' => $type,
|
||||
'name' => $data['name'] . ' initial balance',
|
||||
'active' => false,
|
||||
];
|
||||
$opposing = $this->_store($opposingData);
|
||||
$this->_storeInitialBalance($account, $opposing, $data);
|
||||
}
|
||||
|
||||
} else {
|
||||
// opening balance is zero, should we delete it?
|
||||
if ($openingBalance) {
|
||||
// delete existing opening balance.
|
||||
$openingBalance->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
protected function _store(array $data)
|
||||
{
|
||||
$type = Config::get('firefly.accountTypeByIdentifier.' . $data['accountType']);
|
||||
$accountType = AccountType::whereType($type)->first();
|
||||
$newAccount = new Account(
|
||||
[
|
||||
'user_id' => $data['user'],
|
||||
'account_type_id' => $accountType->id,
|
||||
'name' => $data['name'],
|
||||
'active' => $data['active'] === true ? true : false,
|
||||
]
|
||||
);
|
||||
if (!$newAccount->isValid()) {
|
||||
// does the account already exist?
|
||||
$existingAccount = Account::where('user_id', $data['user'])->where('account_type_id', $accountType->id)->where('name', $data['name'])->first();
|
||||
if (!$existingAccount) {
|
||||
Log::error('Account create error: ' . $newAccount->getErrors()->toJson());
|
||||
var_dump($newAccount->getErrors()->toArray());
|
||||
}
|
||||
$newAccount = $existingAccount;
|
||||
}
|
||||
$newAccount->save();
|
||||
|
||||
return $newAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*/
|
||||
protected function _storeMetadata(Account $account, array $data)
|
||||
{
|
||||
$metaData = new AccountMeta(
|
||||
[
|
||||
'account_id' => $account->id,
|
||||
'name' => 'accountRole',
|
||||
'data' => $data['accountRole']
|
||||
]
|
||||
);
|
||||
if (!$metaData->isValid()) {
|
||||
App::abort(500);
|
||||
}
|
||||
$metaData->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param Account $opposing
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
protected function _storeInitialBalance(Account $account, Account $opposing, array $data)
|
||||
{
|
||||
$type = $data['openingBalance'] < 0 ? 'Withdrawal' : 'Deposit';
|
||||
$transactionType = TransactionType::whereType($type)->first();
|
||||
|
||||
$journal = new TransactionJournal(
|
||||
[
|
||||
'user_id' => $data['user'],
|
||||
'transaction_type_id' => $transactionType->id,
|
||||
'bill_id' => null,
|
||||
'transaction_currency_id' => $data['openingBalanceCurrency'],
|
||||
'description' => 'Initial balance for "' . $account->name . '"',
|
||||
'completed' => true,
|
||||
'date' => $data['openingBalanceDate'],
|
||||
'encrypted' => true
|
||||
]
|
||||
);
|
||||
if (!$journal->isValid()) {
|
||||
App::abort(500);
|
||||
}
|
||||
$journal->save();
|
||||
|
||||
|
||||
if ($data['openingBalance'] < 0) {
|
||||
$firstAccount = $opposing;
|
||||
$secondAccount = $account;
|
||||
$firstAmount = $data['openingBalance'] * -1;
|
||||
$secondAmount = $data['openingBalance'];
|
||||
} else {
|
||||
$firstAccount = $account;
|
||||
$secondAccount = $opposing;
|
||||
$firstAmount = $data['openingBalance'];
|
||||
$secondAmount = $data['openingBalance'] * -1;
|
||||
}
|
||||
|
||||
// first transaction: from
|
||||
$one = new Transaction(
|
||||
[
|
||||
'account_id' => $firstAccount->id,
|
||||
'transaction_journal_id' => $journal->id,
|
||||
'amount' => $firstAmount
|
||||
]
|
||||
);
|
||||
if (!$one->isValid()) {
|
||||
App::abort(500);
|
||||
}
|
||||
$one->save();
|
||||
|
||||
// second transaction: to
|
||||
$two = new Transaction(
|
||||
[
|
||||
'account_id' => $secondAccount->id,
|
||||
'transaction_journal_id' => $journal->id,
|
||||
'amount' => $secondAmount
|
||||
]
|
||||
);
|
||||
if (!$two->isValid()) {
|
||||
App::abort(500);
|
||||
}
|
||||
$two->save();
|
||||
|
||||
return $journal;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param TransactionJournal $journal
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
protected function _updateInitialBalance(Account $account, TransactionJournal $journal, array $data)
|
||||
{
|
||||
$journal->date = $data['openingBalanceDate'];
|
||||
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($journal->transactions()->get() as $transaction) {
|
||||
if ($account->id == $transaction->account_id) {
|
||||
$transaction->amount = $data['openingBalance'];
|
||||
$transaction->save();
|
||||
}
|
||||
if ($account->id != $transaction->account_id) {
|
||||
$transaction->amount = $data['openingBalance'] * -1;
|
||||
$transaction->save();
|
||||
}
|
||||
}
|
||||
|
||||
return $journal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function leftOnAccount(Account $account)
|
||||
{
|
||||
$balance = \Steam::balance($account);
|
||||
/** @var PiggyBank $p */
|
||||
foreach ($account->piggybanks()->get() as $p) {
|
||||
$balance -= $p->currentRelevantRep()->currentamount;
|
||||
}
|
||||
|
||||
return $balance;
|
||||
|
||||
}
|
||||
}
|
59
app/Repositories/Account/AccountRepositoryInterface.php
Normal file
59
app/Repositories/Account/AccountRepositoryInterface.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Repositories\Account;
|
||||
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
|
||||
/**
|
||||
* Interface AccountRepositoryInterface
|
||||
*
|
||||
* @package FireflyIII\Repositories\Account
|
||||
*/
|
||||
interface AccountRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function destroy(Account $account);
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param int $page
|
||||
* @param string $range
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getJournals(Account $account, $page, $range = 'session');
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return TransactionJournal|null
|
||||
*/
|
||||
public function openingBalanceTransaction(Account $account);
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
public function store(array $data);
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
*
|
||||
* @return Account
|
||||
*/
|
||||
public function update(Account $account, array $data);
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function leftOnAccount(Account $account);
|
||||
}
|
198
app/Repositories/Bill/BillRepository.php
Normal file
198
app/Repositories/Bill/BillRepository.php
Normal file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: sander
|
||||
* Date: 25/02/15
|
||||
* Time: 07:40
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Repositories\Bill;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Navigation;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class BillRepository
|
||||
*
|
||||
* @package FireflyIII\Repositories\Bill
|
||||
*/
|
||||
class BillRepository implements BillRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return Carbon
|
||||
*/
|
||||
public function nextExpectedMatch(Bill $bill)
|
||||
{
|
||||
$finalDate = null;
|
||||
if ($bill->active == 0) {
|
||||
return $finalDate;
|
||||
}
|
||||
|
||||
/*
|
||||
* $today is the start of the next period, to make sure FF3 won't miss anything
|
||||
* when the current period has a transaction journal.
|
||||
*/
|
||||
$today = Navigation::addPeriod(new Carbon, $bill->repeat_freq, 0);
|
||||
|
||||
$skip = $bill->skip + 1;
|
||||
$start = Navigation::startOfPeriod(new Carbon, $bill->repeat_freq);
|
||||
/*
|
||||
* go back exactly one month/week/etc because FF3 does not care about 'next'
|
||||
* bills if they're too far into the past.
|
||||
*/
|
||||
|
||||
$counter = 0;
|
||||
while ($start <= $today) {
|
||||
if (($counter % $skip) == 0) {
|
||||
// do something.
|
||||
$end = Navigation::endOfPeriod(clone $start, $bill->repeat_freq);
|
||||
$journalCount = $bill->transactionjournals()->before($end)->after($start)->count();
|
||||
if ($journalCount == 0) {
|
||||
$finalDate = clone $start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// add period for next round!
|
||||
$start = Navigation::addPeriod($start, $bill->repeat_freq, 0);
|
||||
$counter++;
|
||||
}
|
||||
|
||||
return $finalDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function scan(Bill $bill, TransactionJournal $journal)
|
||||
{
|
||||
/*
|
||||
* Match words.
|
||||
*/
|
||||
$wordMatch = false;
|
||||
$matches = explode(',', $bill->match);
|
||||
$description = strtolower($journal->description);
|
||||
Log::debug('Now scanning ' . $description);
|
||||
|
||||
/*
|
||||
* Attach expense account to description for more narrow matching.
|
||||
*/
|
||||
if (count($journal->transactions) < 2) {
|
||||
$transactions = $journal->transactions()->get();
|
||||
} else {
|
||||
$transactions = $journal->transactions;
|
||||
}
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
/** @var Account $account */
|
||||
$account = $transaction->account()->first();
|
||||
/** @var AccountType $type */
|
||||
$type = $account->accountType()->first();
|
||||
if ($type->type == 'Expense account' || $type->type == 'Beneficiary account') {
|
||||
$description .= ' ' . strtolower($account->name);
|
||||
}
|
||||
}
|
||||
Log::debug('Final description: ' . $description);
|
||||
Log::debug('Matches searched: ' . join(':', $matches));
|
||||
|
||||
$count = 0;
|
||||
foreach ($matches as $word) {
|
||||
if (!(strpos($description, strtolower($word)) === false)) {
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
if ($count >= count($matches)) {
|
||||
$wordMatch = true;
|
||||
Log::debug('word match is true');
|
||||
} else {
|
||||
Log::debug('Count: ' . $count.', count(matches): ' . count($matches));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Match amount.
|
||||
*/
|
||||
|
||||
$amountMatch = false;
|
||||
if (count($transactions) > 1) {
|
||||
|
||||
$amount = max(floatval($transactions[0]->amount), floatval($transactions[1]->amount));
|
||||
$min = floatval($bill->amount_min);
|
||||
$max = floatval($bill->amount_max);
|
||||
if ($amount >= $min && $amount <= $max) {
|
||||
$amountMatch = true;
|
||||
Log::debug('Amount match is true!');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If both, update!
|
||||
*/
|
||||
if ($wordMatch && $amountMatch) {
|
||||
Log::debug('TOTAL match is true!');
|
||||
$journal->bill()->associate($bill);
|
||||
$journal->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Bill
|
||||
*/
|
||||
public function store(array $data)
|
||||
{
|
||||
|
||||
|
||||
$bill = Bill::create(
|
||||
[
|
||||
'name' => $data['name'],
|
||||
'match' => $data['match'],
|
||||
'amount_min' => $data['amount_min'],
|
||||
'user_id' => $data['user'],
|
||||
'amount_max' => $data['amount_max'],
|
||||
'date' => $data['date'],
|
||||
'repeat_freq' => $data['repeat_freq'],
|
||||
'skip' => $data['skip'],
|
||||
'automatch' => $data['automatch'],
|
||||
'active' => $data['active'],
|
||||
|
||||
]
|
||||
);
|
||||
|
||||
return $bill;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
* @param array $data
|
||||
*
|
||||
* @return Bill|static
|
||||
*/
|
||||
public function update(Bill $bill, array $data)
|
||||
{
|
||||
|
||||
|
||||
$bill->name = $data['name'];
|
||||
$bill->match = $data['match'];
|
||||
$bill->amount_min = $data['amount_min'];
|
||||
$bill->amount_max = $data['amount_max'];
|
||||
$bill->date = $data['date'];
|
||||
$bill->repeat_freq = $data['repeat_freq'];
|
||||
$bill->skip = $data['skip'];
|
||||
$bill->automatch = $data['automatch'];
|
||||
$bill->active = $data['active'];
|
||||
$bill->save();
|
||||
|
||||
return $bill;
|
||||
}
|
||||
}
|
51
app/Repositories/Bill/BillRepositoryInterface.php
Normal file
51
app/Repositories/Bill/BillRepositoryInterface.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: sander
|
||||
* Date: 25/02/15
|
||||
* Time: 07:40
|
||||
*/
|
||||
|
||||
namespace FireflyIII\Repositories\Bill;
|
||||
|
||||
use FireflyIII\Models\Bill;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
|
||||
/**
|
||||
* Interface BillRepositoryInterface
|
||||
*
|
||||
* @package FireflyIII\Repositories\Bill
|
||||
*/
|
||||
interface BillRepositoryInterface {
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
*
|
||||
* @return Carbon|null
|
||||
*/
|
||||
public function nextExpectedMatch(Bill $bill);
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Bill
|
||||
*/
|
||||
public function store(array $data);
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
* @param array $data
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function update(Bill $bill, array $data);
|
||||
|
||||
/**
|
||||
* @param Bill $bill
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function scan(Bill $bill, TransactionJournal $journal);
|
||||
|
||||
}
|
142
app/Repositories/Budget/BudgetRepository.php
Normal file
142
app/Repositories/Budget/BudgetRepository.php
Normal file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Repositories\Budget;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\BudgetLimit;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
/**
|
||||
* Class BudgetRepository
|
||||
*
|
||||
* @package FireflyIII\Repositories\Budget
|
||||
*/
|
||||
class BudgetRepository implements BudgetRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function destroy(Budget $budget)
|
||||
{
|
||||
$budget->delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the transaction journals for a limit, possibly limited by a limit repetition.
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @param LimitRepetition $repetition
|
||||
* @param int $take
|
||||
*
|
||||
* @return \Illuminate\Pagination\Paginator
|
||||
*/
|
||||
public function getJournals(Budget $budget, LimitRepetition $repetition = null, $take = 50)
|
||||
{
|
||||
$offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $take : 0;
|
||||
|
||||
|
||||
$setQuery = $budget->transactionJournals()->withRelevantData()->take($take)->offset($offset)->orderBy('date', 'DESC');
|
||||
$countQuery = $budget->transactionJournals();
|
||||
|
||||
|
||||
if (!is_null($repetition->id)) {
|
||||
$setQuery->after($repetition->startdate)->before($repetition->enddate);
|
||||
$countQuery->after($repetition->startdate)->before($repetition->enddate);
|
||||
}
|
||||
|
||||
|
||||
$set = $setQuery->get(['transaction_journals.*']);
|
||||
$count = $countQuery->count();
|
||||
return new LengthAwarePaginator($set, $count, $take, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function spentInMonth(Budget $budget, Carbon $date)
|
||||
{
|
||||
$end = clone $date;
|
||||
$date->startOfMonth();
|
||||
$end->endOfMonth();
|
||||
$sum = floatval($budget->transactionjournals()->before($end)->after($date)->lessThan(0)->sum('amount')) * -1;
|
||||
|
||||
return $sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Budget
|
||||
*/
|
||||
public function store(array $data)
|
||||
{
|
||||
$newBudget = new Budget(
|
||||
[
|
||||
'user_id' => $data['user'],
|
||||
'name' => $data['name'],
|
||||
]
|
||||
);
|
||||
$newBudget->save();
|
||||
|
||||
return $newBudget;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
* @param array $data
|
||||
*
|
||||
* @return Budget
|
||||
*/
|
||||
public function update(Budget $budget, array $data)
|
||||
{
|
||||
// update the account:
|
||||
$budget->name = $data['name'];
|
||||
$budget->save();
|
||||
|
||||
return $budget;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
* @param Carbon $date
|
||||
* @param $amount
|
||||
*
|
||||
* @return LimitRepetition|null
|
||||
*/
|
||||
public function updateLimitAmount(Budget $budget, Carbon $date, $amount)
|
||||
{
|
||||
/** @var BudgetLimit $limit */
|
||||
$limit = $budget->limitrepetitions()->where('limit_repetitions.startdate', $date)->first(['limit_repetitions.*']);
|
||||
if (!$limit) {
|
||||
// create one!
|
||||
$limit = new BudgetLimit;
|
||||
$limit->budget()->associate($budget);
|
||||
$limit->startdate = $date;
|
||||
$limit->amount = $amount;
|
||||
$limit->repeat_freq = 'monthly';
|
||||
$limit->repeats = 0;
|
||||
$limit->save();
|
||||
} else {
|
||||
if ($amount > 0) {
|
||||
$limit->amount = $amount;
|
||||
$limit->save();
|
||||
} else {
|
||||
$limit->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return $limit;
|
||||
|
||||
|
||||
}
|
||||
}
|
66
app/Repositories/Budget/BudgetRepositoryInterface.php
Normal file
66
app/Repositories/Budget/BudgetRepositoryInterface.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Repositories\Budget;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\LimitRepetition;
|
||||
|
||||
/**
|
||||
* Interface BudgetRepositoryInterface
|
||||
*
|
||||
* @package FireflyIII\Repositories\Budget
|
||||
*/
|
||||
interface BudgetRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param Budget $budget
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function destroy(Budget $budget);
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function spentInMonth(Budget $budget, Carbon $date);
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
* @param Carbon $date
|
||||
* @param $amount
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function updateLimitAmount(Budget $budget, Carbon $date, $amount);
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Budget
|
||||
*/
|
||||
public function store(array $data);
|
||||
|
||||
/**
|
||||
* @param Budget $budget
|
||||
* @param array $data
|
||||
*
|
||||
* @return Budget
|
||||
*/
|
||||
public function update(Budget $budget, array $data);
|
||||
|
||||
/**
|
||||
* Returns all the transaction journals for a limit, possibly limited by a limit repetition.
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @param LimitRepetition $repetition
|
||||
* @param int $take
|
||||
*
|
||||
* @return \Illuminate\Pagination\Paginator
|
||||
*/
|
||||
public function getJournals(Budget $budget, LimitRepetition $repetition = null, $take = 50);
|
||||
|
||||
}
|
61
app/Repositories/Category/CategoryRepository.php
Normal file
61
app/Repositories/Category/CategoryRepository.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Repositories\Category;
|
||||
|
||||
use FireflyIII\Models\Category;
|
||||
|
||||
/**
|
||||
* Class CategoryRepository
|
||||
*
|
||||
* @package FireflyIII\Repositories\Category
|
||||
*/
|
||||
class CategoryRepository implements CategoryRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function destroy(Category $category)
|
||||
{
|
||||
$category->delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Category
|
||||
*/
|
||||
public function store(array $data)
|
||||
{
|
||||
$newCategory = new Category(
|
||||
[
|
||||
'user_id' => $data['user'],
|
||||
'name' => $data['name'],
|
||||
]
|
||||
);
|
||||
$newCategory->save();
|
||||
|
||||
return $newCategory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param array $data
|
||||
*
|
||||
* @return Category
|
||||
*/
|
||||
public function update(Category $category, array $data)
|
||||
{
|
||||
// update the account:
|
||||
$category->name = $data['name'];
|
||||
$category->save();
|
||||
|
||||
return $category;
|
||||
}
|
||||
|
||||
}
|
36
app/Repositories/Category/CategoryRepositoryInterface.php
Normal file
36
app/Repositories/Category/CategoryRepositoryInterface.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Repositories\Category;
|
||||
|
||||
use FireflyIII\Models\Category;
|
||||
|
||||
/**
|
||||
* Interface CategoryRepositoryInterface
|
||||
*
|
||||
* @package FireflyIII\Repositories\Category
|
||||
*/
|
||||
interface CategoryRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param Category $category
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function destroy(Category $category);
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return Category
|
||||
*/
|
||||
public function store(array $data);
|
||||
|
||||
/**
|
||||
* @param Category $category
|
||||
* @param array $data
|
||||
*
|
||||
* @return Category
|
||||
*/
|
||||
public function update(Category $category, array $data);
|
||||
|
||||
}
|
287
app/Repositories/Journal/JournalRepository.php
Normal file
287
app/Repositories/Journal/JournalRepository.php
Normal file
@ -0,0 +1,287 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Repositories\Journal;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class JournalRepository
|
||||
*
|
||||
* @package FireflyIII\Repositories\Journal
|
||||
*/
|
||||
class JournalRepository implements JournalRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the account_id, which is the asset account that paid for the transaction.
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAssetAccount(TransactionJournal $journal)
|
||||
{
|
||||
$positive = true; // the asset account is in the transaction with the positive amount.
|
||||
switch ($journal->transactionType->type) {
|
||||
case 'Withdrawal':
|
||||
$positive = false;
|
||||
break;
|
||||
}
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($journal->transactions()->get() as $transaction) {
|
||||
if (floatval($transaction->amount) > 0 && $positive === true) {
|
||||
return $transaction->account_id;
|
||||
}
|
||||
if (floatval($transaction->amount) < 0 && $positive === false) {
|
||||
return $transaction->account_id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $journal->transactions()->first()->account_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $query
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchRelated($query, TransactionJournal $journal)
|
||||
{
|
||||
$start = clone $journal->date;
|
||||
$end = clone $journal->date;
|
||||
$start->startOfMonth();
|
||||
$end->endOfMonth();
|
||||
|
||||
// get already related transactions:
|
||||
$exclude = [$journal->id];
|
||||
foreach ($journal->transactiongroups()->get() as $group) {
|
||||
foreach ($group->transactionjournals()->get() as $current) {
|
||||
$exclude[] = $current->id;
|
||||
}
|
||||
}
|
||||
$exclude = array_unique($exclude);
|
||||
|
||||
/** @var Collection $collection */
|
||||
$collection = Auth::user()->transactionjournals()
|
||||
->withRelevantData()
|
||||
->before($end)->after($start)->where('encrypted', 0)
|
||||
->whereNotIn('id', $exclude)
|
||||
->where('description', 'LIKE', '%' . $query . '%')
|
||||
->get();
|
||||
|
||||
// manually search encrypted entries:
|
||||
/** @var Collection $encryptedCollection */
|
||||
$encryptedCollection = Auth::user()->transactionjournals()
|
||||
->withRelevantData()
|
||||
->before($end)->after($start)
|
||||
->where('encrypted', 1)
|
||||
->whereNotIn('id', $exclude)
|
||||
->get();
|
||||
$encrypted = $encryptedCollection->filter(
|
||||
function (TransactionJournal $journal) use ($query) {
|
||||
$strPos = strpos(strtolower($journal->description), strtolower($query));
|
||||
if ($strPos !== false) {
|
||||
return $journal;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
return $collection->merge($encrypted);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
public function store(array $data)
|
||||
{
|
||||
// find transaction type.
|
||||
$transactionType = TransactionType::where('type', ucfirst($data['what']))->first();
|
||||
|
||||
// store actual journal.
|
||||
$journal = new TransactionJournal(
|
||||
[
|
||||
'user_id' => $data['user'],
|
||||
'transaction_type_id' => $transactionType->id,
|
||||
'transaction_currency_id' => $data['amount_currency_id'],
|
||||
'description' => $data['description'],
|
||||
'completed' => 0,
|
||||
'date' => $data['date'],
|
||||
]
|
||||
);
|
||||
$journal->save();
|
||||
|
||||
|
||||
// store or get category
|
||||
if (strlen($data['category']) > 0) {
|
||||
$category = Category::firstOrCreate(['name' => $data['category'], 'user_id' => $data['user']]);
|
||||
$journal->categories()->save($category);
|
||||
}
|
||||
|
||||
// store or get budget
|
||||
if (intval($data['budget_id']) > 0) {
|
||||
$budget = Budget::find($data['budget_id']);
|
||||
$journal->budgets()->save($budget);
|
||||
}
|
||||
|
||||
// store accounts (depends on type)
|
||||
switch ($transactionType->type) {
|
||||
case 'Withdrawal':
|
||||
|
||||
$from = Account::find($data['account_id']);
|
||||
|
||||
if (strlen($data['expense_account']) > 0) {
|
||||
$toType = AccountType::where('type', 'Expense account')->first();
|
||||
$to = Account::firstOrCreate(
|
||||
['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => $data['expense_account'], 'active' => 1]
|
||||
);
|
||||
} else {
|
||||
$toType = AccountType::where('type', 'Cash account')->first();
|
||||
$to = Account::firstOrCreate(['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => 'Cash account', 'active' => 1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Deposit':
|
||||
$to = Account::find($data['account_id']);
|
||||
|
||||
if (strlen($data['revenue_account']) > 0) {
|
||||
$fromType = AccountType::where('type', 'Revenue account')->first();
|
||||
$from = Account::firstOrCreate(
|
||||
['user_id' => $data['user'], 'account_type_id' => $fromType->id, 'name' => $data['revenue_account'], 'active' => 1]
|
||||
);
|
||||
} else {
|
||||
$toType = AccountType::where('type', 'Cash account')->first();
|
||||
$from = Account::firstOrCreate(['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => 'Cash account', 'active' => 1]);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'Transfer':
|
||||
$from = Account::find($data['account_from_id']);
|
||||
$to = Account::find($data['account_to_id']);
|
||||
break;
|
||||
}
|
||||
|
||||
// store accompanying transactions.
|
||||
Transaction::create( // first transaction.
|
||||
[
|
||||
'account_id' => $from->id,
|
||||
'transaction_journal_id' => $journal->id,
|
||||
'amount' => $data['amount'] * -1
|
||||
]
|
||||
);
|
||||
Transaction::create( // second transaction.
|
||||
[
|
||||
'account_id' => $to->id,
|
||||
'transaction_journal_id' => $journal->id,
|
||||
'amount' => $data['amount']
|
||||
]
|
||||
);
|
||||
$journal->completed = 1;
|
||||
$journal->save();
|
||||
|
||||
return $journal;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param array $data
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function update(TransactionJournal $journal, array $data)
|
||||
{
|
||||
// update actual journal.
|
||||
$journal->transaction_currency_id = $data['amount_currency_id'];
|
||||
$journal->description = $data['description'];
|
||||
$journal->date = $data['date'];
|
||||
|
||||
|
||||
// unlink all categories, recreate them:
|
||||
$journal->categories()->detach();
|
||||
if (strlen($data['category']) > 0) {
|
||||
$category = Category::firstOrCreate(['name' => $data['category'], 'user_id' => $data['user']]);
|
||||
$journal->categories()->save($category);
|
||||
}
|
||||
|
||||
// unlink all budgets and recreate them:
|
||||
$journal->budgets()->detach();
|
||||
if (intval($data['budget_id']) > 0) {
|
||||
$budget = Budget::find($data['budget_id']);
|
||||
$journal->budgets()->save($budget);
|
||||
}
|
||||
|
||||
// store accounts (depends on type)
|
||||
switch ($journal->transactionType->type) {
|
||||
case 'Withdrawal':
|
||||
|
||||
$from = Account::find($data['account_id']);
|
||||
|
||||
if (strlen($data['expense_account']) > 0) {
|
||||
$toType = AccountType::where('type', 'Expense account')->first();
|
||||
$to = Account::firstOrCreate(
|
||||
['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => $data['expense_account'], 'active' => 1]
|
||||
);
|
||||
} else {
|
||||
$toType = AccountType::where('type', 'Cash account')->first();
|
||||
$to = Account::firstOrCreate(['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => 'Cash account', 'active' => 1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Deposit':
|
||||
$to = Account::find($data['account_id']);
|
||||
|
||||
if (strlen($data['revenue_account']) > 0) {
|
||||
$fromType = AccountType::where('type', 'Revenue account')->first();
|
||||
$from = Account::firstOrCreate(
|
||||
['user_id' => $data['user'], 'account_type_id' => $fromType->id, 'name' => $data['revenue_account'], 'active' => 1]
|
||||
);
|
||||
} else {
|
||||
$toType = AccountType::where('type', 'Cash account')->first();
|
||||
$from = Account::firstOrCreate(['user_id' => $data['user'], 'account_type_id' => $toType->id, 'name' => 'Cash account', 'active' => 1]);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'Transfer':
|
||||
$from = Account::find($data['account_from_id']);
|
||||
$to = Account::find($data['account_to_id']);
|
||||
break;
|
||||
}
|
||||
|
||||
// update the from and to transaction.
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($journal->transactions()->get() as $transaction) {
|
||||
if ($transaction->account_id === $from->id) {
|
||||
// this is the from transaction, negative amount:
|
||||
$transaction->amount = $data['amount'] * -1;
|
||||
$transaction->save();
|
||||
}
|
||||
if ($transaction->account_id === $to->id) {
|
||||
$transaction->amount = $data['amount'];
|
||||
$transaction->save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$journal->save();
|
||||
|
||||
return $journal;
|
||||
}
|
||||
|
||||
}
|
47
app/Repositories/Journal/JournalRepositoryInterface.php
Normal file
47
app/Repositories/Journal/JournalRepositoryInterface.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Repositories\Journal;
|
||||
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface JournalRepositoryInterface
|
||||
*
|
||||
* @package FireflyIII\Repositories\Journal
|
||||
*/
|
||||
interface JournalRepositoryInterface
|
||||
{
|
||||
/**
|
||||
*
|
||||
* Get the account_id, which is the asset account that paid for the transaction.
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAssetAccount(TransactionJournal $journal);
|
||||
|
||||
/**
|
||||
* @param string $query
|
||||
* @param TransactionJournal $journal
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchRelated($query, TransactionJournal $journal);
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return TransactionJournal
|
||||
*/
|
||||
public function store(array $data);
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param array $data
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function update(TransactionJournal $journal, array $data);
|
||||
}
|
@ -1,21 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Database\PiggyBank;
|
||||
namespace FireflyIII\Repositories\PiggyBank;
|
||||
|
||||
|
||||
use FireflyIII\Collection\PiggyBankPart;
|
||||
use FireflyIII\Database\CommonDatabaseCallsInterface;
|
||||
use FireflyIII\Database\CUDInterface;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use Illuminate\Support\Collection;
|
||||
use Navigation;
|
||||
|
||||
/**
|
||||
* Class RepeatedExpense
|
||||
* Class PiggyBankRepository
|
||||
*
|
||||
* @package FireflyIII\Database
|
||||
* @package FireflyIII\Repositories\PiggyBank
|
||||
*/
|
||||
class RepeatedExpense extends PiggyBankShared implements CUDInterface, CommonDatabaseCallsInterface, PiggyBankInterface
|
||||
class PiggyBankRepository implements PiggyBankRepositoryInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return PiggyBank
|
||||
*/
|
||||
public function store(array $data)
|
||||
{
|
||||
|
||||
$piggyBank = PiggyBank::create($data);
|
||||
|
||||
return $piggyBank;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBank $account
|
||||
* @param array $data
|
||||
*
|
||||
* @return PiggyBank
|
||||
*/
|
||||
public function update(PiggyBank $piggyBank, array $data)
|
||||
{
|
||||
/**
|
||||
'rep_length' => $request->get('rep_length'),
|
||||
'rep_every' => intval($request->get('rep_every')),
|
||||
'rep_times' => intval($request->get('rep_times')),
|
||||
'remind_me' => intval($request->get('remind_me')) == 1 ? true : false ,
|
||||
'reminder' => $request->get('reminder'),
|
||||
*/
|
||||
|
||||
$piggyBank->name = $data['name'];
|
||||
$piggyBank->account_id = intval($data['account_id']);
|
||||
$piggyBank->targetamount = floatval($data['targetamount']);
|
||||
$piggyBank->targetdate = $data['targetdate'];
|
||||
$piggyBank->reminder = $data['reminder'];
|
||||
$piggyBank->rep_length = isset($data['rep_length']) ? $data['rep_length'] : null;
|
||||
$piggyBank->rep_every =isset($data['rep_every']) ? $data['rep_every'] : null;
|
||||
$piggyBank->rep_times = isset($data['rep_times']) ? $data['rep_times'] : null;
|
||||
$piggyBank->remind_me = isset($data['remind_me']) ? $data['remind_me'] : null;
|
||||
|
||||
$piggyBank->save();
|
||||
return $piggyBank;
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
@ -23,13 +65,13 @@ class RepeatedExpense extends PiggyBankShared implements CUDInterface, CommonDat
|
||||
* other variables this method tries to divide the piggy bank into equal parts. Each is
|
||||
* accommodated by a reminder (if everything goes to plan).
|
||||
*
|
||||
* @param \PiggyBankRepetition $repetition
|
||||
* @param PiggyBankRepetition $repetition
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function calculateParts(\PiggyBankRepetition $repetition)
|
||||
public function calculateParts(PiggyBankRepetition $repetition)
|
||||
{
|
||||
/** @var \PiggyBank $piggyBank */
|
||||
/** @var PiggyBank $piggyBank */
|
||||
$piggyBank = $repetition->piggyBank()->first();
|
||||
$bars = new Collection;
|
||||
$currentStart = clone $repetition->startdate;
|
||||
@ -44,7 +86,7 @@ class RepeatedExpense extends PiggyBankShared implements CUDInterface, CommonDat
|
||||
}
|
||||
|
||||
while ($currentStart < $repetition->targetdate) {
|
||||
$currentTarget = \DateKit::endOfX($currentStart, $piggyBank->reminder, $repetition->targetdate);
|
||||
$currentTarget = Navigation::endOfX($currentStart, $piggyBank->reminder, $repetition->targetdate);
|
||||
$entry = ['repetition' => $repetition, 'amountPerBar' => null, 'currentAmount' => floatval($repetition->currentamount),
|
||||
'cumulativeAmount' => null, 'startDate' => $currentStart, 'targetDate' => $currentTarget];
|
||||
$bars->push($this->createPiggyBankPart($entry));
|
||||
@ -84,41 +126,4 @@ class RepeatedExpense extends PiggyBankShared implements CUDInterface, CommonDat
|
||||
|
||||
return $part;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return \Eloquent
|
||||
*/
|
||||
public function store(array $data)
|
||||
{
|
||||
|
||||
$data['rep_every'] = intval($data['rep_every']);
|
||||
$data['reminder_skip'] = intval($data['reminder_skip']);
|
||||
$data['order'] = intval($data['order']);
|
||||
$data['remind_me'] = intval($data['remind_me']);
|
||||
$data['account_id'] = intval($data['account_id']);
|
||||
|
||||
|
||||
if ($data['remind_me'] == 0) {
|
||||
$data['reminder'] = null;
|
||||
}
|
||||
|
||||
$repeated = new \PiggyBank($data);
|
||||
$repeated->save();
|
||||
|
||||
return $repeated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all objects.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
return $this->getUser()->piggyBanks()->where('repeats', 1)->get();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
51
app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php
Normal file
51
app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Repositories\PiggyBank;
|
||||
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface PiggyBankRepositoryInterface
|
||||
*
|
||||
* @package FireflyIII\Repositories\PiggyBank
|
||||
*/
|
||||
interface PiggyBankRepositoryInterface {
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return PiggyBank
|
||||
*/
|
||||
public function store(array $data);
|
||||
|
||||
/**
|
||||
* @param PiggyBank $account
|
||||
* @param array $data
|
||||
*
|
||||
* @return PiggyBank
|
||||
*/
|
||||
public function update(PiggyBank $piggyBank, array $data);
|
||||
|
||||
/**
|
||||
* @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).
|
||||
*
|
||||
* @param PiggyBankRepetition $repetition
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function calculateParts(PiggyBankRepetition $repetition);
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return PiggyBankPart
|
||||
*/
|
||||
public function createPiggyBankPart(array $data);
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Collection;
|
||||
namespace FireflyIII\Repositories\PiggyBank;
|
||||
|
||||
use FireflyIII\Models\Reminder;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
|
||||
use Carbon\Carbon;
|
||||
|
||||
@ -18,10 +20,10 @@ class PiggyBankPart
|
||||
public $cumulativeAmount;
|
||||
/** @var float */
|
||||
public $currentamount;
|
||||
/** @var \Reminder */
|
||||
/** @var Reminder */
|
||||
public $reminder;
|
||||
|
||||
/** @var \PiggyBankRepetition */
|
||||
/** @var PiggyBankRepetition */
|
||||
public $repetition;
|
||||
|
||||
/** @var Carbon */
|
||||
@ -31,7 +33,7 @@ class PiggyBankPart
|
||||
public $targetdate;
|
||||
|
||||
/**
|
||||
* @return \Reminder
|
||||
* @return Reminder
|
||||
*/
|
||||
public function getReminder()
|
||||
{
|
||||
@ -45,7 +47,7 @@ class PiggyBankPart
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Reminder $reminder
|
||||
* @param Reminder $reminder
|
||||
*/
|
||||
public function setReminder($reminder)
|
||||
{
|
||||
@ -85,7 +87,7 @@ class PiggyBankPart
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \PiggyBankRepetition
|
||||
* @return PiggyBankRepetition
|
||||
*/
|
||||
public function getRepetition()
|
||||
{
|
||||
@ -93,7 +95,7 @@ class PiggyBankPart
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \PiggyBankRepetition $repetition
|
||||
* @param PiggyBankRepetition $repetition
|
||||
*/
|
||||
public function setRepetition($repetition)
|
||||
{
|
49
app/Services/Registrar.php
Normal file
49
app/Services/Registrar.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php namespace FireflyIII\Services;
|
||||
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Contracts\Auth\Registrar as RegistrarContract;
|
||||
use Validator;
|
||||
|
||||
/**
|
||||
* Class Registrar
|
||||
*
|
||||
* @package FireflyIII\Services
|
||||
*/
|
||||
class Registrar implements RegistrarContract
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function create(array $data)
|
||||
{
|
||||
return User::create(
|
||||
[
|
||||
'email' => $data['email'],
|
||||
'password' => $data['password'],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return \Illuminate\Contracts\Validation\Validator
|
||||
*/
|
||||
public function validator(array $data)
|
||||
{
|
||||
return Validator::make(
|
||||
$data, [
|
||||
'email' => 'required|email|max:255|unique:users',
|
||||
'password' => 'required|confirmed|min:6',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
133
app/Support/Amount.php
Normal file
133
app/Support/Amount.php
Normal file
@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Support;
|
||||
|
||||
use Cache;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use Preferences as Prefs;
|
||||
|
||||
/**
|
||||
* Class Amount
|
||||
*
|
||||
* @package FireflyIII\Support
|
||||
*/
|
||||
class Amount
|
||||
{
|
||||
/**
|
||||
* @param $amount
|
||||
* @param bool $coloured
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function format($amount, $coloured = true)
|
||||
{
|
||||
$currencySymbol = $this->getCurrencySymbol();
|
||||
|
||||
return $this->formatWithSymbol($currencySymbol, $amount, $coloured);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Transaction|\Transaction $transaction
|
||||
* @param bool $coloured
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatTransaction(Transaction $transaction, $coloured = true)
|
||||
{
|
||||
$symbol = $transaction->transactionJournal->transactionCurrency->symbol;
|
||||
$amount = floatval($transaction->amount);
|
||||
|
||||
return $this->formatWithSymbol($symbol, $amount, $coloured);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $symbol
|
||||
* @param float $amount
|
||||
* @param bool $coloured
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatWithSymbol($symbol, $amount, $coloured = true)
|
||||
{
|
||||
$amount = floatval($amount);
|
||||
$amount = round($amount, 2);
|
||||
$string = number_format($amount, 2, ',', '.');
|
||||
|
||||
if ($coloured === true) {
|
||||
if ($amount === 0.0) {
|
||||
return '<span style="color:#999">' . $symbol . ' ' . $string . '</span>';
|
||||
}
|
||||
if ($amount > 0) {
|
||||
return '<span class="text-success">' . $symbol . ' ' . $string . '</span>';
|
||||
}
|
||||
|
||||
return '<span class="text-danger">' . $symbol . ' ' . $string . '</span>';
|
||||
}
|
||||
|
||||
// €
|
||||
return $symbol . ' ' . $string;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrencySymbol()
|
||||
{
|
||||
if (defined('FFCURRENCYSYMBOL')) {
|
||||
return FFCURRENCYSYMBOL;
|
||||
}
|
||||
if (\Cache::has('FFCURRENCYSYMBOL')) {
|
||||
define('FFCURRENCYSYMBOL', \Cache::get('FFCURRENCYSYMBOL'));
|
||||
|
||||
return FFCURRENCYSYMBOL;
|
||||
}
|
||||
|
||||
$currencyPreference = Prefs::get('currencyPreference', 'EUR');
|
||||
$currency = TransactionCurrency::whereCode($currencyPreference->data)->first();
|
||||
|
||||
\Cache::forever('FFCURRENCYSYMBOL', $currency->symbol);
|
||||
|
||||
define('FFCURRENCYSYMBOL', $currency->symbol);
|
||||
|
||||
return $currency->symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCurrencyCode()
|
||||
{
|
||||
if (defined('FFCURRENCYCODE')) {
|
||||
return FFCURRENCYCODE;
|
||||
}
|
||||
if (Cache::has('FFCURRENCYCODE')) {
|
||||
define('FFCURRENCYCODE', Cache::get('FFCURRENCYCODE'));
|
||||
|
||||
return FFCURRENCYCODE;
|
||||
}
|
||||
|
||||
|
||||
$currencyPreference = Prefs::get('currencyPreference', 'EUR');
|
||||
$currency = TransactionCurrency::whereCode($currencyPreference->data)->first();
|
||||
|
||||
\Cache::forever('FFCURRENCYCODE', $currency->code);
|
||||
|
||||
define('FFCURRENCYCODE', $currency->code);
|
||||
|
||||
return $currency->code;
|
||||
}
|
||||
|
||||
public function getDefaultCurrency()
|
||||
{
|
||||
$currencyPreference = Prefs::get('currencyPreference', 'EUR');
|
||||
$currency = TransactionCurrency::whereCode($currencyPreference->data)->first();
|
||||
|
||||
return $currency;
|
||||
}
|
||||
}
|
317
app/Support/ExpandedForm.php
Normal file
317
app/Support/ExpandedForm.php
Normal file
@ -0,0 +1,317 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Support;
|
||||
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Input;
|
||||
use Session;
|
||||
use View;
|
||||
|
||||
/**
|
||||
* Class ExpandedForm
|
||||
*
|
||||
* @package FireflyIII\Support
|
||||
*/
|
||||
class ExpandedForm
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $value
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function integer($name, $value = null, array $options = [])
|
||||
{
|
||||
$label = $this->label($name, $options);
|
||||
$options = $this->expandOptionArray($name, $label, $options);
|
||||
$classes = $this->getHolderClasses($name);
|
||||
$value = $this->fillFieldValue($name, $value);
|
||||
$options['step'] = '1';
|
||||
$html = \View::make('form.integer', compact('classes', 'name', 'label', 'value', 'options'))->render();
|
||||
|
||||
return $html;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $value
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function tags($name, $value = null, array $options = [])
|
||||
{
|
||||
$label = $this->label($name, $options);
|
||||
$options = $this->expandOptionArray($name, $label, $options);
|
||||
$classes = $this->getHolderClasses($name);
|
||||
$value = $this->fillFieldValue($name, $value);
|
||||
$options['data-role'] = 'tagsinput';
|
||||
$html = \View::make('form.tags', compact('classes', 'name', 'label', 'value', 'options'))->render();
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $value
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function amount($name, $value = null, array $options = [])
|
||||
{
|
||||
$label = $this->label($name, $options);
|
||||
$options = $this->expandOptionArray($name, $label, $options);
|
||||
$classes = $this->getHolderClasses($name);
|
||||
$value = $this->fillFieldValue($name, $value);
|
||||
$options['step'] = 'any';
|
||||
$options['min'] = '0.01';
|
||||
$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;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $options
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function label($name, $options)
|
||||
{
|
||||
if (isset($options['label'])) {
|
||||
return $options['label'];
|
||||
}
|
||||
$labels = ['amount_min' => 'Amount (min)', 'amount_max' => 'Amount (max)', 'match' => 'Matches on', 'repeat_freq' => 'Repetition',
|
||||
'account_from_id' => 'Account from', 'account_to_id' => 'Account to', 'account_id' => 'Asset account', 'budget_id' => 'Budget'
|
||||
, 'piggy_bank_id' => 'Piggy bank'];
|
||||
|
||||
|
||||
return isset($labels[$name]) ? $labels[$name] : str_replace('_', ' ', ucfirst($name));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $label
|
||||
* @param array $options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public 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 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 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
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function balance($name, $value = null, array $options = [])
|
||||
{
|
||||
$label = $this->label($name, $options);
|
||||
$options = $this->expandOptionArray($name, $label, $options);
|
||||
$classes = $this->getHolderClasses($name);
|
||||
$value = $this->fillFieldValue($name, $value);
|
||||
$options['step'] = 'any';
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param int $value
|
||||
* @param null $checked
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function checkbox($name, $value = 1, $checked = null, $options = [])
|
||||
{
|
||||
$options['checked'] = $checked === true ? true : null;
|
||||
$label = $this->label($name, $options);
|
||||
$options = $this->expandOptionArray($name, $label, $options);
|
||||
$classes = $this->getHolderClasses($name);
|
||||
$value = $this->fillFieldValue($name, $value);
|
||||
|
||||
unset($options['placeholder'], $options['autocomplete'], $options['class']);
|
||||
|
||||
$html = View::make('form.checkbox', compact('classes', 'name', 'label', 'value', 'options'))->render();
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $value
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function date($name, $value = null, array $options = [])
|
||||
{
|
||||
$label = $this->label($name, $options);
|
||||
$options = $this->expandOptionArray($name, $label, $options);
|
||||
$classes = $this->getHolderClasses($name);
|
||||
$value = $this->fillFieldValue($name, $value);
|
||||
$html = View::make('form.date', compact('classes', 'name', 'label', 'value', 'options'))->render();
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @param bool $addEmpty
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function makeSelectList(Collection $set, $addEmpty = false)
|
||||
{
|
||||
$selectList = [];
|
||||
if ($addEmpty) {
|
||||
$selectList[0] = '(none)';
|
||||
}
|
||||
$fields = ['title', 'name', 'description'];
|
||||
/** @var \Eloquent $entry */
|
||||
foreach ($set as $entry) {
|
||||
$id = intval($entry->id);
|
||||
$title = null;
|
||||
|
||||
foreach ($fields as $field) {
|
||||
if (isset($entry->$field)) {
|
||||
$title = $entry->$field;
|
||||
}
|
||||
}
|
||||
$selectList[$id] = $title;
|
||||
}
|
||||
|
||||
return $selectList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @param $name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function optionsList($type, $name)
|
||||
{
|
||||
$previousValue = \Input::old('post_submit_action');
|
||||
$previousValue = is_null($previousValue) ? 'store' : $previousValue;
|
||||
$html = \View::make('form.options', compact('type', 'name', 'previousValue'))->render();
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param array $list
|
||||
* @param null $selected
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function select($name, array $list = [], $selected = null, array $options = [])
|
||||
{
|
||||
$label = $this->label($name, $options);
|
||||
$options = $this->expandOptionArray($name, $label, $options);
|
||||
$classes = $this->getHolderClasses($name);
|
||||
$selected = $this->fillFieldValue($name, $selected);
|
||||
$html = \View::make('form.select', compact('classes', 'name', 'label', 'selected', 'options', 'list'))->render();
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $value
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function text($name, $value = null, array $options = [])
|
||||
{
|
||||
$label = $this->label($name, $options);
|
||||
$options = $this->expandOptionArray($name, $label, $options);
|
||||
$classes = $this->getHolderClasses($name);
|
||||
$value = $this->fillFieldValue($name, $value);
|
||||
$html = View::make('form.text', compact('classes', 'name', 'label', 'value', 'options'))->render();
|
||||
|
||||
return $html;
|
||||
|
||||
}
|
||||
}
|
@ -1,19 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Shared\Facade;
|
||||
namespace FireflyIII\Support\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* Class Amount
|
||||
*
|
||||
* @package FireflyIII\Shared\Facade
|
||||
* @package FireflyIII\Support\Facades
|
||||
*/
|
||||
class Amount extends Facade
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
@ -21,4 +21,4 @@ class Amount extends Facade
|
||||
return 'amount';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
24
app/Support/Facades/ExpandedForm.php
Normal file
24
app/Support/Facades/ExpandedForm.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Support\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* Class Amount
|
||||
*
|
||||
* @package FireflyIII\Support\Facades
|
||||
*/
|
||||
class ExpandedForm extends Facade
|
||||
{
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'expandedform';
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Shared\Facade;
|
||||
namespace FireflyIII\Support\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* Class Navigation
|
||||
*
|
||||
* @package FireflyIII\Shared\Facade
|
||||
* @package FireflyIII\Support\Facades
|
||||
*/
|
||||
class Navigation extends Facade
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
@ -21,4 +21,4 @@ class Navigation extends Facade
|
||||
return 'navigation';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
24
app/Support/Facades/Preferences.php
Normal file
24
app/Support/Facades/Preferences.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Support\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* Class Preferences
|
||||
*
|
||||
* @package FireflyIII\Support\Facades
|
||||
*/
|
||||
class Preferences extends Facade
|
||||
{
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'preferences';
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Shared\Facade;
|
||||
namespace FireflyIII\Support\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* Class Steam
|
||||
*
|
||||
* @package FireflyIII\Shared\Facade
|
||||
* @package FireflyIII\Support\Facades
|
||||
*/
|
||||
class Steam extends Facade
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
@ -21,4 +21,4 @@ class Steam extends Facade
|
||||
return 'steam';
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,17 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Shared\Toolkit;
|
||||
namespace FireflyIII\Support;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Exception\FireflyException;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
|
||||
/**
|
||||
* Class Date
|
||||
* Class Navigation
|
||||
*
|
||||
* @package FireflyIII\Shared\Toolkit
|
||||
* @package FireflyIII\Support
|
||||
*/
|
||||
class Date
|
||||
class Navigation
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @param Carbon $theDate
|
||||
* @param $repeatFreq
|
||||
@ -102,14 +104,12 @@ class Date
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings("CyclomaticComplexity") // It's exactly 5. So I don't mind.
|
||||
*
|
||||
* @param Carbon $theCurrentEnd
|
||||
* @param $repeatFreq
|
||||
* @param Carbon $maxDate
|
||||
*
|
||||
* @return Carbon
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function endOfX(Carbon $theCurrentEnd, $repeatFreq, Carbon $maxDate)
|
||||
{
|
||||
@ -147,6 +147,119 @@ class Date
|
||||
return $currentEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $range
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return Carbon
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function jumpToNext($range, Carbon $date)
|
||||
{
|
||||
switch ($range) {
|
||||
case '1D':
|
||||
$date->endOfDay()->addDay();
|
||||
break;
|
||||
case '1W':
|
||||
$date->endOfWeek()->addDay()->startOfWeek();
|
||||
break;
|
||||
case '1M':
|
||||
$date->endOfMonth()->addDay()->startOfMonth();
|
||||
break;
|
||||
case '3M':
|
||||
$date->lastOfQuarter()->addDay();
|
||||
break;
|
||||
case '6M':
|
||||
if (intval($date->format('m')) >= 7) {
|
||||
$date->startOfYear()->addYear();
|
||||
} else {
|
||||
$date->startOfYear()->addMonths(6);
|
||||
}
|
||||
break;
|
||||
case '1Y':
|
||||
$date->startOfYear()->addYear();
|
||||
break;
|
||||
default:
|
||||
throw new FireflyException('Cannot do _next() on ' . $range);
|
||||
break;
|
||||
}
|
||||
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $range
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return Carbon
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function jumpToPrevious($range, Carbon $date)
|
||||
{
|
||||
$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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $range
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return string
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function periodName($range, Carbon $date)
|
||||
{
|
||||
$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('Y');
|
||||
}
|
||||
throw new FireflyException('No _periodName() for range "' . $range . '"');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $date
|
||||
* @param $repeatFrequency
|
||||
@ -214,45 +327,74 @@ class Date
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Carbon $theDate
|
||||
* @param $repeatFreq
|
||||
* @param int $subtract
|
||||
* @param $range
|
||||
* @param Carbon $start
|
||||
*
|
||||
* @return Carbon
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function subtractPeriod(Carbon $theDate, $repeatFreq, $subtract = 1)
|
||||
public function updateEndDate($range, Carbon $start)
|
||||
{
|
||||
$date = clone $theDate;
|
||||
|
||||
$functionMap = [
|
||||
'daily' => 'subDays',
|
||||
'week' => 'subWeeks',
|
||||
'weekly' => 'subWeeks',
|
||||
'month' => 'subMonths',
|
||||
'monthly' => 'subMonths',
|
||||
'year' => 'subYears',
|
||||
'yearly' => 'subYears',
|
||||
'1D' => 'endOfDay',
|
||||
'1W' => 'endOfWeek',
|
||||
'1M' => 'endOfMonth',
|
||||
'3M' => 'lastOfQuarter',
|
||||
'1Y' => 'endOfYear',
|
||||
];
|
||||
$modifierMap = [
|
||||
'quarter' => 3,
|
||||
'quarterly' => 3,
|
||||
'half-year' => 6,
|
||||
];
|
||||
if (isset($functionMap[$repeatFreq])) {
|
||||
$function = $functionMap[$repeatFreq];
|
||||
$date->$function($subtract);
|
||||
$end = clone $start;
|
||||
|
||||
return $date;
|
||||
if (isset($functionMap[$range])) {
|
||||
$function = $functionMap[$range];
|
||||
$end->$function();
|
||||
|
||||
return $end;
|
||||
}
|
||||
if (isset($modifierMap[$repeatFreq])) {
|
||||
$subtract = $subtract * $modifierMap[$repeatFreq];
|
||||
$date->subMonths($subtract);
|
||||
if ($range == '6M') {
|
||||
if (intval($start->format('m')) >= 7) {
|
||||
$end->endOfYear();
|
||||
} else {
|
||||
$end->startOfYear()->addMonths(6);
|
||||
}
|
||||
|
||||
return $date;
|
||||
return $end;
|
||||
}
|
||||
|
||||
throw new FireflyException('Cannot do subtractPeriod for $repeat_freq ' . $repeatFreq);
|
||||
throw new FireflyException('updateEndDate cannot handle $range ' . $range);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $range
|
||||
* @param Carbon $start
|
||||
*
|
||||
* @return Carbon
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function updateStartDate($range, Carbon $start)
|
||||
{
|
||||
$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;
|
||||
}
|
||||
throw new FireflyException('updateStartDate cannot handle $range ' . $range);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,13 +1,17 @@
|
||||
<?php
|
||||
namespace FireflyIII\Shared\Preferences;
|
||||
/**
|
||||
* Class PreferencesHelper
|
||||
*
|
||||
* @package FireflyIII\Shared\Preferences
|
||||
*/
|
||||
class Preferences implements PreferencesInterface
|
||||
{
|
||||
|
||||
namespace FireflyIII\Support;
|
||||
|
||||
use Auth;
|
||||
use FireflyIII\Models\Preference;
|
||||
|
||||
/**
|
||||
* Class Preferences
|
||||
*
|
||||
* @package FireflyIII\Support
|
||||
*/
|
||||
class Preferences
|
||||
{
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $default
|
||||
@ -16,7 +20,7 @@ class Preferences implements PreferencesInterface
|
||||
*/
|
||||
public function get($name, $default = null)
|
||||
{
|
||||
$pref = \Preference::where('user_id', \Auth::user()->id)->where('name', $name)->first();
|
||||
$pref = Preference::where('user_id', Auth::user()->id)->where('name', $name)->first();
|
||||
if (is_null($pref) && is_null($default)) {
|
||||
// return NULL
|
||||
return null;
|
||||
@ -37,11 +41,11 @@ class Preferences implements PreferencesInterface
|
||||
*/
|
||||
public function set($name, $value)
|
||||
{
|
||||
$pref = \Preference::where('user_id', \Auth::user()->id)->where('name', $name)->first();
|
||||
$pref = Preference::where('user_id', Auth::user()->id)->where('name', $name)->first();
|
||||
if (is_null($pref)) {
|
||||
$pref = new \Preference;
|
||||
$pref = new Preference;
|
||||
$pref->name = $name;
|
||||
$pref->user()->associate(\Auth::user());
|
||||
$pref->user()->associate(Auth::user());
|
||||
|
||||
}
|
||||
$pref->data = $value;
|
||||
@ -51,4 +55,4 @@ class Preferences implements PreferencesInterface
|
||||
return $pref;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,17 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Search;
|
||||
namespace FireflyIII\Support\Search;
|
||||
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
use FireflyIII\Models\Budget;
|
||||
use FireflyIII\Models\Category;
|
||||
|
||||
|
||||
/**
|
||||
* Class Search
|
||||
*
|
||||
* @package FireflyIII\Search
|
||||
*/
|
||||
class Search
|
||||
class Search implements SearchInterface
|
||||
{
|
||||
/**
|
||||
* @param array $words
|
||||
@ -39,7 +42,7 @@ class Search
|
||||
/** @var Collection $set */
|
||||
$set = \Auth::user()->budgets()->get();
|
||||
$newSet = $set->filter(
|
||||
function (\Budget $b) use ($words) {
|
||||
function (Budget $b) use ($words) {
|
||||
$found = 0;
|
||||
foreach ($words as $word) {
|
||||
if (!(strpos(strtolower($b->name), strtolower($word)) === false)) {
|
||||
@ -64,7 +67,7 @@ class Search
|
||||
/** @var Collection $set */
|
||||
$set = \Auth::user()->categories()->get();
|
||||
$newSet = $set->filter(
|
||||
function (\Category $c) use ($words) {
|
||||
function (Category $c) use ($words) {
|
||||
$found = 0;
|
||||
foreach ($words as $word) {
|
||||
if (!(strpos(strtolower($c->name), strtolower($word)) === false)) {
|
48
app/Support/Search/SearchInterface.php
Normal file
48
app/Support/Search/SearchInterface.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Support\Search;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Interface SearchInterface
|
||||
*
|
||||
* @package FireflyIII\Support\Search
|
||||
*/
|
||||
interface SearchInterface {
|
||||
/**
|
||||
* @param array $words
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchAccounts(array $words);
|
||||
|
||||
/**
|
||||
* @param array $words
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchBudgets(array $words);
|
||||
|
||||
/**
|
||||
* @param array $words
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchCategories(array $words);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $words
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchTags(array $words);
|
||||
|
||||
/**
|
||||
* @param array $words
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function searchTransactions(array $words);
|
||||
}
|
@ -1,46 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Report;
|
||||
namespace FireflyIII\Support;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\PiggyBankRepetition;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class ReportHelper
|
||||
* Class Steam
|
||||
*
|
||||
* @package FireflyIII\Report
|
||||
* @package FireflyIII\Support
|
||||
*/
|
||||
class ReportHelper implements ReportHelperInterface
|
||||
class Steam
|
||||
{
|
||||
/**
|
||||
* Only return the top X entries, group the rest by amount
|
||||
* and described as 'Others'. id = 0 as well
|
||||
*
|
||||
* @param array $array
|
||||
* @param int $limit
|
||||
* @param Account $account
|
||||
* @param Carbon $date
|
||||
*
|
||||
* @return array
|
||||
* @return float
|
||||
*/
|
||||
public function limitArray(array $array, $limit = 10)
|
||||
public function balance(Account $account, Carbon $date = null)
|
||||
{
|
||||
$others = [
|
||||
'name' => 'Others',
|
||||
'amount' => 0
|
||||
];
|
||||
$return = [];
|
||||
$count = 0;
|
||||
foreach ($array as $id => $entry) {
|
||||
if ($count < ($limit - 1)) {
|
||||
$return[$id] = $entry;
|
||||
} else {
|
||||
$others['amount'] += $entry['amount'];
|
||||
}
|
||||
|
||||
$count++;
|
||||
}
|
||||
$return[0] = $others;
|
||||
|
||||
return $return;
|
||||
$date = is_null($date) ? Carbon::now() : $date;
|
||||
$balance = floatval(
|
||||
$account->transactions()->leftJoin(
|
||||
'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id'
|
||||
)->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount')
|
||||
);
|
||||
|
||||
return $balance;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,6 +109,38 @@ class ReportHelper implements ReportHelperInterface
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Only return the top X entries, group the rest by amount
|
||||
* and described as 'Others'. id = 0 as well
|
||||
*
|
||||
* @param array $array
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function limitArray(array $array, $limit = 10)
|
||||
{
|
||||
$others = [
|
||||
'name' => 'Others',
|
||||
'amount' => 0
|
||||
];
|
||||
$return = [];
|
||||
$count = 0;
|
||||
foreach ($array as $id => $entry) {
|
||||
if ($count < ($limit - 1)) {
|
||||
$return[$id] = $entry;
|
||||
} else {
|
||||
$others['amount'] += $entry['amount'];
|
||||
}
|
||||
|
||||
$count++;
|
||||
}
|
||||
$return[0] = $others;
|
||||
|
||||
return $return;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort an array where all 'amount' keys are negative floats.
|
||||
*
|
||||
@ -139,4 +162,23 @@ class ReportHelper implements ReportHelperInterface
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PiggyBank $piggyBank
|
||||
* @param PiggyBankRepetition $repetition
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function percentage(PiggyBank $piggyBank, PiggyBankRepetition $repetition)
|
||||
{
|
||||
$pct = $repetition->currentamount / $piggyBank->targetamount * 100;
|
||||
if ($pct > 100) {
|
||||
// @codeCoverageIgnoreStart
|
||||
return 100;
|
||||
// @codeCoverageIgnoreEnd
|
||||
} else {
|
||||
return floor($pct);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
110
app/User.php
Normal file
110
app/User.php
Normal file
@ -0,0 +1,110 @@
|
||||
<?php namespace FireflyIII;
|
||||
|
||||
use Illuminate\Auth\Authenticatable;
|
||||
use Illuminate\Auth\Passwords\CanResetPassword;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
|
||||
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* Class User
|
||||
*
|
||||
* @package FireflyIII
|
||||
*/
|
||||
class User extends Model implements AuthenticatableContract, CanResetPasswordContract
|
||||
{
|
||||
|
||||
use Authenticatable, CanResetPassword;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = ['email', 'password'];
|
||||
/**
|
||||
* The attributes excluded from the model's JSON form.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = ['password', 'remember_token'];
|
||||
/**
|
||||
* The database table used by the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'users';
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function accounts()
|
||||
{
|
||||
return $this->hasMany('FireflyIII\Models\Account');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function bills()
|
||||
{
|
||||
return $this->hasMany('FireflyIII\Models\Bill');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function budgets()
|
||||
{
|
||||
return $this->hasMany('FireflyIII\Models\Budget');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function categories()
|
||||
{
|
||||
return $this->hasMany('FireflyIII\Models\Category');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
|
||||
*/
|
||||
public function piggyBanks()
|
||||
{
|
||||
return $this->hasManyThrough('FireflyIII\Models\PiggyBank', 'FireflyIII\Models\Account');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function preferences()
|
||||
{
|
||||
return $this->hasMany('FireflyIII\Models\Preference');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function reminders()
|
||||
{
|
||||
return $this->hasMany('FireflyIII\Models\Reminder');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function transactionjournals()
|
||||
{
|
||||
return $this->hasMany('FireflyIII\Models\TransactionJournal');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
*/
|
||||
public function setPasswordAttribute($value)
|
||||
{
|
||||
$this->attributes['password'] = \Hash::make($value);
|
||||
}
|
||||
|
||||
}
|
53
app/Validation/FireflyValidator.php
Normal file
53
app/Validation/FireflyValidator.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Validation;
|
||||
|
||||
use Auth;
|
||||
use DB;
|
||||
use Illuminate\Validation\Validator;
|
||||
|
||||
/**
|
||||
* Class FireflyValidator
|
||||
*
|
||||
* @package FireflyIII\Validation
|
||||
*/
|
||||
class FireflyValidator extends Validator
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $attribute
|
||||
* @param $value
|
||||
* @param $parameters
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validateBelongsToUser($attribute, $value, $parameters)
|
||||
{
|
||||
$count = DB::table($parameters[0])->where('user_id', Auth::user()->id)->where('id', $value)->count();
|
||||
if ($count == 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attribute
|
||||
* @param $value
|
||||
* @param $parameters
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validateUniqueForUser($attribute, $value, $parameters)
|
||||
{
|
||||
$count = DB::table($parameters[0])->where($parameters[1], $value)->count();
|
||||
if ($count == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,76 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Class Cleanup
|
||||
*/
|
||||
class Cleanup extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Clean caches, regenerate some stuff.';
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'firefly:cleanup';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function fire()
|
||||
{
|
||||
$this->info('Start!');
|
||||
Artisan::call('clear-compiled');
|
||||
$this->info('Cleared compiled...');
|
||||
Artisan::call('ide-helper:generate');
|
||||
$this->info('IDE helper, done...');
|
||||
Artisan::call('ide-helper:models');
|
||||
$this->info('IDE models, done...');
|
||||
Artisan::call('optimize');
|
||||
$this->info('Optimized...');
|
||||
Artisan::call('dump-autoload');
|
||||
$this->info('Done!');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command arguments.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getArguments()
|
||||
{
|
||||
return [
|
||||
// ['example', InputArgument::REQUIRED, 'An example argument.'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
return [
|
||||
// ['example', null, InputOption::VALUE_OPTIONAL, 'An example option.', null],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
4
app/config/.gitignore
vendored
4
app/config/.gitignore
vendored
@ -1,4 +0,0 @@
|
||||
local/
|
||||
laptop/
|
||||
vagrant/
|
||||
production/
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user