Merge branch 'release/3.8.0'

Conflicts:
	app/Repositories/Account/AccountRepository.php
This commit is contained in:
James Cole 2016-03-19 17:17:06 +01:00
commit 7b22099608
520 changed files with 16427 additions and 10570 deletions

View File

@ -1,26 +1,50 @@
# Save as .codeclimate.yml (note leading .) in project root directory
languages:
JavaScript: true
PHP: true
---
engines:
csslint:
enabled: true
duplication:
enabled: true
config:
languages:
- ruby
- javascript
- python
- php
eslint:
enabled: true
fixme:
enabled: true
phpmd:
enabled: true
ratings:
paths:
- "**.css"
- "**.inc"
- "**.js"
- "**.jsx"
- "**.module"
- "**.php"
- "**.py"
- "**.rb"
exclude_paths:
- "gulpfile.js"
- "public/packages/maximebf/php-debugbar/debugbar.js"
- "public/packages/maximebf/php-debugbar/widgets.js"
- "public/packages/maximebf/php-debugbar/openhandler.js"
- "public/packages/maximebf/php-debugbar/widgets/sqlqueries/widget.js"
- "public/js/bootstrap3-typeahead.min.js"
- "public/js/bootstrap-sortable.js"
- "public/js/bootstrap-tagsinput.min.js"
- "public/js/bootstrap-tagsinput.min.js.map"
- "public/js/daterangepicker.js"
- "public/js/jquery-2.1.3.min.js"
- "public/js/jquery-2.1.3.min.js.map"
- "public/js/jquery-ui.min.js"
- "public/js/metisMenu.js"
- "public/js/moment.min.js"
- "public/js/sb-admin-2.js"
- "public/bootstrap/*"
- "resources/lang/*"
- "tests/*"
- "database/*"
- "storage/*"
- gulpfile.js
- public/packages/maximebf/php-debugbar/debugbar.js
- public/packages/maximebf/php-debugbar/widgets.js
- public/packages/maximebf/php-debugbar/openhandler.js
- public/packages/maximebf/php-debugbar/widgets/sqlqueries/widget.js
- public/js/bootstrap3-typeahead.min.js
- public/js/bootstrap-sortable.js
- public/js/bootstrap-tagsinput.min.js
- public/js/bootstrap-tagsinput.min.js.map
- public/js/daterangepicker.js
- public/js/jquery-2.1.3.min.js
- public/js/jquery-2.1.3.min.js.map
- public/js/jquery-ui.min.js
- public/js/metisMenu.js
- public/js/moment.min.js
- public/js/sb-admin-2.js
- public/bootstrap/*
- resources/lang/*
- tests/*
- database/*
- storage/*

2
.csslintrc Normal file
View File

@ -0,0 +1,2 @@
--exclude-exts=.min.css
--ignore=adjoining-classes,box-model,ids,order-alphabetical,unqualified-attributes

1
.eslintignore Normal file
View File

@ -0,0 +1 @@
**/*{.,-}min.js

213
.eslintrc Normal file
View File

@ -0,0 +1,213 @@
ecmaFeatures:
modules: true
jsx: true
env:
amd: true
browser: true
es6: true
jquery: true
node: true
# http://eslint.org/docs/rules/
rules:
# Possible Errors
comma-dangle: [2, never]
no-cond-assign: 2
no-console: 0
no-constant-condition: 2
no-control-regex: 2
no-debugger: 2
no-dupe-args: 2
no-dupe-keys: 2
no-duplicate-case: 2
no-empty: 2
no-empty-character-class: 2
no-ex-assign: 2
no-extra-boolean-cast: 2
no-extra-parens: 0
no-extra-semi: 2
no-func-assign: 2
no-inner-declarations: [2, functions]
no-invalid-regexp: 2
no-irregular-whitespace: 2
no-negated-in-lhs: 2
no-obj-calls: 2
no-regex-spaces: 2
no-sparse-arrays: 2
no-unexpected-multiline: 2
no-unreachable: 2
use-isnan: 2
valid-jsdoc: 0
valid-typeof: 2
# Best Practices
accessor-pairs: 2
block-scoped-var: 0
complexity: [2, 6]
consistent-return: 0
curly: 0
default-case: 0
dot-location: 0
dot-notation: 0
eqeqeq: 2
guard-for-in: 2
no-alert: 2
no-caller: 2
no-case-declarations: 2
no-div-regex: 2
no-else-return: 0
no-empty-label: 2
no-empty-pattern: 2
no-eq-null: 2
no-eval: 2
no-extend-native: 2
no-extra-bind: 2
no-fallthrough: 2
no-floating-decimal: 0
no-implicit-coercion: 0
no-implied-eval: 2
no-invalid-this: 0
no-iterator: 2
no-labels: 0
no-lone-blocks: 2
no-loop-func: 2
no-magic-number: 0
no-multi-spaces: 0
no-multi-str: 0
no-native-reassign: 2
no-new-func: 2
no-new-wrappers: 2
no-new: 2
no-octal-escape: 2
no-octal: 2
no-proto: 2
no-redeclare: 2
no-return-assign: 2
no-script-url: 2
no-self-compare: 2
no-sequences: 0
no-throw-literal: 0
no-unused-expressions: 2
no-useless-call: 2
no-useless-concat: 2
no-void: 2
no-warning-comments: 0
no-with: 2
radix: 2
vars-on-top: 0
wrap-iife: 2
yoda: 0
# Strict
strict: 0
# Variables
init-declarations: 0
no-catch-shadow: 2
no-delete-var: 2
no-label-var: 2
no-shadow-restricted-names: 2
no-shadow: 0
no-undef-init: 2
no-undef: 0
no-undefined: 0
no-unused-vars: 0
no-use-before-define: 0
# Node.js and CommonJS
callback-return: 2
global-require: 2
handle-callback-err: 2
no-mixed-requires: 0
no-new-require: 0
no-path-concat: 2
no-process-exit: 2
no-restricted-modules: 0
no-sync: 0
# Stylistic Issues
array-bracket-spacing: 0
block-spacing: 0
brace-style: 0
camelcase: 0
comma-spacing: 0
comma-style: 0
computed-property-spacing: 0
consistent-this: 0
eol-last: 0
func-names: 0
func-style: 0
id-length: 0
id-match: 0
indent: 0
jsx-quotes: 0
key-spacing: 0
linebreak-style: 0
lines-around-comment: 0
max-depth: 0
max-len: 0
max-nested-callbacks: 0
max-params: 0
max-statements: [2, 30]
new-cap: 0
new-parens: 0
newline-after-var: 0
no-array-constructor: 0
no-bitwise: 0
no-continue: 0
no-inline-comments: 0
no-lonely-if: 0
no-mixed-spaces-and-tabs: 0
no-multiple-empty-lines: 0
no-negated-condition: 0
no-nested-ternary: 0
no-new-object: 0
no-plusplus: 0
no-restricted-syntax: 0
no-spaced-func: 0
no-ternary: 0
no-trailing-spaces: 0
no-underscore-dangle: 0
no-unneeded-ternary: 0
object-curly-spacing: 0
one-var: 0
operator-assignment: 0
operator-linebreak: 0
padded-blocks: 0
quote-props: 0
quotes: 0
require-jsdoc: 0
semi-spacing: 0
semi: 0
sort-vars: 0
space-after-keywords: 0
space-before-blocks: 0
space-before-function-paren: 0
space-before-keywords: 0
space-in-parens: 0
space-infix-ops: 0
space-return-throw-case: 0
space-unary-ops: 0
spaced-comment: 0
wrap-regex: 0
# ECMAScript 6
arrow-body-style: 0
arrow-parens: 0
arrow-spacing: 0
constructor-super: 0
generator-star-spacing: 0
no-arrow-condition: 0
no-class-assign: 0
no-const-assign: 0
no-dupe-class-members: 0
no-this-before-super: 0
no-var: 0
object-shorthand: 0
prefer-arrow-callback: 0
prefer-const: 0
prefer-reflect: 0
prefer-spread: 0
prefer-template: 0
require-yield: 0

11
.gitignore vendored
View File

@ -1,17 +1,6 @@
/vendor
/node_modules
Homestead.yaml
Homestead.json
.env
_ide_helper.php
_ide_helper_models.php
.phpstorm.meta.php
storage/
# Eclipse project files
.buildpath
.project
.settings/
.env.local

View File

