mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-30 02:26:58 +00:00
Code rearrangement.
This commit is contained in:
@@ -12,19 +12,18 @@ use Illuminate\Console\Command;
|
|||||||
*/
|
*/
|
||||||
class UpgradeFireflyInstructions extends Command
|
class UpgradeFireflyInstructions extends Command
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* The name and signature of the console command.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $signature = 'firefly:upgrade-instructions';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The console command description.
|
* The console command description.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $description = 'Command description';
|
protected $description = 'Command description';
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'firefly:upgrade-instructions';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new command instance.
|
* Create a new command instance.
|
||||||
|
@@ -27,7 +27,7 @@ class Kernel extends ConsoleKernel
|
|||||||
*/
|
*/
|
||||||
protected $commands
|
protected $commands
|
||||||
= [
|
= [
|
||||||
UpgradeFireflyInstructions::class
|
UpgradeFireflyInstructions::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -14,6 +14,15 @@ use Illuminate\Support\Collection;
|
|||||||
interface AccountChartGenerator
|
interface AccountChartGenerator
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $accounts
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
@@ -31,13 +40,4 @@ interface AccountChartGenerator
|
|||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function single(Account $account, Carbon $start, Carbon $end);
|
public function single(Account $account, Carbon $start, Carbon $end);
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Collection $accounts
|
|
||||||
* @param Carbon $start
|
|
||||||
* @param Carbon $end
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function expenseAccounts(Collection $accounts, Carbon $start, Carbon $end);
|
|
||||||
}
|
}
|
||||||
|
@@ -62,22 +62,6 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
|||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $array
|
|
||||||
* @param $entryId
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function isInArray($array, $entryId)
|
|
||||||
{
|
|
||||||
if (isset($array[$entryId])) {
|
|
||||||
return $array[$entryId];
|
|
||||||
}
|
|
||||||
|
|
||||||
return '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
@@ -179,4 +163,19 @@ class ChartJsAccountChartGenerator implements AccountChartGenerator
|
|||||||
return array_unique($ids);
|
return array_unique($ids);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $array
|
||||||
|
* @param $entryId
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function isInArray($array, $entryId)
|
||||||
|
{
|
||||||
|
if (isset($array[$entryId])) {
|
||||||
|
return $array[$entryId];
|
||||||
|
}
|
||||||
|
|
||||||
|
return '0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -106,6 +106,40 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
|||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $entries
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function multiYear(Collection $entries)
|
||||||
|
{
|
||||||
|
// dataset:
|
||||||
|
$data = [
|
||||||
|
'count' => 0,
|
||||||
|
'labels' => [],
|
||||||
|
'datasets' => [],
|
||||||
|
];
|
||||||
|
// get labels from one of the budgets (assuming there's at least one):
|
||||||
|
$first = $entries->first();
|
||||||
|
$keys = array_keys($first['budgeted']);
|
||||||
|
foreach ($keys as $year) {
|
||||||
|
$data['labels'][] = strval($year);
|
||||||
|
}
|
||||||
|
|
||||||
|
// then, loop all entries and create datasets:
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$name = $entry['name'];
|
||||||
|
$spent = $entry['spent'];
|
||||||
|
$budgeted = $entry['budgeted'];
|
||||||
|
$data['datasets'][] = ['label' => 'Spent on ' . $name, 'data' => array_values($spent)];
|
||||||
|
$data['datasets'][] = ['label' => 'Budgeted for ' . $name, 'data' => array_values($budgeted)];
|
||||||
|
}
|
||||||
|
$data['count'] = count($data['datasets']);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $budgets
|
* @param Collection $budgets
|
||||||
* @param Collection $entries
|
* @param Collection $entries
|
||||||
@@ -140,38 +174,4 @@ class ChartJsBudgetChartGenerator implements BudgetChartGenerator
|
|||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Collection $entries
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function multiYear(Collection $entries)
|
|
||||||
{
|
|
||||||
// dataset:
|
|
||||||
$data = [
|
|
||||||
'count' => 0,
|
|
||||||
'labels' => [],
|
|
||||||
'datasets' => [],
|
|
||||||
];
|
|
||||||
// get labels from one of the budgets (assuming there's at least one):
|
|
||||||
$first = $entries->first();
|
|
||||||
$keys = array_keys($first['budgeted']);
|
|
||||||
foreach ($keys as $year) {
|
|
||||||
$data['labels'][] = strval($year);
|
|
||||||
}
|
|
||||||
|
|
||||||
// then, loop all entries and create datasets:
|
|
||||||
foreach ($entries as $entry) {
|
|
||||||
$name = $entry['name'];
|
|
||||||
$spent = $entry['spent'];
|
|
||||||
$budgeted = $entry['budgeted'];
|
|
||||||
$data['datasets'][] = ['label' => 'Spent on ' . $name, 'data' => array_values($spent)];
|
|
||||||
$data['datasets'][] = ['label' => 'Budgeted for ' . $name, 'data' => array_values($budgeted)];
|
|
||||||
}
|
|
||||||
$data['count'] = count($data['datasets']);
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -19,14 +19,14 @@ use Symfony\Component\HttpFoundation\File\UploadedFile;
|
|||||||
class AttachmentHelper implements AttachmentHelperInterface
|
class AttachmentHelper implements AttachmentHelperInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
/** @var int */
|
|
||||||
protected $maxUploadSize;
|
|
||||||
/** @var array */
|
|
||||||
protected $allowedMimes;
|
|
||||||
/** @var MessageBag */
|
/** @var MessageBag */
|
||||||
public $errors;
|
public $errors;
|
||||||
/** @var MessageBag */
|
/** @var MessageBag */
|
||||||
public $messages;
|
public $messages;
|
||||||
|
/** @var array */
|
||||||
|
protected $allowedMimes;
|
||||||
|
/** @var int */
|
||||||
|
protected $maxUploadSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -51,6 +51,22 @@ class AttachmentHelper implements AttachmentHelperInterface
|
|||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return MessageBag
|
||||||
|
*/
|
||||||
|
public function getErrors()
|
||||||
|
{
|
||||||
|
return $this->errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return MessageBag
|
||||||
|
*/
|
||||||
|
public function getMessages()
|
||||||
|
{
|
||||||
|
return $this->messages;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Model $model
|
* @param Model $model
|
||||||
*
|
*
|
||||||
@@ -98,27 +114,6 @@ class AttachmentHelper implements AttachmentHelperInterface
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param UploadedFile $file
|
|
||||||
* @param Model $model
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
protected function validateUpload(UploadedFile $file, Model $model)
|
|
||||||
{
|
|
||||||
if (!$this->validMime($file)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!$this->validSize($file)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if ($this->hasFile($file, $model)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param UploadedFile $file
|
* @param UploadedFile $file
|
||||||
* @param Model $model
|
* @param Model $model
|
||||||
@@ -205,19 +200,24 @@ class AttachmentHelper implements AttachmentHelperInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return MessageBag
|
* @param UploadedFile $file
|
||||||
|
* @param Model $model
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function getErrors()
|
protected function validateUpload(UploadedFile $file, Model $model)
|
||||||
{
|
{
|
||||||
return $this->errors;
|
if (!$this->validMime($file)) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
if (!$this->validSize($file)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ($this->hasFile($file, $model)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
return true;
|
||||||
* @return MessageBag
|
|
||||||
*/
|
|
||||||
public function getMessages()
|
|
||||||
{
|
|
||||||
return $this->messages;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -15,11 +15,11 @@ interface AttachmentHelperInterface
|
|||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Model $model
|
* @param Attachment $attachment
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function saveAttachmentsForModel(Model $model);
|
public function getAttachmentLocation(Attachment $attachment);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return MessageBag
|
* @return MessageBag
|
||||||
@@ -32,10 +32,10 @@ interface AttachmentHelperInterface
|
|||||||
public function getMessages();
|
public function getMessages();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Attachment $attachment
|
* @param Model $model
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function getAttachmentLocation(Attachment $attachment);
|
public function saveAttachmentsForModel(Model $model);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -15,36 +15,26 @@ class Data
|
|||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
protected $csvFileContent;
|
protected $csvFileContent;
|
||||||
|
|
||||||
/** @var string */
|
|
||||||
protected $delimiter;
|
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
protected $csvFileLocation;
|
protected $csvFileLocation;
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
protected $dateFormat;
|
protected $dateFormat;
|
||||||
|
/** @var string */
|
||||||
|
protected $delimiter;
|
||||||
/** @var bool */
|
/** @var bool */
|
||||||
protected $hasHeaders;
|
protected $hasHeaders;
|
||||||
|
|
||||||
/** @var array */
|
|
||||||
protected $map = [];
|
|
||||||
|
|
||||||
/** @var array */
|
|
||||||
protected $mapped = [];
|
|
||||||
|
|
||||||
/** @var Reader */
|
|
||||||
protected $reader;
|
|
||||||
|
|
||||||
/** @var array */
|
|
||||||
protected $roles = [];
|
|
||||||
|
|
||||||
/** @var array */
|
|
||||||
protected $specifix = [];
|
|
||||||
|
|
||||||
/** @var int */
|
/** @var int */
|
||||||
protected $importAccount = 0;
|
protected $importAccount = 0;
|
||||||
|
/** @var array */
|
||||||
|
protected $map = [];
|
||||||
|
/** @var array */
|
||||||
|
protected $mapped = [];
|
||||||
|
/** @var Reader */
|
||||||
|
protected $reader;
|
||||||
|
/** @var array */
|
||||||
|
protected $roles = [];
|
||||||
|
/** @var array */
|
||||||
|
protected $specifix = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
@@ -61,67 +51,41 @@ class Data
|
|||||||
$this->sessionDelimiter();
|
$this->sessionDelimiter();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function sessionHasHeaders()
|
/**
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCsvFileContent()
|
||||||
{
|
{
|
||||||
if (Session::has('csv-has-headers')) {
|
return $this->csvFileContent;
|
||||||
$this->hasHeaders = (bool)Session::get('csv-has-headers');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function sessionImportAccount()
|
/**
|
||||||
|
*
|
||||||
|
* @param string $csvFileContent
|
||||||
|
*/
|
||||||
|
public function setCsvFileContent($csvFileContent)
|
||||||
{
|
{
|
||||||
if (Session::has('csv-import-account')) {
|
$this->csvFileContent = $csvFileContent;
|
||||||
$this->importAccount = intval(Session::get('csv-import-account'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function sessionDateFormat()
|
/**
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCsvFileLocation()
|
||||||
{
|
{
|
||||||
if (Session::has('csv-date-format')) {
|
return $this->csvFileLocation;
|
||||||
$this->dateFormat = (string)Session::get('csv-date-format');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function sessionCsvFileLocation()
|
/**
|
||||||
|
*
|
||||||
|
* @param string $csvFileLocation
|
||||||
|
*/
|
||||||
|
public function setCsvFileLocation($csvFileLocation)
|
||||||
{
|
{
|
||||||
if (Session::has('csv-file')) {
|
Session::put('csv-file', $csvFileLocation);
|
||||||
$this->csvFileLocation = (string)Session::get('csv-file');
|
$this->csvFileLocation = $csvFileLocation;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function sessionMap()
|
|
||||||
{
|
|
||||||
if (Session::has('csv-map')) {
|
|
||||||
$this->map = (array)Session::get('csv-map');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function sessionRoles()
|
|
||||||
{
|
|
||||||
if (Session::has('csv-roles')) {
|
|
||||||
$this->roles = (array)Session::get('csv-roles');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function sessionMapped()
|
|
||||||
{
|
|
||||||
if (Session::has('csv-mapped')) {
|
|
||||||
$this->mapped = (array)Session::get('csv-mapped');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function sessionSpecifix()
|
|
||||||
{
|
|
||||||
if (Session::has('csv-specifix')) {
|
|
||||||
$this->specifix = (array)Session::get('csv-specifix');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function sessionDelimiter()
|
|
||||||
{
|
|
||||||
if (Session::has('csv-delimiter')) {
|
|
||||||
$this->delimiter = Session::get('csv-delimiter');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,31 +109,21 @@ class Data
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param int $importAccount
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function setImportAccount($importAccount)
|
public function getDelimiter()
|
||||||
{
|
{
|
||||||
Session::put('csv-import-account', $importAccount);
|
return $this->delimiter;
|
||||||
$this->importAccount = $importAccount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return bool
|
* @param string $delimiter
|
||||||
*/
|
*/
|
||||||
public function hasHeaders()
|
public function setDelimiter($delimiter)
|
||||||
{
|
{
|
||||||
return $this->hasHeaders;
|
Session::put('csv-delimiter', $delimiter);
|
||||||
}
|
$this->delimiter = $delimiter;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param bool $hasHeaders
|
|
||||||
*/
|
|
||||||
public function setHasHeaders($hasHeaders)
|
|
||||||
{
|
|
||||||
Session::put('csv-has-headers', $hasHeaders);
|
|
||||||
$this->hasHeaders = $hasHeaders;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -228,51 +182,6 @@ class Data
|
|||||||
return $this->reader;
|
return $this->reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function loadCsvFile()
|
|
||||||
{
|
|
||||||
$file = $this->getCsvFileLocation();
|
|
||||||
$content = file_get_contents($file);
|
|
||||||
$contentDecrypted = Crypt::decrypt($content);
|
|
||||||
$this->setCsvFileContent($contentDecrypted);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getCsvFileLocation()
|
|
||||||
{
|
|
||||||
return $this->csvFileLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param string $csvFileLocation
|
|
||||||
*/
|
|
||||||
public function setCsvFileLocation($csvFileLocation)
|
|
||||||
{
|
|
||||||
Session::put('csv-file', $csvFileLocation);
|
|
||||||
$this->csvFileLocation = $csvFileLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getCsvFileContent()
|
|
||||||
{
|
|
||||||
return $this->csvFileContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param string $csvFileContent
|
|
||||||
*/
|
|
||||||
public function setCsvFileContent($csvFileContent)
|
|
||||||
{
|
|
||||||
$this->csvFileContent = $csvFileContent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
@@ -313,20 +222,101 @@ class Data
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return string
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function getDelimiter()
|
public function hasHeaders()
|
||||||
{
|
{
|
||||||
return $this->delimiter;
|
return $this->hasHeaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param string $delimiter
|
* @param bool $hasHeaders
|
||||||
*/
|
*/
|
||||||
public function setDelimiter($delimiter)
|
public function setHasHeaders($hasHeaders)
|
||||||
{
|
{
|
||||||
Session::put('csv-delimiter', $delimiter);
|
Session::put('csv-has-headers', $hasHeaders);
|
||||||
$this->delimiter = $delimiter;
|
$this->hasHeaders = $hasHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param int $importAccount
|
||||||
|
*/
|
||||||
|
public function setImportAccount($importAccount)
|
||||||
|
{
|
||||||
|
Session::put('csv-import-account', $importAccount);
|
||||||
|
$this->importAccount = $importAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadCsvFile()
|
||||||
|
{
|
||||||
|
$file = $this->getCsvFileLocation();
|
||||||
|
$content = file_get_contents($file);
|
||||||
|
$contentDecrypted = Crypt::decrypt($content);
|
||||||
|
$this->setCsvFileContent($contentDecrypted);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function sessionCsvFileLocation()
|
||||||
|
{
|
||||||
|
if (Session::has('csv-file')) {
|
||||||
|
$this->csvFileLocation = (string)Session::get('csv-file');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function sessionDateFormat()
|
||||||
|
{
|
||||||
|
if (Session::has('csv-date-format')) {
|
||||||
|
$this->dateFormat = (string)Session::get('csv-date-format');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function sessionDelimiter()
|
||||||
|
{
|
||||||
|
if (Session::has('csv-delimiter')) {
|
||||||
|
$this->delimiter = Session::get('csv-delimiter');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function sessionHasHeaders()
|
||||||
|
{
|
||||||
|
if (Session::has('csv-has-headers')) {
|
||||||
|
$this->hasHeaders = (bool)Session::get('csv-has-headers');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function sessionImportAccount()
|
||||||
|
{
|
||||||
|
if (Session::has('csv-import-account')) {
|
||||||
|
$this->importAccount = intval(Session::get('csv-import-account'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function sessionMap()
|
||||||
|
{
|
||||||
|
if (Session::has('csv-map')) {
|
||||||
|
$this->map = (array)Session::get('csv-map');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function sessionMapped()
|
||||||
|
{
|
||||||
|
if (Session::has('csv-mapped')) {
|
||||||
|
$this->mapped = (array)Session::get('csv-mapped');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function sessionRoles()
|
||||||
|
{
|
||||||
|
if (Session::has('csv-roles')) {
|
||||||
|
$this->roles = (array)Session::get('csv-roles');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function sessionSpecifix()
|
||||||
|
{
|
||||||
|
if (Session::has('csv-specifix')) {
|
||||||
|
$this->specifix = (array)Session::get('csv-specifix');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,8 @@ class Importer
|
|||||||
protected $importRow;
|
protected $importRow;
|
||||||
/** @var int */
|
/** @var int */
|
||||||
protected $imported = 0;
|
protected $imported = 0;
|
||||||
|
/** @var Collection */
|
||||||
|
protected $journals;
|
||||||
/** @var array */
|
/** @var array */
|
||||||
protected $map;
|
protected $map;
|
||||||
/** @var array */
|
/** @var array */
|
||||||
@@ -45,9 +47,6 @@ class Importer
|
|||||||
/** @var array */
|
/** @var array */
|
||||||
protected $specifix = [];
|
protected $specifix = [];
|
||||||
|
|
||||||
/** @var Collection */
|
|
||||||
protected $journals;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by CsvController.
|
* Used by CsvController.
|
||||||
*
|
*
|
||||||
@@ -68,6 +67,14 @@ class Importer
|
|||||||
return $this->imported;
|
return $this->imported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function getJournals()
|
||||||
|
{
|
||||||
|
return $this->journals;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by CsvController
|
* Used by CsvController
|
||||||
*
|
*
|
||||||
@@ -79,14 +86,13 @@ class Importer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getJournals()
|
public function getSpecifix()
|
||||||
{
|
{
|
||||||
return $this->journals;
|
return is_array($this->specifix) ? $this->specifix : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws FireflyException
|
* @throws FireflyException
|
||||||
*/
|
*/
|
||||||
@@ -118,136 +124,11 @@ class Importer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $index
|
* @param Data $data
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
*/
|
||||||
protected function parseRow($index)
|
public function setData($data)
|
||||||
{
|
{
|
||||||
return (($this->data->hasHeaders() && $index >= 1) || !$this->data->hasHeaders());
|
$this->data = $data;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $row
|
|
||||||
*
|
|
||||||
* @throws FireflyException
|
|
||||||
* @return string|bool
|
|
||||||
*/
|
|
||||||
protected function importRow($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';
|
|
||||||
$class = Config::get('csv.roles.' . $role . '.converter');
|
|
||||||
$field = Config::get('csv.roles.' . $role . '.field');
|
|
||||||
|
|
||||||
Log::debug('Column #' . $index . ' (role: ' . $role . ') : converter ' . $class . ' stores its data into field ' . $field . ':');
|
|
||||||
|
|
||||||
/** @var ConverterInterface $converter */
|
|
||||||
$converter = app('FireflyIII\Helpers\Csv\Converter\\' . $class);
|
|
||||||
$converter->setData($data); // the complete array so far.
|
|
||||||
$converter->setField($field);
|
|
||||||
$converter->setIndex($index);
|
|
||||||
$converter->setMapped($this->mapped);
|
|
||||||
$converter->setValue($value);
|
|
||||||
$converter->setRole($role);
|
|
||||||
$data[$field] = $converter->convert();
|
|
||||||
}
|
|
||||||
// move to class vars.
|
|
||||||
$this->importData = $data;
|
|
||||||
$this->importRow = $row;
|
|
||||||
unset($data, $row);
|
|
||||||
// post processing and validating.
|
|
||||||
$this->postProcess();
|
|
||||||
$result = $this->validateData();
|
|
||||||
|
|
||||||
if (!($result === true)) {
|
|
||||||
return $result; // return error.
|
|
||||||
}
|
|
||||||
$journal = $this->createTransactionJournal();
|
|
||||||
|
|
||||||
return $journal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function getFiller()
|
|
||||||
{
|
|
||||||
$filler = [];
|
|
||||||
foreach (Config::get('csv.roles') as $role) {
|
|
||||||
if (isset($role['field'])) {
|
|
||||||
$fieldName = $role['field'];
|
|
||||||
$filler[$fieldName] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// some extra's:
|
|
||||||
$filler['bill-id'] = null;
|
|
||||||
$filler['opposing-account-object'] = null;
|
|
||||||
$filler['asset-account-object'] = null;
|
|
||||||
$filler['amount-modifier'] = '1';
|
|
||||||
|
|
||||||
return $filler;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Row denotes the original data.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function postProcess()
|
|
||||||
{
|
|
||||||
// do bank specific fixes (must be enabled but now all of them.
|
|
||||||
|
|
||||||
foreach ($this->getSpecifix() as $className) {
|
|
||||||
/** @var SpecifixInterface $specifix */
|
|
||||||
$specifix = app('FireflyIII\Helpers\Csv\Specifix\\' . $className);
|
|
||||||
$specifix->setData($this->importData);
|
|
||||||
$specifix->setRow($this->importRow);
|
|
||||||
Log::debug('Now post-process specifix named ' . $className . ':');
|
|
||||||
$this->importData = $specifix->fix();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$set = Config::get('csv.post_processors');
|
|
||||||
foreach ($set as $className) {
|
|
||||||
/** @var PostProcessorInterface $postProcessor */
|
|
||||||
$postProcessor = app('FireflyIII\Helpers\Csv\PostProcessing\\' . $className);
|
|
||||||
$postProcessor->setData($this->importData);
|
|
||||||
Log::debug('Now post-process processor named ' . $className . ':');
|
|
||||||
$this->importData = $postProcessor->process();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getSpecifix()
|
|
||||||
{
|
|
||||||
return is_array($this->specifix) ? $this->specifix : [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @return bool|string
|
|
||||||
*/
|
|
||||||
protected function validateData()
|
|
||||||
{
|
|
||||||
if (is_null($this->importData['date']) && is_null($this->importData['date-rent'])) {
|
|
||||||
return 'No date value for this row.';
|
|
||||||
}
|
|
||||||
if (is_null($this->importData['opposing-account-object'])) {
|
|
||||||
return 'Opposing account is null';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!($this->importData['asset-account-object'] instanceof Account)) {
|
|
||||||
return 'No asset account to import into.';
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -309,6 +190,28 @@ class Importer
|
|||||||
return $journal;
|
return $journal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getFiller()
|
||||||
|
{
|
||||||
|
$filler = [];
|
||||||
|
foreach (Config::get('csv.roles') as $role) {
|
||||||
|
if (isset($role['field'])) {
|
||||||
|
$fieldName = $role['field'];
|
||||||
|
$filler[$fieldName] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// some extra's:
|
||||||
|
$filler['bill-id'] = null;
|
||||||
|
$filler['opposing-account-object'] = null;
|
||||||
|
$filler['asset-account-object'] = null;
|
||||||
|
$filler['amount-modifier'] = '1';
|
||||||
|
|
||||||
|
return $filler;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return TransactionType
|
* @return TransactionType
|
||||||
*/
|
*/
|
||||||
@@ -326,6 +229,89 @@ class Importer
|
|||||||
return $transactionType;
|
return $transactionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $row
|
||||||
|
*
|
||||||
|
* @throws FireflyException
|
||||||
|
* @return string|bool
|
||||||
|
*/
|
||||||
|
protected function importRow($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';
|
||||||
|
$class = Config::get('csv.roles.' . $role . '.converter');
|
||||||
|
$field = Config::get('csv.roles.' . $role . '.field');
|
||||||
|
|
||||||
|
Log::debug('Column #' . $index . ' (role: ' . $role . ') : converter ' . $class . ' stores its data into field ' . $field . ':');
|
||||||
|
|
||||||
|
/** @var ConverterInterface $converter */
|
||||||
|
$converter = app('FireflyIII\Helpers\Csv\Converter\\' . $class);
|
||||||
|
$converter->setData($data); // the complete array so far.
|
||||||
|
$converter->setField($field);
|
||||||
|
$converter->setIndex($index);
|
||||||
|
$converter->setMapped($this->mapped);
|
||||||
|
$converter->setValue($value);
|
||||||
|
$converter->setRole($role);
|
||||||
|
$data[$field] = $converter->convert();
|
||||||
|
}
|
||||||
|
// move to class vars.
|
||||||
|
$this->importData = $data;
|
||||||
|
$this->importRow = $row;
|
||||||
|
unset($data, $row);
|
||||||
|
// post processing and validating.
|
||||||
|
$this->postProcess();
|
||||||
|
$result = $this->validateData();
|
||||||
|
|
||||||
|
if (!($result === true)) {
|
||||||
|
return $result; // return error.
|
||||||
|
}
|
||||||
|
$journal = $this->createTransactionJournal();
|
||||||
|
|
||||||
|
return $journal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $index
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function parseRow($index)
|
||||||
|
{
|
||||||
|
return (($this->data->hasHeaders() && $index >= 1) || !$this->data->hasHeaders());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Row denotes the original data.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function postProcess()
|
||||||
|
{
|
||||||
|
// do bank specific fixes (must be enabled but now all of them.
|
||||||
|
|
||||||
|
foreach ($this->getSpecifix() as $className) {
|
||||||
|
/** @var SpecifixInterface $specifix */
|
||||||
|
$specifix = app('FireflyIII\Helpers\Csv\Specifix\\' . $className);
|
||||||
|
$specifix->setData($this->importData);
|
||||||
|
$specifix->setRow($this->importRow);
|
||||||
|
Log::debug('Now post-process specifix named ' . $className . ':');
|
||||||
|
$this->importData = $specifix->fix();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$set = Config::get('csv.post_processors');
|
||||||
|
foreach ($set as $className) {
|
||||||
|
/** @var PostProcessorInterface $postProcessor */
|
||||||
|
$postProcessor = app('FireflyIII\Helpers\Csv\PostProcessing\\' . $className);
|
||||||
|
$postProcessor->setData($this->importData);
|
||||||
|
Log::debug('Now post-process processor named ' . $className . ':');
|
||||||
|
$this->importData = $postProcessor->process();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param TransactionJournal $journal
|
* @param TransactionJournal $journal
|
||||||
*/
|
*/
|
||||||
@@ -361,11 +347,23 @@ class Importer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Data $data
|
*
|
||||||
|
* @return bool|string
|
||||||
*/
|
*/
|
||||||
public function setData($data)
|
protected function validateData()
|
||||||
{
|
{
|
||||||
$this->data = $data;
|
if (is_null($this->importData['date']) && is_null($this->importData['date-rent'])) {
|
||||||
|
return 'No date value for this row.';
|
||||||
|
}
|
||||||
|
if (is_null($this->importData['opposing-account-object'])) {
|
||||||
|
return 'Opposing account is null';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!($this->importData['asset-account-object'] instanceof Account)) {
|
||||||
|
return 'No asset account to import into.';
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -54,8 +54,50 @@ class AbnAmroDescription
|
|||||||
$this->row = $row;
|
$this->row = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the current description with costs from ABN AMRO itself
|
||||||
|
*
|
||||||
|
* @return boolean true if the description is GEA/BEA-format, false otherwise
|
||||||
|
*/
|
||||||
|
protected function parseABNAMRODescription()
|
||||||
|
{
|
||||||
|
// See if the current description is formatted in ABN AMRO format
|
||||||
|
if (preg_match('/ABN AMRO.{24} (.*)/', $this->data['description'], $matches)) {
|
||||||
|
Log::debug('AbnAmroSpecifix: Description is structured as costs from ABN AMRO itself.');
|
||||||
|
|
||||||
|
$this->data['opposing-account-name'] = "ABN AMRO";
|
||||||
|
$this->data['description'] = $matches[1];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the current description in GEA/BEA format
|
||||||
|
*
|
||||||
|
* @return boolean true if the description is GEA/BEAformat, false otherwise
|
||||||
|
*/
|
||||||
|
protected function parseGEABEADescription()
|
||||||
|
{
|
||||||
|
// See if the current description is formatted in GEA/BEA format
|
||||||
|
if (preg_match('/([BG]EA) +(NR:[a-zA-Z:0-9]+) +([0-9.\/]+) +([^,]*)/', $this->data['description'], $matches)) {
|
||||||
|
Log::debug('AbnAmroSpecifix: Description is structured as GEA or BEA format.');
|
||||||
|
|
||||||
|
// description and opposing account will be the same.
|
||||||
|
$this->data['opposing-account-name'] = $matches[4];
|
||||||
|
$this->data['description'] = $matches[4];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the current description in SEPA format
|
* Parses the current description in SEPA format
|
||||||
|
*
|
||||||
* @return boolean true if the description is SEPA format, false otherwise
|
* @return boolean true if the description is SEPA format, false otherwise
|
||||||
*/
|
*/
|
||||||
protected function parseSepaDescription()
|
protected function parseSepaDescription()
|
||||||
@@ -94,6 +136,7 @@ class AbnAmroDescription
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the current description in TRTP format
|
* Parses the current description in TRTP format
|
||||||
|
*
|
||||||
* @return boolean true if the description is TRTP format, false otherwise
|
* @return boolean true if the description is TRTP format, false otherwise
|
||||||
*/
|
*/
|
||||||
protected function parseTRTPDescription()
|
protected function parseTRTPDescription()
|
||||||
@@ -108,9 +151,9 @@ class AbnAmroDescription
|
|||||||
|
|
||||||
switch (strtoupper($key)) {
|
switch (strtoupper($key)) {
|
||||||
// is not being used.
|
// is not being used.
|
||||||
// case 'TRTP':
|
// case 'TRTP':
|
||||||
// $type = $value;
|
// $type = $value;
|
||||||
// break;
|
// break;
|
||||||
case 'NAME':
|
case 'NAME':
|
||||||
$this->data['opposing-account-name'] = $value;
|
$this->data['opposing-account-name'] = $value;
|
||||||
break;
|
break;
|
||||||
@@ -131,43 +174,4 @@ class AbnAmroDescription
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the current description in GEA/BEA format
|
|
||||||
* @return boolean true if the description is GEA/BEAformat, false otherwise
|
|
||||||
*/
|
|
||||||
protected function parseGEABEADescription()
|
|
||||||
{
|
|
||||||
// See if the current description is formatted in GEA/BEA format
|
|
||||||
if (preg_match('/([BG]EA) +(NR:[a-zA-Z:0-9]+) +([0-9.\/]+) +([^,]*)/', $this->data['description'], $matches)) {
|
|
||||||
Log::debug('AbnAmroSpecifix: Description is structured as GEA or BEA format.');
|
|
||||||
|
|
||||||
// description and opposing account will be the same.
|
|
||||||
$this->data['opposing-account-name'] = $matches[4];
|
|
||||||
$this->data['description'] = $matches[4];
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the current description with costs from ABN AMRO itself
|
|
||||||
* @return boolean true if the description is GEA/BEA-format, false otherwise
|
|
||||||
*/
|
|
||||||
protected function parseABNAMRODescription()
|
|
||||||
{
|
|
||||||
// See if the current description is formatted in ABN AMRO format
|
|
||||||
if (preg_match('/ABN AMRO.{24} (.*)/', $this->data['description'], $matches)) {
|
|
||||||
Log::debug('AbnAmroSpecifix: Description is structured as costs from ABN AMRO itself.');
|
|
||||||
|
|
||||||
$this->data['opposing-account-name'] = "ABN AMRO";
|
|
||||||
$this->data['description'] = $matches[1];
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -168,17 +168,6 @@ class Wizard implements WizardInterface
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param bool $hasHeaders
|
|
||||||
* @param int $index
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
protected function useRow($hasHeaders, $index)
|
|
||||||
{
|
|
||||||
return ($hasHeaders && $index > 1) || !$hasHeaders;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $array
|
* @param array $array
|
||||||
*
|
*
|
||||||
@@ -192,4 +181,15 @@ class Wizard implements WizardInterface
|
|||||||
|
|
||||||
return $array;
|
return $array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $hasHeaders
|
||||||
|
* @param int $index
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function useRow($hasHeaders, $index)
|
||||||
|
{
|
||||||
|
return ($hasHeaders && $index > 1) || !$hasHeaders;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -35,12 +35,10 @@ use Illuminate\Support\Collection;
|
|||||||
class ReportHelper implements ReportHelperInterface
|
class ReportHelper implements ReportHelperInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
/** @var ReportQueryInterface */
|
|
||||||
protected $query;
|
|
||||||
|
|
||||||
/** @var BudgetRepositoryInterface */
|
/** @var BudgetRepositoryInterface */
|
||||||
protected $budgetRepository;
|
protected $budgetRepository;
|
||||||
|
/** @var ReportQueryInterface */
|
||||||
|
protected $query;
|
||||||
/** @var TagRepositoryInterface */
|
/** @var TagRepositoryInterface */
|
||||||
protected $tagRepository;
|
protected $tagRepository;
|
||||||
|
|
||||||
@@ -60,68 +58,6 @@ class ReportHelper implements ReportHelperInterface
|
|||||||
$this->tagRepository = $tagRepository;
|
$this->tagRepository = $tagRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Carbon $start
|
|
||||||
* @param Carbon $end
|
|
||||||
* @param Collection $accounts
|
|
||||||
*
|
|
||||||
* @return CategoryCollection
|
|
||||||
*/
|
|
||||||
public function getCategoryReport(Carbon $start, Carbon $end, Collection $accounts)
|
|
||||||
{
|
|
||||||
$object = new CategoryCollection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GET CATEGORIES:
|
|
||||||
*/
|
|
||||||
/** @var \FireflyIII\Repositories\Category\CategoryRepositoryInterface $repository */
|
|
||||||
$repository = app('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
|
|
||||||
|
|
||||||
$set = $repository->spentForAccountsPerMonth($accounts, $start, $end);
|
|
||||||
foreach ($set as $category) {
|
|
||||||
$object->addCategory($category);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $object;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Carbon $date
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function listOfMonths(Carbon $date)
|
|
||||||
{
|
|
||||||
|
|
||||||
$start = clone $date;
|
|
||||||
$end = Carbon::now();
|
|
||||||
$months = [];
|
|
||||||
while ($start <= $end) {
|
|
||||||
$year = $start->year;
|
|
||||||
|
|
||||||
if (!isset($months[$year])) {
|
|
||||||
$months[$year] = [
|
|
||||||
'start' => Carbon::createFromDate($year, 1, 1)->format('Y-m-d'),
|
|
||||||
'end' => Carbon::createFromDate($year, 12, 31)->format('Y-m-d'),
|
|
||||||
'months' => [],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$currentEnd = clone $start;
|
|
||||||
$currentEnd->endOfMonth();
|
|
||||||
$months[$year]['months'][] = [
|
|
||||||
'formatted' => $start->formatLocalized('%B %Y'),
|
|
||||||
'start' => $start->format('Y-m-d'),
|
|
||||||
'end' => $currentEnd->format('Y-m-d'),
|
|
||||||
'month' => $start->month,
|
|
||||||
'year' => $year,
|
|
||||||
];
|
|
||||||
$start->addMonth();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $months;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method generates a full report for the given period on all
|
* This method generates a full report for the given period on all
|
||||||
* given accounts
|
* given accounts
|
||||||
@@ -211,47 +147,86 @@ class ReportHelper implements ReportHelperInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a full report on the users incomes during the period for the given accounts.
|
|
||||||
*
|
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
*
|
*
|
||||||
* @return Income
|
* @return Balance
|
||||||
*/
|
*/
|
||||||
public function getIncomeReport($start, $end, Collection $accounts)
|
public function getBalanceReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||||
{
|
{
|
||||||
$object = new Income;
|
$balance = new Balance;
|
||||||
$set = $this->query->income($accounts, $start, $end);
|
|
||||||
|
|
||||||
foreach ($set as $entry) {
|
// build a balance header:
|
||||||
$object->addToTotal($entry->journalAmount);
|
$header = new BalanceHeader;
|
||||||
$object->addOrCreateIncome($entry);
|
$budgets = $this->budgetRepository->getBudgetsAndLimitsInRange($start, $end);
|
||||||
|
$spentData = $this->budgetRepository->spentPerBudgetPerAccount($budgets, $accounts, $start, $end);
|
||||||
|
foreach ($accounts as $account) {
|
||||||
|
$header->addAccount($account);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $object;
|
/** @var BudgetModel $budget */
|
||||||
|
foreach ($budgets as $budget) {
|
||||||
|
$balance->addBalanceLine($this->createBalanceLine($budget, $accounts, $spentData));
|
||||||
|
}
|
||||||
|
|
||||||
|
$balance->addBalanceLine($this->createEmptyBalanceLine($accounts, $spentData));
|
||||||
|
$balance->addBalanceLine($this->createTagsBalanceLine($accounts, $start, $end));
|
||||||
|
$balance->addBalanceLine($this->createDifferenceBalanceLine($accounts, $spentData, $start, $end));
|
||||||
|
|
||||||
|
$balance->setBalanceHeader($header);
|
||||||
|
|
||||||
|
return $balance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a full report on the users expenses during the period for a list of accounts.
|
* This method generates a full report for the given period on all
|
||||||
|
* the users bills and their payments.
|
||||||
|
*
|
||||||
|
* Excludes bills which have not had a payment on the mentioned accounts.
|
||||||
*
|
*
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
*
|
*
|
||||||
* @return Expense
|
* @return BillCollection
|
||||||
*/
|
*/
|
||||||
public function getExpenseReport($start, $end, Collection $accounts)
|
public function getBillReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||||
{
|
{
|
||||||
$object = new Expense;
|
/** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */
|
||||||
$set = $this->query->expense($accounts, $start, $end);
|
$repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface');
|
||||||
|
$bills = $repository->getBillsForAccounts($accounts);
|
||||||
|
$journals = $repository->getAllJournalsInRange($bills, $start, $end);
|
||||||
|
$collection = new BillCollection;
|
||||||
|
|
||||||
|
/** @var Bill $bill */
|
||||||
|
foreach ($bills as $bill) {
|
||||||
|
$billLine = new BillLine;
|
||||||
|
$billLine->setBill($bill);
|
||||||
|
$billLine->setActive(intval($bill->active) == 1);
|
||||||
|
$billLine->setMin($bill->amount_min);
|
||||||
|
$billLine->setMax($bill->amount_max);
|
||||||
|
|
||||||
|
// is hit in period?
|
||||||
|
bcscale(2);
|
||||||
|
|
||||||
|
$entry = $journals->filter(
|
||||||
|
function (TransactionJournal $journal) use ($bill) {
|
||||||
|
return $journal->bill_id == $bill->id;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (!is_null($entry->first())) {
|
||||||
|
$billLine->setAmount($entry->first()->journalAmount);
|
||||||
|
$billLine->setHit(true);
|
||||||
|
} else {
|
||||||
|
$billLine->setHit(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$collection->addBill($billLine);
|
||||||
|
|
||||||
foreach ($set as $entry) {
|
|
||||||
$object->addToTotal($entry->journalAmount); // can be positive, if it's a transfer
|
|
||||||
$object->addOrCreateExpense($entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $object;
|
return $collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -338,82 +313,105 @@ class ReportHelper implements ReportHelperInterface
|
|||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
*
|
*
|
||||||
* @return Balance
|
* @return CategoryCollection
|
||||||
*/
|
*/
|
||||||
public function getBalanceReport(Carbon $start, Carbon $end, Collection $accounts)
|
public function getCategoryReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||||
{
|
{
|
||||||
$balance = new Balance;
|
$object = new CategoryCollection;
|
||||||
|
|
||||||
// build a balance header:
|
/**
|
||||||
$header = new BalanceHeader;
|
* GET CATEGORIES:
|
||||||
$budgets = $this->budgetRepository->getBudgetsAndLimitsInRange($start, $end);
|
*/
|
||||||
$spentData = $this->budgetRepository->spentPerBudgetPerAccount($budgets, $accounts, $start, $end);
|
/** @var \FireflyIII\Repositories\Category\CategoryRepositoryInterface $repository */
|
||||||
foreach ($accounts as $account) {
|
$repository = app('FireflyIII\Repositories\Category\CategoryRepositoryInterface');
|
||||||
$header->addAccount($account);
|
|
||||||
|
$set = $repository->spentForAccountsPerMonth($accounts, $start, $end);
|
||||||
|
foreach ($set as $category) {
|
||||||
|
$object->addCategory($category);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var BudgetModel $budget */
|
return $object;
|
||||||
foreach ($budgets as $budget) {
|
|
||||||
$balance->addBalanceLine($this->createBalanceLine($budget, $accounts, $spentData));
|
|
||||||
}
|
|
||||||
|
|
||||||
$balance->addBalanceLine($this->createEmptyBalanceLine($accounts, $spentData));
|
|
||||||
$balance->addBalanceLine($this->createTagsBalanceLine($accounts, $start, $end));
|
|
||||||
$balance->addBalanceLine($this->createDifferenceBalanceLine($accounts, $spentData, $start, $end));
|
|
||||||
|
|
||||||
$balance->setBalanceHeader($header);
|
|
||||||
|
|
||||||
return $balance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method generates a full report for the given period on all
|
* Get a full report on the users expenses during the period for a list of accounts.
|
||||||
* the users bills and their payments.
|
|
||||||
*
|
|
||||||
* Excludes bills which have not had a payment on the mentioned accounts.
|
|
||||||
*
|
*
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
*
|
*
|
||||||
* @return BillCollection
|
* @return Expense
|
||||||
*/
|
*/
|
||||||
public function getBillReport(Carbon $start, Carbon $end, Collection $accounts)
|
public function getExpenseReport($start, $end, Collection $accounts)
|
||||||
{
|
{
|
||||||
/** @var \FireflyIII\Repositories\Bill\BillRepositoryInterface $repository */
|
$object = new Expense;
|
||||||
$repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface');
|
$set = $this->query->expense($accounts, $start, $end);
|
||||||
$bills = $repository->getBillsForAccounts($accounts);
|
|
||||||
$journals = $repository->getAllJournalsInRange($bills, $start, $end);
|
|
||||||
$collection = new BillCollection;
|
|
||||||
|
|
||||||
/** @var Bill $bill */
|
|
||||||
foreach ($bills as $bill) {
|
|
||||||
$billLine = new BillLine;
|
|
||||||
$billLine->setBill($bill);
|
|
||||||
$billLine->setActive(intval($bill->active) == 1);
|
|
||||||
$billLine->setMin($bill->amount_min);
|
|
||||||
$billLine->setMax($bill->amount_max);
|
|
||||||
|
|
||||||
// is hit in period?
|
|
||||||
bcscale(2);
|
|
||||||
|
|
||||||
$entry = $journals->filter(
|
|
||||||
function (TransactionJournal $journal) use ($bill) {
|
|
||||||
return $journal->bill_id == $bill->id;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (!is_null($entry->first())) {
|
|
||||||
$billLine->setAmount($entry->first()->journalAmount);
|
|
||||||
$billLine->setHit(true);
|
|
||||||
} else {
|
|
||||||
$billLine->setHit(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
$collection->addBill($billLine);
|
|
||||||
|
|
||||||
|
foreach ($set as $entry) {
|
||||||
|
$object->addToTotal($entry->journalAmount); // can be positive, if it's a transfer
|
||||||
|
$object->addOrCreateExpense($entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $collection;
|
return $object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a full report on the users incomes during the period for the given accounts.
|
||||||
|
*
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
* @param Collection $accounts
|
||||||
|
*
|
||||||
|
* @return Income
|
||||||
|
*/
|
||||||
|
public function getIncomeReport($start, $end, Collection $accounts)
|
||||||
|
{
|
||||||
|
$object = new Income;
|
||||||
|
$set = $this->query->income($accounts, $start, $end);
|
||||||
|
|
||||||
|
foreach ($set as $entry) {
|
||||||
|
$object->addToTotal($entry->journalAmount);
|
||||||
|
$object->addOrCreateIncome($entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Carbon $date
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function listOfMonths(Carbon $date)
|
||||||
|
{
|
||||||
|
|
||||||
|
$start = clone $date;
|
||||||
|
$end = Carbon::now();
|
||||||
|
$months = [];
|
||||||
|
while ($start <= $end) {
|
||||||
|
$year = $start->year;
|
||||||
|
|
||||||
|
if (!isset($months[$year])) {
|
||||||
|
$months[$year] = [
|
||||||
|
'start' => Carbon::createFromDate($year, 1, 1)->format('Y-m-d'),
|
||||||
|
'end' => Carbon::createFromDate($year, 12, 31)->format('Y-m-d'),
|
||||||
|
'months' => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentEnd = clone $start;
|
||||||
|
$currentEnd->endOfMonth();
|
||||||
|
$months[$year]['months'][] = [
|
||||||
|
'formatted' => $start->formatLocalized('%B %Y'),
|
||||||
|
'start' => $start->format('Y-m-d'),
|
||||||
|
'end' => $currentEnd->format('Y-m-d'),
|
||||||
|
'month' => $start->month,
|
||||||
|
'year' => $year,
|
||||||
|
];
|
||||||
|
$start->addMonth();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $months;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -478,6 +476,56 @@ class ReportHelper implements ReportHelperInterface
|
|||||||
return $line;
|
return $line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Collection $accounts
|
||||||
|
* @param Collection $spentData
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
||||||
|
*
|
||||||
|
* @return BalanceLine
|
||||||
|
*/
|
||||||
|
private function createDifferenceBalanceLine(Collection $accounts, Collection $spentData, Carbon $start, Carbon $end)
|
||||||
|
{
|
||||||
|
$diff = new BalanceLine;
|
||||||
|
$tagsLeft = $this->tagRepository->allCoveredByBalancingActs($accounts, $start, $end);
|
||||||
|
|
||||||
|
$diff->setRole(BalanceLine::ROLE_DIFFROLE);
|
||||||
|
|
||||||
|
foreach ($accounts as $account) {
|
||||||
|
$entry = $spentData->filter(
|
||||||
|
function (TransactionJournal $model) use ($account) {
|
||||||
|
return $model->account_id == $account->id && is_null($model->budget_id);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
$spent = 0;
|
||||||
|
if (!is_null($entry->first())) {
|
||||||
|
$spent = $entry->first()->spent;
|
||||||
|
}
|
||||||
|
$leftEntry = $tagsLeft->filter(
|
||||||
|
function (Tag $tag) use ($account) {
|
||||||
|
return $tag->account_id == $account->id;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
$left = 0;
|
||||||
|
if (!is_null($leftEntry->first())) {
|
||||||
|
$left = $leftEntry->first()->sum;
|
||||||
|
}
|
||||||
|
bcscale(2);
|
||||||
|
$diffValue = bcadd($spent, $left);
|
||||||
|
|
||||||
|
// difference:
|
||||||
|
$diffEntry = new BalanceEntry;
|
||||||
|
$diffEntry->setAccount($account);
|
||||||
|
$diffEntry->setSpent($diffValue);
|
||||||
|
$diff->addBalanceEntry($diffEntry);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $diff;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
* @param Collection $spentData
|
* @param Collection $spentData
|
||||||
@@ -546,54 +594,4 @@ class ReportHelper implements ReportHelperInterface
|
|||||||
|
|
||||||
return $tags;
|
return $tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Collection $accounts
|
|
||||||
* @param Collection $spentData
|
|
||||||
* @param Carbon $start
|
|
||||||
* @param Carbon $end
|
|
||||||
*
|
|
||||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
|
|
||||||
*
|
|
||||||
* @return BalanceLine
|
|
||||||
*/
|
|
||||||
private function createDifferenceBalanceLine(Collection $accounts, Collection $spentData, Carbon $start, Carbon $end)
|
|
||||||
{
|
|
||||||
$diff = new BalanceLine;
|
|
||||||
$tagsLeft = $this->tagRepository->allCoveredByBalancingActs($accounts, $start, $end);
|
|
||||||
|
|
||||||
$diff->setRole(BalanceLine::ROLE_DIFFROLE);
|
|
||||||
|
|
||||||
foreach ($accounts as $account) {
|
|
||||||
$entry = $spentData->filter(
|
|
||||||
function (TransactionJournal $model) use ($account) {
|
|
||||||
return $model->account_id == $account->id && is_null($model->budget_id);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
$spent = 0;
|
|
||||||
if (!is_null($entry->first())) {
|
|
||||||
$spent = $entry->first()->spent;
|
|
||||||
}
|
|
||||||
$leftEntry = $tagsLeft->filter(
|
|
||||||
function (Tag $tag) use ($account) {
|
|
||||||
return $tag->account_id == $account->id;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
$left = 0;
|
|
||||||
if (!is_null($leftEntry->first())) {
|
|
||||||
$left = $leftEntry->first()->sum;
|
|
||||||
}
|
|
||||||
bcscale(2);
|
|
||||||
$diffValue = bcadd($spent, $left);
|
|
||||||
|
|
||||||
// difference:
|
|
||||||
$diffEntry = new BalanceEntry;
|
|
||||||
$diffEntry->setAccount($account);
|
|
||||||
$diffEntry->setSpent($diffValue);
|
|
||||||
$diff->addBalanceEntry($diffEntry);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return $diff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,15 @@ interface ReportHelperInterface
|
|||||||
*/
|
*/
|
||||||
public function getAccountReport(Carbon $start, Carbon $end, Collection $accounts);
|
public function getAccountReport(Carbon $start, Carbon $end, Collection $accounts);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
* @param Collection $accounts
|
||||||
|
*
|
||||||
|
* @return Balance
|
||||||
|
*/
|
||||||
|
public function getBalanceReport(Carbon $start, Carbon $end, Collection $accounts);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method generates a full report for the given period on all
|
* This method generates a full report for the given period on all
|
||||||
* the users bills and their payments.
|
* the users bills and their payments.
|
||||||
@@ -46,15 +55,6 @@ interface ReportHelperInterface
|
|||||||
*/
|
*/
|
||||||
public function getBillReport(Carbon $start, Carbon $end, Collection $accounts);
|
public function getBillReport(Carbon $start, Carbon $end, Collection $accounts);
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Carbon $start
|
|
||||||
* @param Carbon $end
|
|
||||||
* @param Collection $accounts
|
|
||||||
*
|
|
||||||
* @return Balance
|
|
||||||
*/
|
|
||||||
public function getBalanceReport(Carbon $start, Carbon $end, Collection $accounts);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
|
@@ -17,51 +17,6 @@ use Illuminate\Support\Collection;
|
|||||||
class ReportQuery implements ReportQueryInterface
|
class ReportQuery implements ReportQueryInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
|
|
||||||
* grouped by month like so: "2015-01" => '123.45'
|
|
||||||
*
|
|
||||||
* @param Collection $accounts
|
|
||||||
* @param Carbon $start
|
|
||||||
* @param Carbon $end
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function spentPerMonth(Collection $accounts, Carbon $start, Carbon $end)
|
|
||||||
{
|
|
||||||
$ids = $accounts->pluck('id')->toArray();
|
|
||||||
$query = Auth::user()->transactionjournals()
|
|
||||||
->leftJoin(
|
|
||||||
'transactions AS t_from', function (JoinClause $join) {
|
|
||||||
$join->on('transaction_journals.id', '=', 't_from.transaction_journal_id')->where('t_from.amount', '<', 0);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
->leftJoin(
|
|
||||||
'transactions AS t_to', function (JoinClause $join) {
|
|
||||||
$join->on('transaction_journals.id', '=', 't_to.transaction_journal_id')->where('t_to.amount', '>', 0);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
->whereIn('t_from.account_id', $ids)
|
|
||||||
->whereNotIn('t_to.account_id', $ids)
|
|
||||||
->after($start)
|
|
||||||
->before($end)
|
|
||||||
->transactionTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
|
|
||||||
->groupBy('dateFormatted')
|
|
||||||
->get(
|
|
||||||
[
|
|
||||||
DB::Raw('DATE_FORMAT(`transaction_journals`.`date`,"%Y-%m") AS `dateFormatted`'),
|
|
||||||
DB::Raw('SUM(`t_from`.`amount`) AS `sum`'),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
$array = [];
|
|
||||||
foreach ($query as $result) {
|
|
||||||
$array[$result->dateFormatted] = $result->sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $array;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
|
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
|
||||||
* grouped by month like so: "2015-01" => '123.45'
|
* grouped by month like so: "2015-01" => '123.45'
|
||||||
@@ -106,6 +61,41 @@ class ReportQuery implements ReportQueryInterface
|
|||||||
return $array;
|
return $array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns all the "out" transaction journals for the given account and given period. The amount
|
||||||
|
* is stored in "journalAmount".
|
||||||
|
*
|
||||||
|
* @param Collection $accounts
|
||||||
|
* @param Carbon $start
|
||||||
|
* @param Carbon $end
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function expense(Collection $accounts, Carbon $start, Carbon $end)
|
||||||
|
{
|
||||||
|
$ids = $accounts->pluck('id')->toArray();
|
||||||
|
$set = Auth::user()->transactionjournals()
|
||||||
|
->leftJoin(
|
||||||
|
'transactions as t_from', function (JoinClause $join) {
|
||||||
|
$join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
->leftJoin(
|
||||||
|
'transactions as t_to', function (JoinClause $join) {
|
||||||
|
$join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
->leftJoin('accounts', 't_to.account_id', '=', 'accounts.id')
|
||||||
|
->transactionTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
|
||||||
|
->before($end)
|
||||||
|
->after($start)
|
||||||
|
->whereIn('t_from.account_id', $ids)
|
||||||
|
->whereNotIn('t_to.account_id', $ids)
|
||||||
|
->get(['transaction_journals.*', 't_from.amount as journalAmount', 'accounts.id as account_id', 'accounts.name as account_name']);
|
||||||
|
|
||||||
|
return $set;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns all the "in" transaction journals for the given account and given period. The amount
|
* This method returns all the "in" transaction journals for the given account and given period. The amount
|
||||||
* is stored in "journalAmount".
|
* is stored in "journalAmount".
|
||||||
@@ -142,37 +132,47 @@ class ReportQuery implements ReportQueryInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns all the "out" transaction journals for the given account and given period. The amount
|
* Returns an array of the amount of money spent in the given accounts (on withdrawals, opening balances and transfers)
|
||||||
* is stored in "journalAmount".
|
* grouped by month like so: "2015-01" => '123.45'
|
||||||
*
|
*
|
||||||
* @param Collection $accounts
|
* @param Collection $accounts
|
||||||
* @param Carbon $start
|
* @param Carbon $start
|
||||||
* @param Carbon $end
|
* @param Carbon $end
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function expense(Collection $accounts, Carbon $start, Carbon $end)
|
public function spentPerMonth(Collection $accounts, Carbon $start, Carbon $end)
|
||||||
{
|
{
|
||||||
$ids = $accounts->pluck('id')->toArray();
|
$ids = $accounts->pluck('id')->toArray();
|
||||||
$set = Auth::user()->transactionjournals()
|
$query = Auth::user()->transactionjournals()
|
||||||
->leftJoin(
|
->leftJoin(
|
||||||
'transactions as t_from', function (JoinClause $join) {
|
'transactions AS t_from', function (JoinClause $join) {
|
||||||
$join->on('t_from.transaction_journal_id', '=', 'transaction_journals.id')->where('t_from.amount', '<', 0);
|
$join->on('transaction_journals.id', '=', 't_from.transaction_journal_id')->where('t_from.amount', '<', 0);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
->leftJoin(
|
->leftJoin(
|
||||||
'transactions as t_to', function (JoinClause $join) {
|
'transactions AS t_to', function (JoinClause $join) {
|
||||||
$join->on('t_to.transaction_journal_id', '=', 'transaction_journals.id')->where('t_to.amount', '>', 0);
|
$join->on('transaction_journals.id', '=', 't_to.transaction_journal_id')->where('t_to.amount', '>', 0);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
->leftJoin('accounts', 't_to.account_id', '=', 'accounts.id')
|
->whereIn('t_from.account_id', $ids)
|
||||||
->transactionTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
|
->whereNotIn('t_to.account_id', $ids)
|
||||||
->before($end)
|
->after($start)
|
||||||
->after($start)
|
->before($end)
|
||||||
->whereIn('t_from.account_id', $ids)
|
->transactionTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE])
|
||||||
->whereNotIn('t_to.account_id', $ids)
|
->groupBy('dateFormatted')
|
||||||
->get(['transaction_journals.*', 't_from.amount as journalAmount', 'accounts.id as account_id', 'accounts.name as account_name']);
|
->get(
|
||||||
|
[
|
||||||
|
DB::Raw('DATE_FORMAT(`transaction_journals`.`date`,"%Y-%m") AS `dateFormatted`'),
|
||||||
|
DB::Raw('SUM(`t_from`.`amount`) AS `sum`'),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$array = [];
|
||||||
|
foreach ($query as $result) {
|
||||||
|
$array[$result->dateFormatted] = $result->sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $array;
|
||||||
|
|
||||||
return $set;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -61,6 +61,18 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*
|
||||||
|
* @param $accountId
|
||||||
|
*
|
||||||
|
* @return Account
|
||||||
|
*/
|
||||||
|
public function find($accountId)
|
||||||
|
{
|
||||||
|
return Auth::user()->accounts()->findOrNew($accountId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $types
|
* @param array $types
|
||||||
*
|
*
|
||||||
@@ -84,7 +96,6 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the users credit cards, along with some basic information about the
|
* This method returns the users credit cards, along with some basic information about the
|
||||||
* balance they have on their CC. To be used in the JSON boxes on the front page that say
|
* balance they have on their CC. To be used in the JSON boxes on the front page that say
|
||||||
@@ -465,29 +476,6 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
return $newAccount;
|
return $newAccount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Account $account
|
|
||||||
* @param array $data
|
|
||||||
*/
|
|
||||||
protected function storeMetadata(Account $account, array $data)
|
|
||||||
{
|
|
||||||
$validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType'];
|
|
||||||
foreach ($validFields as $field) {
|
|
||||||
if (isset($data[$field])) {
|
|
||||||
$metaData = new AccountMeta(
|
|
||||||
[
|
|
||||||
'account_id' => $account->id,
|
|
||||||
'name' => $field,
|
|
||||||
'data' => $data[$field],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
$metaData->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Account $account
|
* @param Account $account
|
||||||
* @param Account $opposing
|
* @param Account $opposing
|
||||||
@@ -536,33 +524,24 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
/**
|
/**
|
||||||
* @param Account $account
|
* @param Account $account
|
||||||
* @param array $data
|
* @param array $data
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
protected function updateMetadata(Account $account, array $data)
|
protected function storeMetadata(Account $account, array $data)
|
||||||
{
|
{
|
||||||
$validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType'];
|
$validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType'];
|
||||||
|
|
||||||
foreach ($validFields as $field) {
|
foreach ($validFields as $field) {
|
||||||
$entry = $account->accountMeta()->where('name', $field)->first();
|
|
||||||
|
|
||||||
if (isset($data[$field])) {
|
if (isset($data[$field])) {
|
||||||
// update if new data is present:
|
$metaData = new AccountMeta(
|
||||||
if (!is_null($entry)) {
|
[
|
||||||
$entry->data = $data[$field];
|
'account_id' => $account->id,
|
||||||
$entry->save();
|
'name' => $field,
|
||||||
} else {
|
'data' => $data[$field],
|
||||||
$metaData = new AccountMeta(
|
]
|
||||||
[
|
);
|
||||||
'account_id' => $account->id,
|
$metaData->save();
|
||||||
'name' => $field,
|
|
||||||
'data' => $data[$field],
|
|
||||||
]
|
|
||||||
);
|
|
||||||
$metaData->save();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -592,14 +571,34 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @param Account $account
|
||||||
|
* @param array $data
|
||||||
*
|
*
|
||||||
* @param $accountId
|
|
||||||
*
|
|
||||||
* @return Account
|
|
||||||
*/
|
*/
|
||||||
public function find($accountId)
|
protected function updateMetadata(Account $account, array $data)
|
||||||
{
|
{
|
||||||
return Auth::user()->accounts()->findOrNew($accountId);
|
$validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType'];
|
||||||
|
|
||||||
|
foreach ($validFields as $field) {
|
||||||
|
$entry = $account->accountMeta()->where('name', $field)->first();
|
||||||
|
|
||||||
|
if (isset($data[$field])) {
|
||||||
|
// update if new data is present:
|
||||||
|
if (!is_null($entry)) {
|
||||||
|
$entry->data = $data[$field];
|
||||||
|
$entry->save();
|
||||||
|
} else {
|
||||||
|
$metaData = new AccountMeta(
|
||||||
|
[
|
||||||
|
'account_id' => $account->id,
|
||||||
|
'name' => $field,
|
||||||
|
'data' => $data[$field],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$metaData->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,14 @@ interface AccountRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function countAccounts(array $types);
|
public function countAccounts(array $types);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Account $account
|
||||||
|
* @param Account $moveTo
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function destroy(Account $account, Account $moveTo = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $accountId
|
* @param $accountId
|
||||||
*
|
*
|
||||||
@@ -33,14 +41,6 @@ interface AccountRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function find($accountId);
|
public function find($accountId);
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Account $account
|
|
||||||
* @param Account $moveTo
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function destroy(Account $account, Account $moveTo = null);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $types
|
* @param array $types
|
||||||
*
|
*
|
||||||
@@ -48,14 +48,6 @@ interface AccountRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function getAccounts(array $types);
|
public function getAccounts(array $types);
|
||||||
|
|
||||||
/**
|
|
||||||
* @param TransactionJournal $journal
|
|
||||||
* @param Account $account
|
|
||||||
*
|
|
||||||
* @return Transaction
|
|
||||||
*/
|
|
||||||
public function getFirstTransaction(TransactionJournal $journal, Account $account);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the users credit cards, along with some basic information about the
|
* This method returns the users credit cards, along with some basic information about the
|
||||||
* balance they have on their CC. To be used in the JSON boxes on the front page that say
|
* balance they have on their CC. To be used in the JSON boxes on the front page that say
|
||||||
@@ -70,11 +62,12 @@ interface AccountRepositoryInterface
|
|||||||
public function getCreditCards(Carbon $date);
|
public function getCreditCards(Carbon $date);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the accounts of a user that have piggy banks connected to them.
|
* @param TransactionJournal $journal
|
||||||
|
* @param Account $account
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return Transaction
|
||||||
*/
|
*/
|
||||||
public function getPiggyBankAccounts();
|
public function getFirstTransaction(TransactionJournal $journal, Account $account);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Preference $preference
|
* @param Preference $preference
|
||||||
@@ -101,9 +94,11 @@ interface AccountRepositoryInterface
|
|||||||
public function getJournals(Account $account, $page);
|
public function getJournals(Account $account, $page);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* Get the accounts of a user that have piggy banks connected to them.
|
||||||
|
*
|
||||||
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
public function sumOfEverything();
|
public function getPiggyBankAccounts();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get savings accounts and the balance difference in the period.
|
* Get savings accounts and the balance difference in the period.
|
||||||
@@ -134,6 +129,11 @@ interface AccountRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function store(array $data);
|
public function store(array $data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function sumOfEverything();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Account $account
|
* @param Account $account
|
||||||
* @param array $data
|
* @param array $data
|
||||||
|
@@ -46,6 +46,13 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function get()
|
||||||
|
{
|
||||||
|
return Auth::user()->ruleGroups()->orderBy('order', 'ASC')->get();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return int
|
||||||
@@ -57,36 +64,6 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
|
|||||||
return intval($entry);
|
return intval($entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Collection
|
|
||||||
*/
|
|
||||||
public function get()
|
|
||||||
{
|
|
||||||
return Auth::user()->ruleGroups()->orderBy('order', 'ASC')->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param RuleGroup $ruleGroup
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function moveUp(RuleGroup $ruleGroup)
|
|
||||||
{
|
|
||||||
$order = $ruleGroup->order;
|
|
||||||
|
|
||||||
// find the rule with order-1 and give it order+1
|
|
||||||
$other = Auth::user()->ruleGroups()->where('order', ($order - 1))->first();
|
|
||||||
if ($other) {
|
|
||||||
$other->order = ($other->order + 1);
|
|
||||||
$other->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
$ruleGroup->order = ($ruleGroup->order - 1);
|
|
||||||
$ruleGroup->save();
|
|
||||||
$this->resetRuleGroupOrder();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param RuleGroup $ruleGroup
|
* @param RuleGroup $ruleGroup
|
||||||
*
|
*
|
||||||
@@ -108,6 +85,26 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
|
|||||||
$this->resetRuleGroupOrder();
|
$this->resetRuleGroupOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param RuleGroup $ruleGroup
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function moveUp(RuleGroup $ruleGroup)
|
||||||
|
{
|
||||||
|
$order = $ruleGroup->order;
|
||||||
|
|
||||||
|
// find the rule with order-1 and give it order+1
|
||||||
|
$other = Auth::user()->ruleGroups()->where('order', ($order - 1))->first();
|
||||||
|
if ($other) {
|
||||||
|
$other->order = ($other->order + 1);
|
||||||
|
$other->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
$ruleGroup->order = ($ruleGroup->order - 1);
|
||||||
|
$ruleGroup->save();
|
||||||
|
$this->resetRuleGroupOrder();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
|
@@ -21,6 +21,10 @@ interface RuleGroupRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function destroy(RuleGroup $ruleGroup, RuleGroup $moveTo = null);
|
public function destroy(RuleGroup $ruleGroup, RuleGroup $moveTo = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection
|
||||||
|
*/
|
||||||
|
public function get();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return int
|
||||||
@@ -28,9 +32,11 @@ interface RuleGroupRepositoryInterface
|
|||||||
public function getHighestOrderRuleGroup();
|
public function getHighestOrderRuleGroup();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Collection
|
* @param RuleGroup $ruleGroup
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function get();
|
public function moveDown(RuleGroup $ruleGroup);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param RuleGroup $ruleGroup
|
* @param RuleGroup $ruleGroup
|
||||||
@@ -39,13 +45,6 @@ interface RuleGroupRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function moveUp(RuleGroup $ruleGroup);
|
public function moveUp(RuleGroup $ruleGroup);
|
||||||
|
|
||||||
/**
|
|
||||||
* @param RuleGroup $ruleGroup
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function moveDown(RuleGroup $ruleGroup);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user