@ -1,3 +1,6 @@
# .scrutinizer.yml
tools:
external_code_coverage: false
filter:
excluded_paths:
- app/Support/Migration/*

View File

@ -1,15 +1,15 @@
language: php
sudo: false
php:
- 5.6
- 7
install:
- phpenv config-rm xdebug.ini
- composer selfupdate
- composer install --no-dev
- composer update
- rm composer.lock
- composer update --no-scripts
- php artisan clear-compiled
- php artisan optimize
- php artisan env
- mv -v .env.testing .env
- php artisan env

47
CHANGELOG.md Normal file
View File

@ -0,0 +1,47 @@
# Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
- No unreleased changes yet.
## [3.8.0] - 2016-03-20
### Added
- Two factor authentication, thanks to the excellent work of [zjean](https://github.com/zjean).
- A new chart showing your net worth in year and multi-year reports.
- You can now see if your current or future rules actually match any transactions, thanks to the excellent work of @roberthorlings.
- New date fields for transactions. They are not used yet in reports or anything, but they can be filled in.
- New routine to export your data.
- Firefly III will mail the site owner when blocked users try to login, or when blocked domains are used in registrations.
### Changed
- Firefly III now requires PHP 7.0 minimum.
### Fixed
- HTML fixes, thanks to [roberthorlings](https://github.com/roberthorlings) and [zjean](https://github.com/zjean)..
- A bug fix in the ABN Amro importer, thanks to [roberthorlings](https://github.com/roberthorlings)
- It was not possible to change the opening balance, once it had been set. Thanks to [xnyhps](https://github.com/xnyhps) and [marcoveeneman](https://github.com/marcoveeneman) for spotting this.
- Various other bug fixes.
## [3.4.2] - 2015-05-25
### Added
- Initial release.
### Changed
- Initial release.
### Deprecated
- Initial release.
### Removed
- Initial release.
### Fixed
- Initial release.
### Security
- Initial release.

View File

@ -1,12 +1,11 @@
# Firefly III
[![Requires PHP7](https://img.shields.io/badge/php-7.0-red.svg)](https://secure.php.net/downloads.php#v7.0.4)
[![Latest Stable Version](https://poser.pugx.org/grumpydictator/firefly-iii/v/stable)](https://packagist.org/packages/grumpydictator/firefly-iii)
[![Total Downloads](https://poser.pugx.org/grumpydictator/firefly-iii/downloads)](https://packagist.org/packages/grumpydictator/firefly-iii)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/JC5/firefly-iii/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/JC5/firefly-iii/?branch=master)
[![Build Status](https://scrutinizer-ci.com/g/JC5/firefly-iii/badges/build.png?b=master)](https://scrutinizer-ci.com/g/JC5/firefly-iii/build-status/master)
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102/mini.png)](https://insight.sensiolabs.com/projects/d44c7012-5f50-41ad-add8-8445330e4102)
[![Code Climate](https://codeclimate.com/github/JC5/firefly-iii/badges/gpa.svg)](https://codeclimate.com/github/JC5/firefly-iii)
[![Project Status](http://stillmaintained.com/JC5/firefly-iii.png?a=b)](http://stillmaintained.com/JC5/firefly-iii)
## About

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Console\Commands;
@ -44,7 +45,7 @@ class UpgradeFireflyInstructions extends Command
//
$version = Config::get('firefly.version');
$config = Config::get('upgrade.text');
$text = isset($config[$version]) ? $config[$version] : null;
$text = $config[$version] ?? null;
$this->line('+------------------------------------------------------------------------------+');
$this->line('');

View File

@ -1,4 +1,6 @@
<?php
declare(strict_types = 1);
/**
* Kernel.php
* Copyright (C) 2016 Sander Dorigo

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Events;
/**

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
/**
* TransactionJournalStored.php
* Copyright (C) 2016 Sander Dorigo
@ -30,9 +31,9 @@ class TransactionJournalStored extends Event
* Create a new event instance.
*
* @param TransactionJournal $journal
* @param $piggyBankId
* @param int $piggyBankId
*/
public function __construct(TransactionJournal $journal, $piggyBankId)
public function __construct(TransactionJournal $journal, int $piggyBankId)
{
//
$this->journal = $journal;

View File

@ -1,4 +1,7 @@
<?php namespace FireflyIII\Events;
<?php
declare(strict_types = 1);
namespace FireflyIII\Events;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Queue\SerializesModels;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Exceptions;

View File

@ -1,11 +1,16 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Exceptions;
use Auth;
use ErrorException;
use Exception;
use FireflyIII\Jobs\MailError;
use FireflyIII\User;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
/**
@ -37,9 +42,17 @@ class Handler extends ExceptionHandler
*/
public function render($request, Exception $exception)
{
if ($exception instanceof FireflyException || $exception instanceof ErrorException) {
$isDebug = env('APP_DEBUG', false);
return response()->view('errors.FireflyException', ['exception' => $exception, 'debug' => $isDebug], 500);
}
return parent::render($request, $exception);
}
/**
* Report or log an exception.
*
@ -51,6 +64,26 @@ class Handler extends ExceptionHandler
*/
public function report(Exception $exception)
{
if ($exception instanceof FireflyException || $exception instanceof ErrorException) {
$user = Auth::check() ? Auth::user() : new User;
$data = [
'class' => get_class($exception),
'errorMessage' => $exception->getMessage(),
'time' => date('r'),
'stackTrace' => $exception->getTraceAsString(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'code' => $exception->getCode(),
];
// create job that will mail.
$job = new MailError($user, env('SITE_OWNER'), Request::ip(), $data);
dispatch($job);
}
parent::report($exception);
}
}

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Exceptions;

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Exceptions;
/**

View File

@ -0,0 +1,148 @@
<?php
declare(strict_types = 1);
/**
* AttachmentCollector.php
* Copyright (C) 2016 Sander Dorigo
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Export\Collector;
use Amount;
use Crypt;
use FireflyIII\Models\Attachment;
use FireflyIII\Models\ExportJob;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Collection;
use Log;
use Storage;
/**
* Class AttachmentCollector
*
* @package FireflyIII\Export\Collector
*/
class AttachmentCollector extends BasicCollector implements CollectorInterface
{
/** @var string */
private $explanationString = '';
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
private $exportDisk;
/** @var AttachmentRepositoryInterface */
private $repository;
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
private $uploadDisk;
/**
* AttachmentCollector constructor.
*
* @param ExportJob $job
*/
public function __construct(ExportJob $job)
{
$this->repository = app('FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface');
// make storage:
$this->uploadDisk = Storage::disk('upload');
$this->exportDisk = Storage::disk('export');
parent::__construct($job);
}
/**
*
*/
public function run()
{
// grab all the users attachments:
$attachments = $this->getAttachments();
/** @var Attachment $attachment */
foreach ($attachments as $attachment) {
$this->exportAttachment($attachment);
}
// put the explanation string in a file and attach it as well.
$file = $this->job->key . '-Source of all your attachments explained.txt';
$this->exportDisk->put($file, $this->explanationString);
Log::debug('Also put explanation file "' . $file . '" in the zip.');
$this->getFiles()->push($file);
}
/**
* @param Attachment $attachment
*/
private function explain(Attachment $attachment)
{
/** @var TransactionJournal $journal */
$journal = $attachment->attachable;
$args = [
'attachment_name' => $attachment->filename,
'attachment_id' => $attachment->id,
'type' => strtolower($journal->transactionType->type),
'description' => $journal->description,
'journal_id' => $journal->id,
'date' => $journal->date->formatLocalized(strval(trans('config.month_and_day'))),
'amount' => Amount::formatJournal($journal, false),
];
$string = trans('firefly.attachment_explanation', $args) . "\n";
$this->explanationString .= $string;
}
/**
* @param Attachment $attachment
*
* @return bool
*/
private function exportAttachment(Attachment $attachment): bool
{
$file = $attachment->fileName();
Log::debug('Original file is at "' . $file . '".');
if ($this->uploadDisk->exists($file)) {
try {
$decrypted = Crypt::decrypt($this->uploadDisk->get($file));
$exportFile = $this->exportFileName($attachment);
$this->exportDisk->put($exportFile, $decrypted);
$this->getFiles()->push($exportFile);
Log::debug('Stored file content in new file "' . $exportFile . '", which will be in the final zip file.');
// explain:
$this->explain($attachment);
} catch (DecryptException $e) {
Log::error('Catchable error: could not decrypt attachment #' . $attachment->id . ' because: ' . $e->getMessage());
}
}
return true;
}
/**
* Returns the new file name for the export file.
*
* @param $attachment
*
* @return string
*/
private function exportFileName($attachment): string
{
return sprintf('%s-Attachment nr. %s - %s', $this->job->key, strval($attachment->id), $attachment->filename);
}
/**
* @return Collection
*/
private function getAttachments(): Collection
{
$attachments = $this->repository->get();
Log::debug('Found ' . $attachments->count() . ' attachments.');
return $attachments;
}
}

View File

@ -0,0 +1,57 @@
<?php
declare(strict_types = 1);
/**
* BasicCollector.php
* Copyright (C) 2016 Sander Dorigo
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Export\Collector;
use FireflyIII\Models\ExportJob;
use Illuminate\Support\Collection;
/**
* Class BasicCollector
*
* @package FireflyIII\Export\Collector
*/
class BasicCollector
{
/** @var ExportJob */
protected $job;
/** @var Collection */
private $files;
/**
* BasicCollector constructor.
*
* @param ExportJob $job
*/
public function __construct(ExportJob $job)
{
$this->files = new Collection;
$this->job = $job;
}
/**
* @return Collection
*/
public function getFiles()
{
return $this->files;
}
/**
* @param Collection $files
*/
public function setFiles(Collection $files)
{
$this->files = $files;
}
}

View File

@ -0,0 +1,38 @@
<?php
declare(strict_types = 1);
/**
* CollectorInterface.php
* Copyright (C) 2016 Sander Dorigo
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Export\Collector;
use Illuminate\Support\Collection;
/**
* Interface CollectorInterface
*
* @package FireflyIII\Export\Collector
*/
interface CollectorInterface
{
/**
* @return Collection
*/
public function getFiles();
/**
* @return bool
*/
public function run();
/**
* @param Collection $files
*
*/
public function setFiles(Collection $files);
}

View File

@ -0,0 +1,119 @@
<?php
declare(strict_types = 1);
/**
* UploadCollector.php
* Copyright (C) 2016 Sander Dorigo
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Export\Collector;
use Auth;
use Crypt;
use FireflyIII\Models\ExportJob;
use Illuminate\Contracts\Encryption\DecryptException;
use Log;
use Storage;
/**
* Class UploadCollector
*
* @package FireflyIII\Export\Collector
*/
class UploadCollector extends BasicCollector implements CollectorInterface
{
/** @var string */
private $expected;
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
private $exportDisk;
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
private $uploadDisk;
/**
* AttachmentCollector constructor.
*
* @param ExportJob $job
*/
public function __construct(ExportJob $job)
{
parent::__construct($job);
// make storage:
$this->uploadDisk = Storage::disk('upload');
$this->exportDisk = Storage::disk('export');
$this->expected = 'csv-upload-' . Auth::user()->id . '-';
}
/**
*
*/
public function run()
{
// grab upload directory.
$files = $this->uploadDisk->files();
Log::debug('Found ' . count($files) . ' files in the upload directory.');
foreach ($files as $entry) {
$this->processOldUpload($entry);
}
}
/**
* @param string $entry
*
* @return string
*/
private function getOriginalUploadDate(string $entry): string
{
// this is an original upload.
$parts = explode('-', str_replace(['.csv.encrypted', $this->expected], '', $entry));
$originalUpload = intval($parts[1]);
$date = date('Y-m-d \a\t H-i-s', $originalUpload);
return $date;
}
/**
* @param string $entry
*
* @return bool
*/
private function isValidFile(string $entry): bool
{
$len = strlen($this->expected);
if (substr($entry, 0, $len) === $this->expected) {
Log::debug($entry . ' is part of this users original uploads.');
return true;
}
Log::debug($entry . ' is not part of this users original uploads.');
return false;
}
/**
* @param $entry
*/
private function processOldUpload(string $entry)
{
$content = '';
if ($this->isValidFile($entry)) {
try {
$content = Crypt::decrypt($this->uploadDisk->get($entry));
} catch (DecryptException $e) {
Log::error('Could not decrypt old CSV import file ' . $entry . '. Skipped because ' . $e->getMessage());
}
}
if (strlen($content) > 0) {
// continue with file:
$date = $this->getOriginalUploadDate($entry);
$file = $this->job->key . '-Old CSV import dated ' . $date . '.csv';
Log::debug('Will put "' . $file . '" in the zip file.');
$this->exportDisk->put($file, $content);
$this->getFiles()->push($file);
}
}
}

View File

@ -0,0 +1,67 @@
<?php
declare(strict_types = 1);
/**
* ConfigurationFile.php
* Copyright (C) 2016 Sander Dorigo
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Export;
use FireflyIII\Models\ExportJob;
use Log;
use Storage;
/**
* Class ConfigurationFile
*
* @package FireflyIII\Export
*/
class ConfigurationFile
{
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
private $exportDisk;
/** @var ExportJob */
private $job;
/**
* ConfigurationFile constructor.
*
* @param ExportJob $job
*/
public function __construct(ExportJob $job)
{
$this->job = $job;
$this->exportDisk = Storage::disk('export');
}
/**
* @return bool
*/
public function make()
{
$fields = array_keys(get_class_vars(Entry::class));
$types = Entry::getTypes();
$configuration = [
'date-format' => 'Y-m-d', // unfortunately, this is hard-coded.
'has-headers' => true,
'map' => [], // we could build a map if necessary for easy re-import.
'roles' => [],
'mapped' => [],
'specifix' => [],
];
foreach ($fields as $field) {
$configuration['roles'][] = $types[$field];
}
$file = $this->job->key . '-configuration.json';
Log::debug('Created JSON config file.');
Log::debug('Will put "' . $file . '" in the ZIP file.');
$this->exportDisk->put($file, json_encode($configuration, JSON_PRETTY_PRINT));
return $file;
}
}

460
app/Export/Entry.php Normal file
View File

@ -0,0 +1,460 @@
<?php
declare(strict_types = 1);
/**
* Entry.php
* Copyright (C) 2016 Sander Dorigo
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Export;
use FireflyIII\Models\Account;
use FireflyIII\Models\Budget;
use FireflyIII\Models\Category;
use FireflyIII\Models\TransactionJournal;
/**
* To extend the exported object, in case of new features in Firefly III for example,
* do the following:
*
* - Add the field(s) to this class
* - Make sure the "fromJournal"-routine fills these fields.
* - Add them to the static function that returns its type (key=value. Remember that the only
* valid types can be found in config/csv.php (under "roles").
*
* These new entries should be should be strings and numbers as much as possible.
*
*
*
* Class Entry
*
* @package FireflyIII\Export
*/
class Entry
{
/** @var string */
public $amount;
/** @var int */
public $billId;
/** @var string */
public $billName;
/** @var int */
public $budgetId;
/** @var string */
public $budgetName;
/** @var int */
public $categoryId;
/** @var string */
public $categoryName;
/** @var string */
public $date;
/** @var string */
public $description;
/** @var string */
public $fromAccountIban;
/** @var int */
public $fromAccountId;
/** @var string */
public $fromAccountName;
public $fromAccountNumber;
/** @var string */
public $fromAccountType;
/** @var string */
public $toAccountIban;
/** @var int */
public $toAccountId;
/** @var string */
public $toAccountName;
public $toAccountNumber;
/** @var string */
public $toAccountType;
/**
* @param TransactionJournal $journal
*
* @return Entry
*/
public static function fromJournal(TransactionJournal $journal)
{
$entry = new self;
$entry->setDescription($journal->description);
$entry->setDate($journal->date->format('Y-m-d'));
$entry->setAmount(TransactionJournal::amount($journal));
/** @var Budget $budget */
$budget = $journal->budgets->first();
if (!is_null($budget)) {
$entry->setBudgetId($budget->id);
$entry->setBudgetName($budget->name);
}
/** @var Category $category */
$category = $journal->categories->first();
if (!is_null($category)) {
$entry->setCategoryId($category->id);
$entry->setCategoryName($category->name);
}
if (!is_null($journal->bill_id)) {
$entry->setBillId($journal->bill_id);
$entry->setBillName($journal->bill->name);
}
/** @var Account $sourceAccount */
$sourceAccount = TransactionJournal::sourceAccount($journal);
$entry->setFromAccountId($sourceAccount->id);
$entry->setFromAccountName($sourceAccount->name);
$entry->setFromAccountIban($sourceAccount->iban);
$entry->setFromAccountType($sourceAccount->accountType->type);
$entry->setFromAccountNumber($sourceAccount->getMeta('accountNumber'));
/** @var Account $destination */
$destination = TransactionJournal::destinationAccount($journal);
$entry->setToAccountId($destination->id);
$entry->setToAccountName($destination->name);
$entry->setToAccountIban($destination->iban);
$entry->setToAccountType($destination->accountType->type);
$entry->setToAccountNumber($destination->getMeta('accountNumber'));
return $entry;
}
/**
* @return array
*/
public static function getTypes(): array
{
// key = field name (see top of class)
// value = field type (see csv.php under 'roles')
return [
'amount' => 'amount',
'date' => 'date-transaction',
'description' => 'description',
'billId' => 'bill-id',
'billName' => 'bill-name',
'budgetId' => 'budget-id',
'budgetName' => 'budget-name',
'categoryId' => 'category-id',
'categoryName' => 'category-name',
'fromAccountId' => 'account-id',
'fromAccountName' => 'account-name',
'fromAccountIban' => 'account-iban',
'fromAccountType' => '_ignore', // no, Firefly cannot import what it exports. I know :D
'toAccountId' => 'opposing-id',
'toAccountName' => 'opposing-name',
'toAccountIban' => 'opposing-iban',
'toAccountType' => '_ignore',
];
}
/**
* @return string
*/
public function getAmount(): string
{
return $this->amount;
}
/**
* @param string $amount
*/
public function setAmount(string $amount)
{
$this->amount = $amount;
}
/**
* @return int
*/
public function getBillId()
{
return $this->billId;
}
/**
* @param int $billId
*/
public function setBillId($billId)
{
$this->billId = $billId;
}
/**
* @return string
*/
public function getBillName()
{
return $this->billName;
}
/**
* @param string $billName
*/
public function setBillName($billName)
{
$this->billName = $billName;
}
/**
* @return int
*/
public function getBudgetId()
{
return $this->budgetId;
}
/**
* @param int $budgetId
*/
public function setBudgetId($budgetId)
{
$this->budgetId = $budgetId;
}
/**
* @return string
*/
public function getBudgetName()
{
return $this->budgetName;
}
/**
* @param string $budgetName
*/
public function setBudgetName($budgetName)
{
$this->budgetName = $budgetName;
}
/**
* @return int
*/
public function getCategoryId()
{
return $this->categoryId;
}
/**
* @param int $categoryId
*/
public function setCategoryId($categoryId)
{
$this->categoryId = $categoryId;
}
/**
* @return string
*/
public function getCategoryName()
{
return $this->categoryName;
}
/**
* @param string $categoryName
*/
public function setCategoryName($categoryName)
{
$this->categoryName = $categoryName;
}
/**
* @return string
*/
public function getDate()
{
return $this->date;
}
/**
* @param string $date
*/
public function setDate(string $date)
{
$this->date = $date;
}
/**
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* @param string $description
*/
public function setDescription(string $description)
{
$this->description = $description;
}
/**
* @return string
*/
public function getFromAccountIban()
{
return $this->fromAccountIban;
}
/**
* @param string $fromAccountIban
*/
public function setFromAccountIban($fromAccountIban)
{
$this->fromAccountIban = $fromAccountIban;
}
/**
* @return int
*/
public function getFromAccountId()
{
return $this->fromAccountId;
}
/**
* @param int $fromAccountId
*/
public function setFromAccountId($fromAccountId)
{
$this->fromAccountId = $fromAccountId;
}
/**
* @return string
*/
public function getFromAccountName()
{
return $this->fromAccountName;
}
/**
* @param string $fromAccountName
*/
public function setFromAccountName($fromAccountName)
{
$this->fromAccountName = $fromAccountName;
}
/**
* @return mixed
*/
public function getFromAccountNumber()
{
return $this->fromAccountNumber;
}
/**
* @param mixed $fromAccountNumber
*/
public function setFromAccountNumber($fromAccountNumber)
{
$this->fromAccountNumber = $fromAccountNumber;
}
/**
* @return string
*/
public function getFromAccountType()
{
return $this->fromAccountType;
}
/**
* @param string $fromAccountType
*/
public function setFromAccountType($fromAccountType)
{
$this->fromAccountType = $fromAccountType;
}
/**
* @return string
*/
public function getToAccountIban()
{
return $this->toAccountIban;
}
/**
* @param string $toAccountIban
*/
public function setToAccountIban($toAccountIban)
{
$this->toAccountIban = $toAccountIban;
}
/**
* @return int
*/
public function getToAccountId()
{
return $this->toAccountId;
}
/**
* @param int $toAccountId
*/
public function setToAccountId($toAccountId)
{
$this->toAccountId = $toAccountId;
}
/**
* @return string
*/
public function getToAccountName()
{
return $this->toAccountName;
}
/**
* @param string $toAccountName
*/
public function setToAccountName($toAccountName)
{
$this->toAccountName = $toAccountName;
}
/**
* @return mixed
*/
public function getToAccountNumber()
{
return $this->toAccountNumber;
}
/**
* @param mixed $toAccountNumber
*/
public function setToAccountNumber($toAccountNumber)
{
$this->toAccountNumber = $toAccountNumber;
}
/**
* @return string
*/
public function getToAccountType()
{
return $this->toAccountType;
}
/**
* @param string $toAccountType
*/
public function setToAccountType($toAccountType)
{
$this->toAccountType = $toAccountType;
}
}

View File

@ -0,0 +1,56 @@
<?php
declare(strict_types = 1);
/**
* BasicExporter.php
* Copyright (C) 2016 Sander Dorigo
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Export\Exporter;
use FireflyIII\Models\ExportJob;
use Illuminate\Support\Collection;
/**
* Class BasicExporter
*
* @package FireflyIII\Export\Exporter
*/
class BasicExporter
{
/** @var ExportJob */
protected $job;
private $entries;
/**
* BasicExporter constructor.
*
* @param ExportJob $job
*/
public function __construct(ExportJob $job)
{
$this->entries = new Collection;
$this->job = $job;
}
/**
* @return Collection
*/
public function getEntries()
{
return $this->entries;
}
/**
* @param Collection $entries
*/
public function setEntries(Collection $entries)
{
$this->entries = $entries;
}
}

View File

@ -0,0 +1,81 @@
<?php
declare(strict_types = 1);
/**
* CsvExporter.php
* Copyright (C) 2016 Sander Dorigo
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Export\Exporter;
use FireflyIII\Export\Entry;
use FireflyIII\Models\ExportJob;
use League\Csv\Writer;
use SplFileObject;
/**
* Class CsvExporter
*
* @package FireflyIII\Export\Exporter
*/
class CsvExporter extends BasicExporter implements ExporterInterface
{
/** @var string */
private $fileName;
/**
* CsvExporter constructor.
*
* @param ExportJob $job
*/
public function __construct(ExportJob $job)
{
parent::__construct($job);
}
/**
* @return string
*/
public function getFileName()
{
return $this->fileName;
}
/**
*
*/
public function run()
{
// create temporary file:
$this->tempFile();
// necessary for CSV writer:
$fullPath = storage_path('export') . DIRECTORY_SEPARATOR . $this->fileName;
// create CSV writer:
$writer = Writer::createFromPath(new SplFileObject($fullPath, 'a+'), 'w');
// all rows:
$rows = [];
// add header:
$first = $this->getEntries()->first();
$rows[] = array_keys(get_object_vars($first));
// then the rest:
/** @var Entry $entry */
foreach ($this->getEntries() as $entry) {
$rows[] = array_values(get_object_vars($entry));
}
$writer->insertAll($rows);
}
private function tempFile()
{
$this->fileName = $this->job->key . '-records.csv';
}
}

View File

@ -0,0 +1,43 @@
<?php
declare(strict_types = 1);
/**
* ExporterInterface.php
* Copyright (C) 2016 Sander Dorigo
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Export\Exporter;
use Illuminate\Support\Collection;
/**
* Interface ExporterInterface
*
* @package FireflyIII\Export\Exporter
*/
interface ExporterInterface
{
/**
* @return Collection
*/
public function getEntries();
/**
* @return string
*/
public function getFileName();
/**
*
*/
public function run();
/**
* @param Collection $entries
*
*/
public function setEntries(Collection $entries);
}

182
app/Export/Processor.php Normal file
View File

@ -0,0 +1,182 @@
<?php
declare(strict_types = 1);
/**
* Processor.php
* Copyright (C) 2016 Sander Dorigo
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Export;
use Auth;
use Config;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\ExportJob;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Support\Collection;
use Log;
use Storage;
use ZipArchive;
/**
* Class Processor
*
* @package FireflyIII\Export
*/
class Processor
{
/** @var Collection */
public $accounts;
/** @var string */
public $exportFormat;
/** @var bool */
public $includeAttachments;
/** @var bool */
public $includeConfig;
/** @var bool */
public $includeOldUploads;
/** @var ExportJob */
public $job;
/** @var array */
public $settings;
/** @var \FireflyIII\Export\ConfigurationFile */
private $configurationMaker;
/** @var Collection */
private $exportEntries;
/** @var Collection */
private $files;
/** @var Collection */
private $journals;
/**
* Processor constructor.
*
* @param array $settings
*/
public function __construct(array $settings)
{
// save settings
$this->settings = $settings;
$this->accounts = $settings['accounts'];
$this->exportFormat = $settings['exportFormat'];
$this->includeAttachments = $settings['includeAttachments'];
$this->includeConfig = $settings['includeConfig'];
$this->includeOldUploads = $settings['includeOldUploads'];
$this->job = $settings['job'];
$this->journals = new Collection;
$this->exportEntries = new Collection;
$this->files = new Collection;
}
/**
*
*/
public function collectAttachments()
{
$attachmentCollector = app('FireflyIII\Export\Collector\AttachmentCollector', [$this->job]);
$attachmentCollector->run();
$this->files = $this->files->merge($attachmentCollector->getFiles());
}
/**
*
*/
public function collectJournals()
{
$args = [$this->accounts, Auth::user(), $this->settings['startDate'], $this->settings['endDate']];
$journalCollector = app('FireflyIII\Repositories\Journal\JournalCollector', $args);
$this->journals = $journalCollector->collect();
Log::debug(
'Collected ' .
$this->journals->count() . ' journals (between ' .
$this->settings['startDate']->format('Y-m-d') . ' and ' .
$this->settings['endDate']->format('Y-m-d')
. ').'
);
}
public function collectOldUploads()
{
$uploadCollector = app('FireflyIII\Export\Collector\UploadCollector', [$this->job]);
$uploadCollector->run();
$this->files = $this->files->merge($uploadCollector->getFiles());
}
/**
*
*/
public function convertJournals()
{
$count = 0;
/** @var TransactionJournal $journal */
foreach ($this->journals as $journal) {
$this->exportEntries->push(Entry::fromJournal($journal));
$count++;
}
Log::debug('Converted ' . $count . ' journals to "Entry" objects.');
}
public function createConfigFile()
{
$this->configurationMaker = app('FireflyIII\Export\ConfigurationFile', [$this->job]);
$this->files->push($this->configurationMaker->make());
}
public function createZipFile()
{
$zip = new ZipArchive;
$file = $this->job->key . '.zip';
$fullPath = storage_path('export') . '/' . $file;
Log::debug('Will create zip file at ' . $fullPath);
if ($zip->open($fullPath, ZipArchive::CREATE) !== true) {
throw new FireflyException('Cannot store zip file.');
}
// for each file in the collection, add it to the zip file.
$disk = Storage::disk('export');
foreach ($this->getFiles() as $entry) {
// is part of this job?
$zipFileName = str_replace($this->job->key . '-', '', $entry);
$result = $zip->addFromString($zipFileName, $disk->get($entry));
if (!$result) {
Log::error('Could not add "' . $entry . '" into zip file as "' . $zipFileName . '".');
}
}
$zip->close();
// delete the files:
foreach ($this->getFiles() as $file) {
Log::debug('Will now delete file "' . $file . '".');
$disk->delete($file);
}
Log::debug('Done!');
}
/**
*
*/
public function exportJournals()
{
$exporterClass = Config::get('firefly.export_formats.' . $this->exportFormat);
$exporter = app($exporterClass, [$this->job]);
Log::debug('Going to export ' . $this->exportEntries->count() . ' export entries into ' . $this->exportFormat . ' format.');
$exporter->setEntries($this->exportEntries);
$exporter->run();
$this->files->push($exporter->getFileName());
Log::debug('Added "' . $exporter->getFileName() . '" to the list of files to include in the zip.');
}
/**
* @return Collection
*/
public function getFiles()
{
return $this->files;
}
}

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
/**
* AccountChartGeneratorInterface.php
* Copyright (C) 2016 Sander Dorigo
@ -28,7 +29,7 @@ interface AccountChartGeneratorInterface
*
* @return array
*/
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end);
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end): array;
/**
* @param Collection $accounts
@ -37,7 +38,7 @@ interface AccountChartGeneratorInterface
*
* @return array
*/
public function frontpage(Collection $accounts, Carbon $start, Carbon $end);
public function frontpage(Collection $accounts, Carbon $start, Carbon $end): array;
/**
* @param Account $account
@ -46,5 +47,5 @@ interface AccountChartGeneratorInterface
*
* @return array
*/
public function single(Account $account, Carbon $start, Carbon $end);
public function single(Account $account, Carbon $start, Carbon $end): array;
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\Account;
use Carbon\Carbon;
@ -22,7 +22,7 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
*
* @return array
*/
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end)
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end): array
{
$data = [
'count' => 1,
@ -30,7 +30,6 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
'label' => trans('firefly.spent'),
'data' => []]]];
bcscale(2);
$start->subDay();
$ids = $this->getIdsFromCollection($accounts);
$startBalances = Steam::balancesById($ids, $start);
@ -69,7 +68,7 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
*
* @return array
*/
public function frontpage(Collection $accounts, Carbon $start, Carbon $end)
public function frontpage(Collection $accounts, Carbon $start, Carbon $end): array
{
// language:
$format = (string)trans('config.month_and_day');
@ -116,7 +115,7 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
*
* @return array
*/
public function single(Account $account, Carbon $start, Carbon $end)
public function single(Account $account, Carbon $start, Carbon $end): array
{
// language:
$format = (string)trans('config.month_and_day');
@ -137,7 +136,7 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
while ($end >= $current) {
$theDate = $current->format('Y-m-d');
$balance = isset($range[$theDate]) ? $range[$theDate] : $previous;
$balance = $range[$theDate] ?? $previous;
$data['labels'][] = $current->formatLocalized($format);
$data['datasets'][0]['data'][] = $balance;
@ -153,7 +152,7 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
*
* @return array
*/
protected function getIdsFromCollection(Collection $collection)
protected function getIdsFromCollection(Collection $collection): array
{
$ids = [];
foreach ($collection as $entry) {
@ -170,7 +169,7 @@ class ChartJsAccountChartGenerator implements AccountChartGeneratorInterface
*
* @return string
*/
protected function isInArray($array, $entryId)
protected function isInArray($array, $entryId): string
{
if (isset($array[$entryId])) {
return $array[$entryId];

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
/**
* BillChartGeneratorInterface.php
* Copyright (C) 2016 Sander Dorigo
@ -27,7 +28,7 @@ interface BillChartGeneratorInterface
*
* @return array
*/
public function frontpage($paid, $unpaid);
public function frontpage(string $paid, string $unpaid): array;
/**
* @param Bill $bill
@ -35,6 +36,6 @@ interface BillChartGeneratorInterface
*
* @return array
*/
public function single(Bill $bill, Collection $entries);
public function single(Bill $bill, Collection $entries): array;
}

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
/**
* ChartJsBillChartGenerator.php
* Copyright (C) 2016 Sander Dorigo
@ -27,9 +28,8 @@ class ChartJsBillChartGenerator implements BillChartGeneratorInterface
*
* @return array
*/
public function frontpage($paid, $unpaid)
public function frontpage(string $paid, string $unpaid): array
{
bcscale(2);
$data = [
[
'value' => round($unpaid, 2),
@ -38,7 +38,7 @@ class ChartJsBillChartGenerator implements BillChartGeneratorInterface
'label' => trans('firefly.unpaid'),
],
[
'value' => round($paid * -1, 2), // paid is negative, must be positive.
'value' => round(bcmul($paid, '-1'), 2), // paid is negative, must be positive.
'color' => 'rgba(0, 141, 76, 0.7)',
'highlight' => 'rgba(0, 141, 76, 0.9)',
'label' => trans('firefly.paid'),
@ -54,7 +54,7 @@ class ChartJsBillChartGenerator implements BillChartGeneratorInterface
*
* @return array
*/
public function single(Bill $bill, Collection $entries)
public function single(Bill $bill, Collection $entries): array
{
$format = (string)trans('config.month');
$data = [
@ -73,7 +73,7 @@ class ChartJsBillChartGenerator implements BillChartGeneratorInterface
/*
* journalAmount has been collected in BillRepository::getJournals
*/
$actualAmount[] = round(($entry->journalAmount * -1), 2);
$actualAmount[] = round(TransactionJournal::amountPositive($entry), 2);
}
$data['datasets'][] = [

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
/**
* BudgetChartGeneratorInterface.php
* Copyright (C) 2016 Sander Dorigo
@ -23,28 +24,28 @@ interface BudgetChartGeneratorInterface
*
* @return array
*/
public function budget(Collection $entries);
public function budget(Collection $entries): array;
/**
* @param Collection $entries
*
* @return array
*/
public function budgetLimit(Collection $entries);
public function budgetLimit(Collection $entries): array;
/**
* @param Collection $entries
*
* @return array
*/
public function frontpage(Collection $entries);
public function frontpage(Collection $entries): array;
/**
* @param Collection $entries
*
* @return array
*/
public function multiYear(Collection $entries);
public function multiYear(Collection $entries): array;
/**
* @param Collection $budgets
@ -52,6 +53,6 @@ interface BudgetChartGeneratorInterface
*
* @return array
*/
public function year(Collection $budgets, Collection $entries);
public function year(Collection $budgets, Collection $entries): array;
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\Budget;
@ -21,7 +21,7 @@ class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface
*
* @return array
*/
public function budget(Collection $entries, $dateFormat = 'month')
public function budget(Collection $entries, $dateFormat = 'month'): array
{
// language:
$language = Preferences::get('language', env('DEFAULT_LANGUAGE', 'en_US'))->data;
@ -56,7 +56,7 @@ class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface
*
* @return array
*/
public function budgetLimit(Collection $entries)
public function budgetLimit(Collection $entries): array
{
return $this->budget($entries, 'monthAndDay');
}
@ -66,7 +66,7 @@ class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface
*
* @return array
*/
public function frontpage(Collection $entries)
public function frontpage(Collection $entries): array
{
$data = [
'count' => 0,
@ -84,8 +84,8 @@ class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface
foreach ($filtered as $entry) {
$data['labels'][] = $entry[0];
$left[] = round($entry[1], 2);
$spent[] = round($entry[2] * -1, 2); // spent is coming in negative, must be positive
$overspent[] = round($entry[3] * -1, 2); // same
$spent[] = round(bcmul($entry[2], '-1'), 2); // spent is coming in negative, must be positive
$overspent[] = round(bcmul($entry[3], '-1'), 2); // same
}
$data['datasets'][] = [
@ -111,7 +111,7 @@ class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface
*
* @return array
*/
public function multiYear(Collection $entries)
public function multiYear(Collection $entries): array
{
// dataset:
$data = [
@ -146,7 +146,7 @@ class ChartJsBudgetChartGenerator implements BudgetChartGeneratorInterface
*
* @return array
*/
public function year(Collection $budgets, Collection $entries)
public function year(Collection $budgets, Collection $entries): array
{
// language:
$format = (string)trans('config.month');

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
/**
* CategoryChartGeneratorInterface.php
* Copyright (C) 2016 Sander Dorigo
@ -32,28 +33,28 @@ interface CategoryChartGeneratorInterface
*
* @return array
*/
public function earnedInPeriod(Collection $categories, Collection $entries);
public function earnedInPeriod(Collection $categories, Collection $entries): array;
/**
* @param Collection $entries
*
* @return array
*/
public function frontpage(Collection $entries);
public function frontpage(Collection $entries): array;
/**
* @param Collection $entries
*
* @return array
*/
public function multiYear(Collection $entries);
public function multiYear(Collection $entries): array;
/**
* @param Collection $entries
*
* @return array
*/
public function period(Collection $entries);
public function period(Collection $entries): array;
/**
* @param Collection $categories
@ -61,5 +62,5 @@ interface CategoryChartGeneratorInterface
*
* @return array
*/
public function spentInPeriod(Collection $categories, Collection $entries);
public function spentInPeriod(Collection $categories, Collection $entries): array;
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\Category;
use Illuminate\Support\Collection;
@ -18,7 +18,7 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
*
* @return array
*/
public function all(Collection $entries)
public function all(Collection $entries): array
{
@ -39,11 +39,11 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
foreach ($entries as $entry) {
$data['labels'][] = $entry[1];
$spent = round($entry[2], 2);
$earned = round($entry[3], 2);
$spent = $entry[2];
$earned = $entry[3];
$data['datasets'][0]['data'][] = $spent == 0 ? null : $spent * -1;
$data['datasets'][1]['data'][] = $earned == 0 ? null : $earned;
$data['datasets'][0]['data'][] = bccomp($spent, '0') === 0 ? null : bcmul($spent, '-1');
$data['datasets'][1]['data'][] = bccomp($earned, '0') === 0 ? null : $earned;
}
return $data;
@ -55,7 +55,7 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
*
* @return array
*/
public function earnedInPeriod(Collection $categories, Collection $entries)
public function earnedInPeriod(Collection $categories, Collection $entries): array
{
// language:
@ -87,7 +87,7 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
*
* @return array
*/
public function frontpage(Collection $entries)
public function frontpage(Collection $entries): array
{
$data = [
'count' => 1,
@ -102,7 +102,7 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
foreach ($entries as $entry) {
if ($entry->spent != 0) {
$data['labels'][] = $entry->name;
$data['datasets'][0]['data'][] = round(($entry->spent * -1), 2);
$data['datasets'][0]['data'][] = round(bcmul($entry->spent, '-1'), 2);
}
}
@ -114,7 +114,7 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
*
* @return array
*/
public function multiYear(Collection $entries)
public function multiYear(Collection $entries): array
{
// dataset:
$data = [
@ -154,7 +154,7 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
*
* @return array
*/
public function period(Collection $entries)
public function period(Collection $entries): array
{
return $this->all($entries);
@ -166,7 +166,7 @@ class ChartJsCategoryChartGenerator implements CategoryChartGeneratorInterface
*
* @return array
*/
public function spentInPeriod(Collection $categories, Collection $entries)
public function spentInPeriod(Collection $categories, Collection $entries): array
{
// language:

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\PiggyBank;
use Carbon\Carbon;
@ -19,7 +19,7 @@ class ChartJsPiggyBankChartGenerator implements PiggyBankChartGeneratorInterface
*
* @return array
*/
public function history(Collection $set)
public function history(Collection $set): array
{
// language:
@ -36,7 +36,6 @@ class ChartJsPiggyBankChartGenerator implements PiggyBankChartGeneratorInterface
],
];
$sum = '0';
bcscale(2);
foreach ($set as $entry) {
$date = new Carbon($entry->date);
$sum = bcadd($sum, $entry->sum);

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
/**
* PiggyBankChartGenerator.php
* Copyright (C) 2016 Sander Dorigo
@ -23,5 +24,5 @@ interface PiggyBankChartGeneratorInterface
*
* @return array
*/
public function history(Collection $set);
public function history(Collection $set): array;
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Generator\Chart\Report;
use Illuminate\Support\Collection;
@ -19,7 +19,7 @@ class ChartJsReportChartGenerator implements ReportChartGeneratorInterface
*
* @return array
*/
public function multiYearInOut(Collection $entries)
public function multiYearInOut(Collection $entries): array
{
$data = [
'count' => 2,
@ -52,7 +52,7 @@ class ChartJsReportChartGenerator implements ReportChartGeneratorInterface
*
* @return array
*/
public function multiYearInOutSummarized($income, $expense, $count)
public function multiYearInOutSummarized(string $income, string $expense, int $count): array
{
$data = [
'count' => 2,
@ -81,7 +81,33 @@ class ChartJsReportChartGenerator implements ReportChartGeneratorInterface
*
* @return array
*/
public function yearInOut(Collection $entries)
public function netWorth(Collection $entries) : array
{
$format = (string)trans('config.month_and_day');
$data = [
'count' => 1,
'labels' => [],
'datasets' => [
[
'label' => trans('firefly.net-worth'),
'data' => [],
],
],
];
foreach ($entries as $entry) {
$data['labels'][] = trim($entry['date']->formatLocalized($format));
$data['datasets'][0]['data'][] = round($entry['net-worth'], 2);
}
return $data;
}
/**
* @param Collection $entries
*
* @return array
*/
public function yearInOut(Collection $entries): array
{
// language:
$format = (string)trans('config.month');
@ -117,7 +143,7 @@ class ChartJsReportChartGenerator implements ReportChartGeneratorInterface
*
* @return array
*/
public function yearInOutSummarized($income, $expense, $count)
public function yearInOutSummarized(string $income, string $expense, int $count): array
{
$data = [

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
/**
* ReportChartGenerator.php
* Copyright (C) 2016 Sander Dorigo
@ -24,7 +25,7 @@ interface ReportChartGeneratorInterface
*
* @return array
*/
public function multiYearInOut(Collection $entries);
public function multiYearInOut(Collection $entries): array;
/**
* @param string $income
@ -33,14 +34,21 @@ interface ReportChartGeneratorInterface
*
* @return array
*/
public function multiYearInOutSummarized($income, $expense, $count);
public function multiYearInOutSummarized(string $income, string $expense, int $count): array;
/**
* @param Collection $entries
*
* @return array
*/
public function yearInOut(Collection $entries);
public function netWorth(Collection $entries) : array;
/**
* @param Collection $entries
*
* @return array
*/
public function yearInOut(Collection $entries): array;
/**
* @param string $income
@ -49,6 +57,6 @@ interface ReportChartGeneratorInterface
*
* @return array
*/
public function yearInOutSummarized($income, $expense, $count);
public function yearInOutSummarized(string $income, string $expense, int $count): array;
}

View File

@ -1,4 +1,7 @@
<?php namespace FireflyIII\Handlers\Events;
<?php
declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
use Auth;
use FireflyIII\Events\TransactionJournalStored;
@ -14,25 +17,14 @@ use FireflyIII\Models\TransactionJournal;
class ConnectJournalToPiggyBank
{
/**
* Create the event handler.
*
* @codeCoverageIgnore
*
*/
public function __construct()
{
//
}
/**
* Connect a new transaction journal to any related piggy banks.
*
* @param TransactionJournalStored $event
*
* @return boolean
* @return bool
*/
public function handle(TransactionJournalStored $event)
public function handle(TransactionJournalStored $event): bool
{
/** @var TransactionJournal $journal */
$journal = $event->journal;
@ -49,12 +41,11 @@ class ConnectJournalToPiggyBank
if (is_null($repetition)) {
return true;
}
bcscale(2);
$amount = $journal->amount_positive;
$amount = TransactionJournal::amountPositive($journal);
// if piggy account matches source account, the amount is positive
if ($piggyBank->account_id == $journal->source_account->id) {
$amount = $amount * -1;
if ($piggyBank->account_id == TransactionJournal::sourceAccount($journal)->id) {
$amount = bcmul($amount, '-1');
}

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
/**
* FireRulesForStore.php
* Copyright (C) 2016 Sander Dorigo
@ -25,25 +26,15 @@ use Log;
*/
class FireRulesForStore
{
/**
* Create the event handler.
*
* @codeCoverageIgnore
*
*/
public function __construct()
{
//
}
/**
* Connect a new transaction journal to any related piggy banks.
*
* @param TransactionJournalStored $event
*
* @return boolean
* @return bool
*/
public function handle(TransactionJournalStored $event)
public function handle(TransactionJournalStored $event): bool
{
// get all the user's rule groups, with the rules, order by 'order'.
/** @var User $user */
@ -61,17 +52,18 @@ class FireRulesForStore
->get(['rules.*']);
/** @var Rule $rule */
foreach ($rules as $rule) {
Log::debug('Now handling rule #' . $rule->id . ' (' . $rule->title . ')');
$processor = new Processor($rule, $event->journal);
// get some return out of this?
$processor->handle();
Log::debug('Now handling rule #' . $rule->id . ' (' . $rule->title . ')');
$processor = Processor::make($rule);
$processor->handleTransactionJournal($event->journal);
if ($rule->stop_processing) {
break;
return true;
}
}
}
return true;
}
}

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
/**
* FireRulesForUpdate.php
* Copyright (C) 2016 Sander Dorigo
@ -24,23 +25,14 @@ use Log;
*/
class FireRulesForUpdate
{
/**
* Create the event handler.
*
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param TransactionJournalUpdated $event
*
* @return void
* @return bool
*/
public function handle(TransactionJournalUpdated $event)
public function handle(TransactionJournalUpdated $event): bool
{
// get all the user's rule groups, with the rules, order by 'order'.
/** @var User $user */
@ -59,10 +51,10 @@ class FireRulesForUpdate
/** @var Rule $rule */
foreach ($rules as $rule) {
Log::debug('Now handling rule #' . $rule->id . ' (' . $rule->title . ')');
$processor = new Processor($rule, $event->journal);
// get some return out of this?
$processor->handle();
Log::debug('Now handling rule #' . $rule->id . ' (' . $rule->title . ')');
$processor = Processor::make($rule);
$processor->handleTransactionJournal($event->journal);
if ($rule->stop_processing) {
break;
@ -70,5 +62,7 @@ class FireRulesForUpdate
}
}
return true;
}
}

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
/**
* RescanJournalAfterStore.php
* Copyright (C) 2016 Sander Dorigo
@ -11,7 +12,6 @@ namespace FireflyIII\Handlers\Events;
use FireflyIII\Events\TransactionJournalStored;
use FireflyIII\Support\Events\BillScanner;
use Log;
/**
* Class RescanJournal
@ -22,26 +22,19 @@ use Log;
class ScanForBillsAfterStore
{
/**
* Create the event handler.
*
*/
public function __construct()
{
//
}
/**
* Scan a transaction journal for possible links to bills, right after storing.
*
* @param TransactionJournalStored $event
*
* @return void
* @return bool
*/
public function handle(TransactionJournalStored $event)
public function handle(TransactionJournalStored $event): bool
{
$journal = $event->journal;
BillScanner::scan($journal);
return true;
}
}

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
/**
* ScanForBillsAfterUpdate.php
* Copyright (C) 2016 Sander Dorigo
@ -11,7 +12,6 @@ namespace FireflyIII\Handlers\Events;
use FireflyIII\Events\TransactionJournalUpdated;
use FireflyIII\Support\Events\BillScanner;
use Log;
/**
* Class RescanJournal
@ -21,27 +21,19 @@ use Log;
*/
class ScanForBillsAfterUpdate
{
/**
* Create the event handler.
*
*/
public function __construct()
{
//
}
/**
* Scan a transaction journal for possibly related bills after it has been updated.
*
* @param TransactionJournalUpdated $event
*
* @return void
* @return bool
*/
public function handle(TransactionJournalUpdated $event)
public function handle(TransactionJournalUpdated $event): bool
{
$journal = $event->journal;
BillScanner::scan($journal);
return true;
}
}

View File

@ -1,8 +1,11 @@
<?php namespace FireflyIII\Handlers\Events;
<?php
declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
use FireflyIII\Events\TransactionJournalUpdated;
use FireflyIII\Models\PiggyBankEvent;
use FireflyIII\Models\PiggyBankRepetition;
use FireflyIII\Models\TransactionJournal;
/**
* Class UpdateJournalConnection
@ -13,23 +16,14 @@ use FireflyIII\Models\PiggyBankRepetition;
class UpdateJournalConnection
{
/**
* Create the event handler.
*
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param TransactionJournalUpdated $event
*
* @return void
* @return bool
*/
public function handle(TransactionJournalUpdated $event)
public function handle(TransactionJournalUpdated $event):bool
{
$journal = $event->journal;
@ -37,7 +31,7 @@ class UpdateJournalConnection
/** @var PiggyBankEvent $event */
$event = PiggyBankEvent::where('transaction_journal_id', $journal->id)->first();
if (is_null($event)) {
return;
return false;
}
$piggyBank = $event->piggyBank()->first();
$repetition = null;
@ -47,11 +41,10 @@ class UpdateJournalConnection
}
if (is_null($repetition)) {
return;
return false;
}
bcscale(2);
$amount = $journal->amount;
$amount = TransactionJournal::amount($journal);
$diff = bcsub($amount, $event->amount); // update current repetition
$repetition->currentamount = bcadd($repetition->currentamount, $diff);
@ -60,6 +53,8 @@ class UpdateJournalConnection
$event->amount = $amount;
$event->save();
return true;
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* UserEventListener.php
* Copyright (C) 2016 Sander Dorigo
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Handlers\Events;
use Session;
/**
* Class UserEventListener
*
* @package FireflyIII\Handlers\Events
*/
class UserEventListener
{
/**
* Handle user logout events.
*/
public function onUserLogout($event)
{
// dump stuff from the session:
Session::forget('twofactor-authenticated');
Session::forget('twofactor-authenticated-date');
return true;
}
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Attachments;
use Auth;
@ -9,7 +9,10 @@ use FireflyIII\Models\Attachment;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\MessageBag;
use Input;
use Log;
use Storage;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use TypeError;
/**
* Class AttachmentHelper
@ -28,6 +31,9 @@ class AttachmentHelper implements AttachmentHelperInterface
/** @var int */
protected $maxUploadSize;
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
protected $uploadDisk;
/**
*
*/
@ -37,6 +43,7 @@ class AttachmentHelper implements AttachmentHelperInterface
$this->allowedMimes = Config::get('firefly.allowedMimes');
$this->errors = new MessageBag;
$this->messages = new MessageBag;
$this->uploadDisk = Storage::disk('upload');
}
/**
@ -44,7 +51,7 @@ class AttachmentHelper implements AttachmentHelperInterface
*
* @return string
*/
public function getAttachmentLocation(Attachment $attachment)
public function getAttachmentLocation(Attachment $attachment): string
{
$path = storage_path('upload') . DIRECTORY_SEPARATOR . 'at-' . $attachment->id . '.data';
@ -54,7 +61,7 @@ class AttachmentHelper implements AttachmentHelperInterface
/**
* @return MessageBag
*/
public function getErrors()
public function getErrors(): MessageBag
{
return $this->errors;
}
@ -62,7 +69,7 @@ class AttachmentHelper implements AttachmentHelperInterface
/**
* @return MessageBag
*/
public function getMessages()
public function getMessages(): MessageBag
{
return $this->messages;
}
@ -72,9 +79,17 @@ class AttachmentHelper implements AttachmentHelperInterface
*
* @return bool
*/
public function saveAttachmentsForModel(Model $model)
public function saveAttachmentsForModel(Model $model): bool
{
$files = Input::file('attachments');
$files = null;
try {
if (Input::hasFile('attachments')) {
$files = Input::file('attachments');
}
} catch (TypeError $e) {
// Log it, do nothing else.
Log::error($e->getMessage());
}
if (is_array($files)) {
foreach ($files as $entry) {
@ -97,7 +112,7 @@ class AttachmentHelper implements AttachmentHelperInterface
*
* @return bool
*/
protected function hasFile(UploadedFile $file, Model $model)
protected function hasFile(UploadedFile $file, Model $model): bool
{
$md5 = md5_file($file->getRealPath());
$name = $file->getClientOriginalName();
@ -115,16 +130,17 @@ class AttachmentHelper implements AttachmentHelperInterface
}
/**
*
* @param UploadedFile $file
* @param Model $model
*
* @return bool|Attachment
* @return Attachment
*/
protected function processFile(UploadedFile $file, Model $model)
protected function processFile(UploadedFile $file, Model $model): Attachment
{
$validation = $this->validateUpload($file, $model);
if ($validation === false) {
return false;
return new Attachment;
}
$attachment = new Attachment; // create Attachment object.
@ -137,15 +153,13 @@ class AttachmentHelper implements AttachmentHelperInterface
$attachment->uploaded = 0;
$attachment->save();
$path = $file->getRealPath(); // encrypt and move file to storage.
$content = file_get_contents($path);
$fileObject = $file->openFile('r');
$fileObject->rewind();
$content = $fileObject->fread($file->getSize());
$encrypted = Crypt::encrypt($content);
// store it:
$upload = $this->getAttachmentLocation($attachment);
if (is_writable(dirname($upload))) {
file_put_contents($upload, $encrypted);
}
$this->uploadDisk->put($attachment->fileName(), $encrypted);
$attachment->uploaded = 1; // update attachment
$attachment->save();
@ -165,7 +179,7 @@ class AttachmentHelper implements AttachmentHelperInterface
*
* @return bool
*/
protected function validMime(UploadedFile $file)
protected function validMime(UploadedFile $file): bool
{
$mime = e($file->getMimeType());
$name = e($file->getClientOriginalName());
@ -185,7 +199,7 @@ class AttachmentHelper implements AttachmentHelperInterface
*
* @return bool
*/
protected function validSize(UploadedFile $file)
protected function validSize(UploadedFile $file): bool
{
$size = $file->getSize();
$name = e($file->getClientOriginalName());
@ -205,7 +219,7 @@ class AttachmentHelper implements AttachmentHelperInterface
*
* @return bool
*/
protected function validateUpload(UploadedFile $file, Model $model)
protected function validateUpload(UploadedFile $file, Model $model): bool
{
if (!$this->validMime($file)) {
return false;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Attachments;
use FireflyIII\Models\Attachment;
@ -17,25 +17,25 @@ interface AttachmentHelperInterface
/**
* @param Attachment $attachment
*
* @return mixed
* @return string
*/
public function getAttachmentLocation(Attachment $attachment);
public function getAttachmentLocation(Attachment $attachment): string;
/**
* @return MessageBag
*/
public function getErrors();
public function getErrors(): MessageBag;
/**
* @return MessageBag
*/
public function getMessages();
public function getMessages(): MessageBag;
/**
* @param Model $model
*
* @return bool
*/
public function saveAttachmentsForModel(Model $model);
public function saveAttachmentsForModel(Model $model): bool;
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use Illuminate\Support\Collection;
@ -15,73 +15,81 @@ class Account
/** @var Collection */
protected $accounts;
/** @var float */
protected $difference;
/** @var float */
protected $end;
/** @var float */
protected $start;
/** @var string */
protected $difference = '';
/** @var string */
protected $end = '';
/** @var string */
protected $start = '';
/**
* @return \Illuminate\Support\Collection
* Account constructor.
*/
public function getAccounts()
public function __construct()
{
$this->accounts = new Collection;
}
/**
* @return Collection
*/
public function getAccounts(): Collection
{
return $this->accounts;
}
/**
* @param \Illuminate\Support\Collection $accounts
* @param Collection $accounts
*/
public function setAccounts($accounts)
public function setAccounts(Collection $accounts)
{
$this->accounts = $accounts;
}
/**
* @return float
* @return string
*/
public function getDifference()
public function getDifference(): string
{
return $this->difference;
}
/**
* @param float $difference
* @param string $difference
*/
public function setDifference($difference)
public function setDifference(string $difference)
{
$this->difference = $difference;
}
/**
* @return float
* @return string
*/
public function getEnd()
public function getEnd(): string
{
return $this->end;
}
/**
* @param float $end
* @param string $end
*/
public function setEnd($end)
public function setEnd(string $end)
{
$this->end = $end;
}
/**
* @return float
* @return string
*/
public function getStart()
public function getStart(): string
{
return $this->start;
}
/**
* @param float $start
* @param string $start
*/
public function setStart($start)
public function setStart(string $start)
{
$this->start = $start;
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use Illuminate\Support\Collection;
@ -39,23 +39,23 @@ class Balance
/**
* @return BalanceHeader
*/
public function getBalanceHeader()
public function getBalanceHeader(): BalanceHeader
{
return $this->balanceHeader;
return $this->balanceHeader ?? new BalanceHeader;
}
/**
* @param BalanceHeader $balanceHeader
*/
public function setBalanceHeader($balanceHeader)
public function setBalanceHeader(BalanceHeader $balanceHeader)
{
$this->balanceHeader = $balanceHeader;
}
/**
* @return \Illuminate\Support\Collection
* @return Collection
*/
public function getBalanceLines()
public function getBalanceLines(): Collection
{
return $this->balanceLines;
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use FireflyIII\Models\Account as AccountModel;
@ -17,15 +17,15 @@ class BalanceEntry
/** @var AccountModel */
protected $account;
/** @var float */
protected $left = 0.0;
/** @var float */
protected $spent = 0.0;
/** @var string */
protected $left = '0';
/** @var string */
protected $spent = '0';
/**
* @return AccountModel
*/
public function getAccount()
public function getAccount(): AccountModel
{
return $this->account;
}
@ -33,39 +33,39 @@ class BalanceEntry
/**
* @param AccountModel $account
*/
public function setAccount($account)
public function setAccount(AccountModel $account)
{
$this->account = $account;
}
/**
* @return float
* @return string
*/
public function getLeft()
public function getLeft(): string
{
return $this->left;
}
/**
* @param float $left
* @param string $left
*/
public function setLeft($left)
public function setLeft(string $left)
{
$this->left = $left;
}
/**
* @return float
* @return string
*/
public function getSpent()
public function getSpent(): string
{
return $this->spent;
}
/**
* @param float $spent
* @param string $spent
*/
public function setSpent($spent)
public function setSpent(string $spent)
{
$this->spent = $spent;
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use FireflyIII\Models\Account as AccountModel;
@ -37,7 +37,7 @@ class BalanceHeader
/**
* @return Collection
*/
public function getAccounts()
public function getAccounts(): Collection
{
return $this->accounts;
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use FireflyIII\Models\Budget as BudgetModel;
@ -25,6 +25,7 @@ class BalanceLine
/** @var BudgetModel */
protected $budget;
/** @var int */
protected $role = self::ROLE_DEFAULTROLE;
/**
@ -33,6 +34,7 @@ class BalanceLine
public function __construct()
{
$this->balanceEntries = new Collection;
}
/**
@ -46,7 +48,7 @@ class BalanceLine
/**
* @return Collection
*/
public function getBalanceEntries()
public function getBalanceEntries(): Collection
{
return $this->balanceEntries;
}
@ -54,7 +56,7 @@ class BalanceLine
/**
* @param Collection $balanceEntries
*/
public function setBalanceEntries($balanceEntries)
public function setBalanceEntries(Collection $balanceEntries)
{
$this->balanceEntries = $balanceEntries;
}
@ -62,15 +64,15 @@ class BalanceLine
/**
* @return BudgetModel
*/
public function getBudget()
public function getBudget(): BudgetModel
{
return $this->budget;
return $this->budget ?? new BudgetModel;
}
/**
* @param BudgetModel $budget
*/
public function setBudget($budget)
public function setBudget(BudgetModel $budget)
{
$this->budget = $budget;
}
@ -78,7 +80,7 @@ class BalanceLine
/**
* @return int
*/
public function getRole()
public function getRole(): int
{
return $this->role;
}
@ -86,7 +88,7 @@ class BalanceLine
/**
* @param int $role
*/
public function setRole($role)
public function setRole(int $role)
{
$this->role = $role;
}
@ -94,9 +96,9 @@ class BalanceLine
/**
* @return string
*/
public function getTitle()
public function getTitle(): string
{
if ($this->getBudget() instanceof BudgetModel) {
if ($this->getBudget() instanceof BudgetModel && !is_null($this->getBudget()->id)) {
return $this->getBudget()->name;
}
if ($this->getRole() == self::ROLE_DEFAULTROLE) {
@ -118,14 +120,14 @@ class BalanceLine
* on the given budget/repetition. If you subtract all those amounts from the budget/repetition's
* total amount, this is returned:
*
* @return float
* @return string
*/
public function leftOfRepetition()
public function leftOfRepetition(): string
{
$start = isset($this->budget->amount) ? $this->budget->amount : 0;
$start = $this->budget->amount ?? '0';
/** @var BalanceEntry $balanceEntry */
foreach ($this->getBalanceEntries() as $balanceEntry) {
$start += $balanceEntry->getSpent();
$start = bcadd($balanceEntry->getSpent(), $start);
}
return $start;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
@ -38,7 +38,7 @@ class Bill
/**
* @return Collection
*/
public function getBills()
public function getBills(): Collection
{
$set = $this->bills->sortBy(
function (BillLine $bill) {

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use FireflyIII\Models\Bill as BillModel;
@ -27,18 +27,21 @@ class BillLine
/** @var string */
protected $min;
/** @var int */
private $transactionJournalId;
/**
* @return string
*/
public function getAmount()
public function getAmount(): string
{
return $this->amount;
return $this->amount ?? '0';
}
/**
* @param string $amount
*/
public function setAmount($amount)
public function setAmount(string $amount)
{
$this->amount = $amount;
}
@ -46,7 +49,7 @@ class BillLine
/**
* @return BillModel
*/
public function getBill()
public function getBill(): BillModel
{
return $this->bill;
}
@ -54,7 +57,7 @@ class BillLine
/**
* @param BillModel $bill
*/
public function setBill($bill)
public function setBill(BillModel $bill)
{
$this->bill = $bill;
}
@ -62,7 +65,7 @@ class BillLine
/**
* @return string
*/
public function getMax()
public function getMax(): string
{
return $this->max;
}
@ -70,7 +73,7 @@ class BillLine
/**
* @param string $max
*/
public function setMax($max)
public function setMax(string $max)
{
$this->max = $max;
}
@ -78,7 +81,7 @@ class BillLine
/**
* @return string
*/
public function getMin()
public function getMin(): string
{
return $this->min;
}
@ -86,23 +89,39 @@ class BillLine
/**
* @param string $min
*/
public function setMin($min)
public function setMin(string $min)
{
$this->min = $min;
}
/**
* @return int
*/
public function getTransactionJournalId(): int
{
return $this->transactionJournalId ?? 0;
}
/**
* @param int $transactionJournalId
*/
public function setTransactionJournalId(int $transactionJournalId)
{
$this->transactionJournalId = $transactionJournalId;
}
/**
* @return boolean
*/
public function isActive()
public function isActive(): bool
{
return $this->active;
}
/**
* @param boolean $active
* @param bool $active
*/
public function setActive($active)
public function setActive(bool $active)
{
$this->active = $active;
}
@ -110,15 +129,15 @@ class BillLine
/**
* @return boolean
*/
public function isHit()
public function isHit(): bool
{
return $this->hit;
}
/**
* @param boolean $hit
* @param bool $hit
*/
public function setHit($hit)
public function setHit(bool $hit)
{
$this->hit = $hit;
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use Illuminate\Support\Collection;
@ -41,49 +41,45 @@ class Budget
}
/**
* @param float $add
* @param string $add
*/
public function addBudgeted($add)
public function addBudgeted(string $add)
{
$add = strval(round($add, 2));
bcscale(2);
$add = strval(round($add, 2));
$this->budgeted = bcadd($this->budgeted, $add);
}
/**
* @param float $add
* @param string $add
*/
public function addLeft($add)
public function addLeft(string $add)
{
$add = strval(round($add, 2));
bcscale(2);
$add = strval(round($add, 2));
$this->left = bcadd($this->left, $add);
}
/**
* @param float $add
* @param string $add
*/
public function addOverspent($add)
public function addOverspent(string $add)
{
$add = strval(round($add, 2));
bcscale(2);
$add = strval(round($add, 2));
$this->overspent = bcadd($this->overspent, $add);
}
/**
* @param float $add
* @param string $add
*/
public function addSpent($add)
public function addSpent(string $add)
{
$add = strval(round($add, 2));
bcscale(2);
$add = strval(round($add, 2));
$this->spent = bcadd($this->spent, $add);
}
/**
* @return \Illuminate\Support\Collection
*/
public function getBudgetLines()
public function getBudgetLines(): Collection
{
return $this->budgetLines;
}
@ -91,7 +87,7 @@ class Budget
/**
* @return string
*/
public function getBudgeted()
public function getBudgeted(): string
{
return $this->budgeted;
}
@ -99,7 +95,7 @@ class Budget
/**
* @param string $budgeted
*/
public function setBudgeted($budgeted)
public function setBudgeted(string $budgeted)
{
$this->budgeted = $budgeted;
}
@ -107,7 +103,7 @@ class Budget
/**
* @return string
*/
public function getLeft()
public function getLeft(): string
{
return $this->left;
}
@ -115,7 +111,7 @@ class Budget
/**
* @param string $left
*/
public function setLeft($left)
public function setLeft(string $left)
{
$this->left = $left;
}
@ -123,7 +119,7 @@ class Budget
/**
* @return string
*/
public function getOverspent()
public function getOverspent(): string
{
return $this->overspent;
}
@ -131,7 +127,7 @@ class Budget
/**
* @param string $overspent
*/
public function setOverspent($overspent)
public function setOverspent(string $overspent)
{
$this->overspent = strval(round($overspent, 2));
}
@ -139,7 +135,7 @@ class Budget
/**
* @return string
*/
public function getSpent()
public function getSpent(): string
{
return $this->spent;
}
@ -147,7 +143,7 @@ class Budget
/**
* @param string $spent
*/
public function setSpent($spent)
public function setSpent(string $spent)
{
$this->spent = strval(round($spent, 2));
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use FireflyIII\Models\Budget as BudgetModel;
@ -17,77 +17,77 @@ class BudgetLine
/** @var BudgetModel */
protected $budget;
/** @var float */
protected $budgeted = 0;
/** @var float */
protected $left = 0;
/** @var float */
protected $overspent = 0;
/** @var string */
protected $budgeted = '0';
/** @var string */
protected $left = '0';
/** @var string */
protected $overspent = '0';
/** @var LimitRepetition */
protected $repetition;
/** @var float */
protected $spent = 0;
/** @var string */
protected $spent = '0';
/**
* @return BudgetModel
*/
public function getBudget()
public function getBudget(): BudgetModel
{
return $this->budget;
return $this->budget ?? new BudgetModel;
}
/**
* @param BudgetModel $budget
*/
public function setBudget($budget)
public function setBudget(BudgetModel $budget)
{
$this->budget = $budget;
}
/**
* @return float
* @return string
*/
public function getBudgeted()
public function getBudgeted(): string
{
return $this->budgeted;
}
/**
* @param float $budgeted
* @param string $budgeted
*/
public function setBudgeted($budgeted)
public function setBudgeted(string $budgeted)
{
$this->budgeted = $budgeted;
}
/**
* @return float
* @return string
*/
public function getLeft()
public function getLeft(): string
{
return $this->left;
}
/**
* @param float $left
* @param string $left
*/
public function setLeft($left)
public function setLeft(string $left)
{
$this->left = $left;
}
/**
* @return float
* @return string
*/
public function getOverspent()
public function getOverspent(): string
{
return $this->overspent;
}
/**
* @param float $overspent
* @param string $overspent
*/
public function setOverspent($overspent)
public function setOverspent(string $overspent)
{
$this->overspent = $overspent;
}
@ -95,31 +95,31 @@ class BudgetLine
/**
* @return LimitRepetition
*/
public function getRepetition()
public function getRepetition(): LimitRepetition
{
return $this->repetition;
return $this->repetition ?? new LimitRepetition;
}
/**
* @param LimitRepetition $repetition
*/
public function setRepetition($repetition)
public function setRepetition(LimitRepetition $repetition)
{
$this->repetition = $repetition;
}
/**
* @return float
* @return string
*/
public function getSpent()
public function getSpent(): string
{
return $this->spent;
}
/**
* @param float $spent
* @param string $spent
*/
public function setSpent($spent)
public function setSpent(string $spent)
{
$this->spent = $spent;
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use FireflyIII\Models\Category as CategoryModel;
@ -42,19 +42,18 @@ class Category
}
/**
* @param float $add
* @param string $add
*/
public function addTotal($add)
public function addTotal(string $add)
{
$add = strval(round($add, 2));
bcscale(2);
$add = strval(round($add, 2));
$this->total = bcadd($this->total, $add);
}
/**
* @return Collection
*/
public function getCategories()
public function getCategories(): Collection
{
$set = $this->categories->sortBy(
function (CategoryModel $category) {
@ -69,7 +68,7 @@ class Category
/**
* @return string
*/
public function getTotal()
public function getTotal(): string
{
return strval(round($this->total, 2));
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use Crypt;
@ -34,7 +34,6 @@ class Expense
*/
public function addOrCreateExpense(TransactionJournal $entry)
{
bcscale(2);
$accountId = $entry->account_id;
$amount = strval(round($entry->journalAmount, 2));
@ -58,11 +57,10 @@ class Expense
}
/**
* @param $add
* @param string $add
*/
public function addToTotal($add)
public function addToTotal(string $add)
{
bcscale(2);
$add = strval(round($add, 2));
@ -80,7 +78,7 @@ class Expense
/**
* @return Collection
*/
public function getExpenses()
public function getExpenses(): Collection
{
$set = $this->expenses->sortBy(
function (stdClass $object) {
@ -94,7 +92,7 @@ class Expense
/**
* @return string
*/
public function getTotal()
public function getTotal(): string
{
return strval(round($this->total, 2));
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Collection;
use Crypt;
@ -20,7 +20,7 @@ class Income
/** @var Collection */
protected $incomes;
/** @var string */
protected $total;
protected $total = '0';
/**
*
@ -45,7 +45,6 @@ class Income
$newObject->id = $accountId;
$this->incomes->put($accountId, $newObject);
} else {
bcscale(2);
$existing = $this->incomes->get($accountId);
$existing->amount = bcadd($existing->amount, $entry->journalAmount);
$existing->count++;
@ -54,19 +53,18 @@ class Income
}
/**
* @param $add
* @param string $add
*/
public function addToTotal($add)
public function addToTotal(string $add)
{
$add = strval(round($add, 2));
bcscale(2);
$add = strval(round($add, 2));
$this->total = bcadd($this->total, $add);
}
/**
* @return Collection
*/
public function getIncomes()
public function getIncomes(): Collection
{
$set = $this->incomes->sortByDesc(
function (stdClass $object) {
@ -80,7 +78,7 @@ class Income
/**
* @return string
*/
public function getTotal()
public function getTotal(): string
{
return strval(round($this->total, 2));
}

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
@ -16,7 +17,7 @@ class AccountId extends BasicConverter implements ConverterInterface
/**
* @return Account
*/
public function convert()
public function convert(): Account
{
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
@ -30,6 +31,9 @@ class AccountId extends BasicConverter implements ConverterInterface
if (!is_null($account)) {
Log::debug('Found ' . $account->accountType->type . ' named "******" with ID: ' . $this->value . ' (not mapped) ');
} else {
// new account to prevent TypeErrors.
$account = new Account;
}
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
/**
@ -11,14 +11,14 @@ class Amount extends BasicConverter implements ConverterInterface
{
/**
* @return string|int
* @return string
*/
public function convert()
public function convert(): string
{
if (is_numeric($this->value)) {
return $this->value;
return strval($this->value);
}
return 0;
return '0';
}
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
/**
@ -17,12 +17,12 @@ class AmountComma extends BasicConverter implements ConverterInterface
*/
public function convert()
{
$value = str_replace(',', '.', $this->value);
$value = str_replace(',', '.', strval($this->value));
if (is_numeric($value)) {
return floatval($value);
return strval($value);
}
return 0;
return '0';
}
}

View File

@ -1,10 +1,10 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use Carbon\Carbon;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
/**
* Class AssetAccountIban
@ -15,10 +15,11 @@ class AssetAccountIban extends BasicConverter implements ConverterInterface
{
/**
* @return Account|null
* @return Account
*/
public function convert()
public function convert(): Account
{
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
@ -27,32 +28,41 @@ class AssetAccountIban extends BasicConverter implements ConverterInterface
}
if (strlen($this->value) > 0) {
// find or create new account:
$account = $this->findAccount();
$accountType = AccountType::where('type', 'Asset account')->first();
$account = $this->findAccount();
if (is_null($account)) {
if (is_null($account->id)) {
// create it if doesn't exist.
$account = Account::firstOrCreateEncrypted(
[
'name' => $this->value,
'iban' => $this->value,
'user_id' => Auth::user()->id,
'account_type_id' => $accountType->id,
'active' => 1,
]
);
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$accountData = [
'name' => $this->value,
'accountType' => 'asset',
'virtualBalance' => 0,
'virtualBalanceCurrency' => 1, // hard coded.
'active' => true,
'user' => Auth::user()->id,
'iban' => null,
'accountNumber' => $this->value,
'accountRole' => null,
'openingBalance' => 0,
'openingBalanceDate' => new Carbon,
'openingBalanceCurrency' => 1, // hard coded.
];
$account = $repository->store($accountData);
}
return $account;
}
return null;
return new Account;
}
/**
* @return Account|null
* @return Account
*/
protected function findAccount()
protected function findAccount(): Account
{
$set = Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']);
/** @var Account $entry */
@ -63,6 +73,6 @@ class AssetAccountIban extends BasicConverter implements ConverterInterface
}
}
return null;
return new Account;
}
}

View File

@ -1,10 +1,10 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use Carbon\Carbon;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
/**
* Class AssetAccountName
@ -26,8 +26,7 @@ class AssetAccountName extends BasicConverter implements ConverterInterface
return $account;
}
// find or create new account:
$accountType = AccountType::where('type', 'Asset account')->first();
$set = Auth::user()->accounts()->accountTypeIn(['Asset account', 'Default account'])->get();
$set = Auth::user()->accounts()->accountTypeIn(['Asset account', 'Default account'])->get();
/** @var Account $entry */
foreach ($set as $entry) {
if ($entry->name == $this->value) {
@ -36,15 +35,25 @@ class AssetAccountName extends BasicConverter implements ConverterInterface
}
// create it if doesnt exist.
$account = Account::firstOrCreateEncrypted(
[
'name' => $this->value,
'iban' => '',
'user_id' => Auth::user()->id,
'account_type_id' => $accountType->id,
'active' => 1,
]
);
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$accountData = [
'name' => $this->value,
'accountType' => 'asset',
'virtualBalance' => 0,
'virtualBalanceCurrency' => 1, // hard coded.
'active' => true,
'user' => Auth::user()->id,
'iban' => null,
'accountNumber' => $this->value,
'accountRole' => null,
'openingBalance' => 0,
'openingBalanceDate' => new Carbon,
'openingBalanceCurrency' => 1, // hard coded.
];
$account = $repository->store($accountData);
return $account;
}

View File

@ -0,0 +1,89 @@
<?php
/**
* AssetAccountNumber.php
* Copyright (C) 2016 Sander Dorigo
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use Carbon\Carbon;
use FireflyIII\Models\Account;
/**
* Class AssetAccountNumber
*
* @package FireflyIII\Helpers\Csv\Converter
*/
class AssetAccountNumber extends BasicConverter implements ConverterInterface
{
/**
* @return Account|null
*/
public function convert()
{
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
return $account;
}
// if not, search for it (or create it):
$value = $this->value ?? '';
if (strlen($value) > 0) {
// find or create new account:
$account = $this->findAccount();
if (is_null($account->id)) {
// create it if doesn't exist.
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$accountData = [
'name' => $this->value,
'accountType' => 'asset',
'virtualBalance' => 0,
'virtualBalanceCurrency' => 1, // hard coded.
'active' => true,
'user' => Auth::user()->id,
'iban' => null,
'accountNumber' => $this->value,
'accountRole' => null,
'openingBalance' => 0,
'openingBalanceDate' => new Carbon,
'openingBalanceCurrency' => 1, // hard coded.
];
$account = $repository->store($accountData);
}
return $account;
}
return null;
}
/**
* @return Account
*/
protected function findAccount(): Account
{
$set = Auth::user()->accounts()->with(['accountmeta'])->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']);
/** @var Account $entry */
foreach ($set as $entry) {
$accountNumber = $entry->getMeta('accountNumber');
if ($accountNumber == $this->value) {
return $entry;
}
}
return new Account;
}
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
/**

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
@ -19,15 +20,10 @@ class BudgetName extends BasicConverter implements ConverterInterface
{
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$budget = Auth::user()->budgets()->find($this->mapped[$this->index][$this->value]);
$budget = Auth::user()->budgets()->find($this->mapped[$this->index][$this->value]); // see issue #180
} else {
$budget = Budget::firstOrCreateEncrypted(
[
'name' => $this->value,
'user_id' => Auth::user()->id,
'active' => true,
]
);
$repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$budget = $repository->store(['name' => $this->value, 'user' => Auth::user()->id]);
}
return $budget;

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;

View File

@ -1,4 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
@ -21,7 +22,7 @@ class CategoryName extends BasicConverter implements ConverterInterface
if (isset($this->mapped[$this->index][$this->value])) {
$category = Auth::user()->categories()->find($this->mapped[$this->index][$this->value]);
} else {
$category = Category::firstOrCreateEncrypted(
$category = Category::firstOrCreateEncrypted( // See issue #180
[
'name' => $this->value,
'user_id' => Auth::user()->id,

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
/**

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use FireflyIII\Models\TransactionCurrency;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use FireflyIII\Models\TransactionCurrency;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use FireflyIII\Models\TransactionCurrency;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use FireflyIII\Models\TransactionCurrency;

View File

@ -1,12 +1,11 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use InvalidArgumentException;
use Log;
use Session;
/**
* Class Date
@ -22,7 +21,7 @@ class Date extends BasicConverter implements ConverterInterface
*/
public function convert()
{
$format = Session::get('csv-date-format');
$format = session('csv-date-format');
try {
$date = Carbon::createFromFormat($format, $this->value);
} catch (InvalidArgumentException $e) {

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
/**
@ -16,6 +16,8 @@ class Description extends BasicConverter implements ConverterInterface
*/
public function convert()
{
return trim($this->data['description'] . ' ' . $this->value);
$description = $this->data['description'] ?? '';
return trim($description . ' ' . $this->value);
}
}

View File

@ -0,0 +1,34 @@
<?php
/**
* INGDebetCredit.php
* Copyright (C) 2016 Sander Dorigo
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
/**
* Class INGDebetCredit
*
* @package FireflyIII\Helpers\Csv\Converter
*/
class INGDebetCredit extends BasicConverter implements ConverterInterface
{
/**
* @return int
*/
public function convert()
{
if ($this->value === 'Af') {
return -1;
}
return 1;
}
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
/**

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
@ -23,7 +23,7 @@ class TagsComma extends BasicConverter implements ConverterInterface
$strings = explode(',', $this->value);
foreach ($strings as $string) {
$tag = Tag::firstOrCreateEncrypted(
$tag = Tag::firstOrCreateEncrypted( // See issue #180
[
'tag' => $string,
'tagMode' => 'nothing',

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
@ -23,7 +23,7 @@ class TagsSpace extends BasicConverter implements ConverterInterface
$strings = explode(' ', $this->value);
foreach ($strings as $string) {
$tag = Tag::firstOrCreateEncrypted(
$tag = Tag::firstOrCreateEncrypted( // See issue #180
[
'tag' => $string,
'tagMode' => 'nothing',

View File

@ -1,9 +1,11 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv;
use Crypt;
use League\Csv\Reader;
use Session;
use Storage;
/**
* Class Data
@ -14,13 +16,13 @@ class Data
{
/** @var string */
protected $csvFileContent;
protected $csvFileContent = '';
/** @var string */
protected $csvFileLocation;
protected $csvFileLocation = '';
/** @var string */
protected $dateFormat;
protected $dateFormat = '';
/** @var string */
protected $delimiter;
protected $delimiter = '';
/** @var bool */
protected $hasHeaders;
/** @var int */
@ -57,14 +59,14 @@ class Data
*/
public function getCsvFileContent()
{
return $this->csvFileContent;
return $this->csvFileContent ?? '';
}
/**
*
* @param string $csvFileContent
*/
public function setCsvFileContent($csvFileContent)
public function setCsvFileContent(string $csvFileContent)
{
$this->csvFileContent = $csvFileContent;
}
@ -82,7 +84,7 @@ class Data
*
* @param string $csvFileLocation
*/
public function setCsvFileLocation($csvFileLocation)
public function setCsvFileLocation(string $csvFileLocation)
{
Session::put('csv-file', $csvFileLocation);
$this->csvFileLocation = $csvFileLocation;
@ -99,9 +101,9 @@ class Data
/**
*
* @param mixed $dateFormat
* @param string $dateFormat
*/
public function setDateFormat($dateFormat)
public function setDateFormat(string $dateFormat)
{
Session::put('csv-date-format', $dateFormat);
$this->dateFormat = $dateFormat;
@ -120,7 +122,7 @@ class Data
*
* @param string $delimiter
*/
public function setDelimiter($delimiter)
public function setDelimiter(string $delimiter)
{
Session::put('csv-delimiter', $delimiter);
$this->delimiter = $delimiter;
@ -170,7 +172,7 @@ class Data
*/
public function getReader()
{
if (strlen($this->csvFileContent) === 0) {
if (!is_null($this->csvFileContent) && strlen($this->csvFileContent) === 0) {
$this->loadCsvFile();
}
@ -233,7 +235,7 @@ class Data
*
* @param bool $hasHeaders
*/
public function setHasHeaders($hasHeaders)
public function setHasHeaders(bool $hasHeaders)
{
Session::put('csv-has-headers', $hasHeaders);
$this->hasHeaders = $hasHeaders;
@ -243,7 +245,7 @@ class Data
*
* @param int $importAccount
*/
public function setImportAccount($importAccount)
public function setImportAccount(int $importAccount)
{
Session::put('csv-import-account', $importAccount);
$this->importAccount = $importAccount;
@ -252,7 +254,8 @@ class Data
protected function loadCsvFile()
{
$file = $this->getCsvFileLocation();
$content = file_get_contents($file);
$disk = Storage::disk('upload');
$content = $disk->get($file);
$contentDecrypted = Crypt::decrypt($content);
$this->setCsvFileContent($contentDecrypted);
}
@ -260,63 +263,63 @@ class Data
protected function sessionCsvFileLocation()
{
if (Session::has('csv-file')) {
$this->csvFileLocation = (string)Session::get('csv-file');
$this->csvFileLocation = (string)session('csv-file');
}
}
protected function sessionDateFormat()
{
if (Session::has('csv-date-format')) {
$this->dateFormat = (string)Session::get('csv-date-format');
$this->dateFormat = (string)session('csv-date-format');
}
}
protected function sessionDelimiter()
{
if (Session::has('csv-delimiter')) {
$this->delimiter = Session::get('csv-delimiter');
$this->delimiter = session('csv-delimiter');
}
}
protected function sessionHasHeaders()
{
if (Session::has('csv-has-headers')) {
$this->hasHeaders = (bool)Session::get('csv-has-headers');
$this->hasHeaders = (bool)session('csv-has-headers');
}
}
protected function sessionImportAccount()
{
if (Session::has('csv-import-account')) {
$this->importAccount = intval(Session::get('csv-import-account'));
$this->importAccount = intval(session('csv-import-account'));
}
}
protected function sessionMap()
{
if (Session::has('csv-map')) {
$this->map = (array)Session::get('csv-map');
$this->map = (array)session('csv-map');
}
}
protected function sessionMapped()
{
if (Session::has('csv-mapped')) {
$this->mapped = (array)Session::get('csv-mapped');
$this->mapped = (array)session('csv-mapped');
}
}
protected function sessionRoles()
{
if (Session::has('csv-roles')) {
$this->roles = (array)Session::get('csv-roles');
$this->roles = (array)session('csv-roles');
}
}
protected function sessionSpecifix()
{
if (Session::has('csv-specifix')) {
$this->specifix = (array)Session::get('csv-specifix');
$this->specifix = (array)session('csv-specifix');
}
}
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv;
use Auth;
@ -136,7 +136,7 @@ class Importer
/**
* @param Data $data
*/
public function setData($data)
public function setData(Data $data)
{
$this->data = $data;
}
@ -147,7 +147,6 @@ class Importer
*/
protected function createTransactionJournal()
{
bcscale(2);
$date = $this->importData['date'];
if (is_null($this->importData['date'])) {
$date = $this->importData['date-rent'];
@ -169,7 +168,7 @@ class Importer
// second transaction
$accountId = $this->importData['opposing-account-object']->id; // create second transaction:
$amount = bcmul($this->importData['amount'], -1);
$amount = bcmul($this->importData['amount'], '-1');
$transaction = Transaction::create(['transaction_journal_id' => $journal->id, 'account_id' => $accountId, 'amount' => $amount]);
$errors = $transaction->getErrors()->merge($errors);
}
@ -187,7 +186,7 @@ class Importer
// some debug info:
$journalId = $journal->id;
$type = $journal->getTransactionType();
$type = $journal->transaction_type_type ?? $journal->transactionType->type;
/** @var Account $asset */
$asset = $this->importData['asset-account-object'];
/** @var Account $opposing */
@ -195,7 +194,7 @@ class Importer
Log::info('Created journal #' . $journalId . ' of type ' . $type . '!');
Log::info('Asset account #' . $asset->id . ' lost/gained: ' . $this->importData['amount']);
Log::info($opposing->accountType->type . ' #' . $opposing->id . ' lost/gained: ' . bcmul($this->importData['amount'], -1));
Log::info($opposing->accountType->type . ' #' . $opposing->id . ' lost/gained: ' . bcmul($this->importData['amount'], '-1'));
return $journal;
}
@ -218,17 +217,17 @@ class Importer
}
/**
* @param $row
* @param array $row
*
* @throws FireflyException
* @return string|bool
*/
protected function importRow($row)
protected function importRow(array $row)
{
$data = $this->getFiller(); // These fields are necessary to create a new transaction journal. Some are optional
foreach ($row as $index => $value) {
$role = isset($this->roles[$index]) ? $this->roles[$index] : '_ignore';
$role = $this->roles[$index] ?? '_ignore';
$class = Config::get('csv.roles.' . $role . '.converter');
$field = Config::get('csv.roles.' . $role . '.field');
@ -266,7 +265,7 @@ class Importer
*
* @return bool
*/
protected function parseRow($index)
protected function parseRow(int $index)
{
return (($this->data->hasHeaders() && $index >= 1) || !$this->data->hasHeaders());
}
@ -296,7 +295,8 @@ class Importer
foreach ($set as $className) {
/** @var PostProcessorInterface $postProcessor */
$postProcessor = app('FireflyIII\Helpers\Csv\PostProcessing\\' . $className);
$postProcessor->setData($this->importData);
$array = $this->importData ?? [];
$postProcessor->setData($array);
Log::debug('Now post-process processor named ' . $className . ':');
$this->importData = $postProcessor->process();
}
@ -343,7 +343,9 @@ class Importer
*/
protected function validateData()
{
if (is_null($this->importData['date']) && is_null($this->importData['date-rent'])) {
$date = $this->importData['date'] ?? null;
$rentDate = $this->importData['date-rent'] ?? null;
if (is_null($date) && is_null($rentDate)) {
return 'No date value for this row.';
}
if (is_null($this->importData['opposing-account-object'])) {
@ -368,8 +370,8 @@ class Importer
/** @var Rule $rule */
foreach ($group->rules as $rule) {
$processor = new Processor($rule, $journal);
$processor->handle();
$processor = Processor::make($rule);
$processor->handleTransactionJournal($journal);
if ($rule->stop_processing) {
break;
}

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;
use Auth;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;
use Auth;
@ -30,7 +30,8 @@ class AssetAccount implements MapperInterface
/** @var Account $account */
foreach ($result as $account) {
$name = $account->name;
if (strlen($account->iban) > 0) {
$iban = $account->iban ?? '';
if (strlen($iban) > 0) {
$name .= ' (' . $account->iban . ')';
}
$list[$account->id] = $name;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;
use Auth;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;
use Auth;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;
use Auth;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;
/**

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;
use Auth;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Mapper;
use FireflyIII\Models\TransactionCurrency as TC;

View File

@ -1,5 +1,5 @@
<?php
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\PostProcessing;
@ -19,8 +19,9 @@ class Amount implements PostProcessorInterface
*/
public function process()
{
bcscale(2);
$this->data['amount'] = bcmul($this->data['amount'], $this->data['amount-modifier']);
$amount = $this->data['amount'] ?? '0';
$modifier = strval($this->data['amount-modifier']);
$this->data['amount'] = bcmul($amount, $modifier);
return $this->data;
}

Some files were not shown because too many files have changed in this diff Show More