mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-19 19:01:58 +00:00
Fixed most importers.
This commit is contained in:
40
app/Helpers/Csv/Converter/TagsComma.php
Normal file
40
app/Helpers/Csv/Converter/TagsComma.php
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Helpers\Csv\Converter;
|
||||||
|
|
||||||
|
use Auth;
|
||||||
|
use FireflyIII\Models\Bill;
|
||||||
|
use FireflyIII\Models\Tag;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class TagsComma
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Helpers\Csv\Converter
|
||||||
|
*/
|
||||||
|
class TagsComma extends BasicConverter implements ConverterInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Bill
|
||||||
|
*/
|
||||||
|
public function convert()
|
||||||
|
{
|
||||||
|
$tags = new Collection;
|
||||||
|
|
||||||
|
$strings = explode(',', $this->value);
|
||||||
|
foreach ($strings as $string) {
|
||||||
|
$tag = Tag::firstOrCreateEncrypted(
|
||||||
|
[
|
||||||
|
'tag' => $string,
|
||||||
|
'tagMode' => 'nothing',
|
||||||
|
'user_id' => Auth::user()->id,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$tags->push($tag);
|
||||||
|
}
|
||||||
|
$tags = $tags->merge($this->data['tags']);
|
||||||
|
|
||||||
|
return $tags;
|
||||||
|
}
|
||||||
|
}
|
40
app/Helpers/Csv/Converter/TagsSpace.php
Normal file
40
app/Helpers/Csv/Converter/TagsSpace.php
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Helpers\Csv\Converter;
|
||||||
|
|
||||||
|
use Auth;
|
||||||
|
use FireflyIII\Models\Bill;
|
||||||
|
use FireflyIII\Models\Tag;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class TagsSpace
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Helpers\Csv\Converter
|
||||||
|
*/
|
||||||
|
class TagsSpace extends BasicConverter implements ConverterInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Bill
|
||||||
|
*/
|
||||||
|
public function convert()
|
||||||
|
{
|
||||||
|
$tags = new Collection;
|
||||||
|
|
||||||
|
$strings = explode(' ', $this->value);
|
||||||
|
foreach ($strings as $string) {
|
||||||
|
$tag = Tag::firstOrCreateEncrypted(
|
||||||
|
[
|
||||||
|
'tag' => $string,
|
||||||
|
'tagMode' => 'nothing',
|
||||||
|
'user_id' => Auth::user()->id,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$tags->push($tag);
|
||||||
|
}
|
||||||
|
$tags = $tags->merge($this->data['tags']);
|
||||||
|
|
||||||
|
return $tags;
|
||||||
|
}
|
||||||
|
}
|
@@ -7,8 +7,6 @@ use Auth;
|
|||||||
use Config;
|
use Config;
|
||||||
use FireflyIII\Exceptions\FireflyException;
|
use FireflyIII\Exceptions\FireflyException;
|
||||||
use FireflyIII\Helpers\Csv\Converter\ConverterInterface;
|
use FireflyIII\Helpers\Csv\Converter\ConverterInterface;
|
||||||
use FireflyIII\Models\Account;
|
|
||||||
use FireflyIII\Models\AccountType;
|
|
||||||
use FireflyIII\Models\Transaction;
|
use FireflyIII\Models\Transaction;
|
||||||
use FireflyIII\Models\TransactionCurrency;
|
use FireflyIII\Models\TransactionCurrency;
|
||||||
use FireflyIII\Models\TransactionJournal;
|
use FireflyIII\Models\TransactionJournal;
|
||||||
@@ -16,7 +14,6 @@ use FireflyIII\Models\TransactionType;
|
|||||||
use Illuminate\Support\MessageBag;
|
use Illuminate\Support\MessageBag;
|
||||||
use Log;
|
use Log;
|
||||||
use Preferences;
|
use Preferences;
|
||||||
use ReflectionException;
|
|
||||||
|
|
||||||
set_time_limit(0);
|
set_time_limit(0);
|
||||||
|
|
||||||
@@ -75,10 +72,10 @@ class Importer
|
|||||||
$this->map = $this->data->getMap();
|
$this->map = $this->data->getMap();
|
||||||
$this->roles = $this->data->getRoles();
|
$this->roles = $this->data->getRoles();
|
||||||
$this->mapped = $this->data->getMapped();
|
$this->mapped = $this->data->getMapped();
|
||||||
|
|
||||||
foreach ($this->data->getReader() as $index => $row) {
|
foreach ($this->data->getReader() as $index => $row) {
|
||||||
if (($this->data->getHasHeaders() && $index > 1) || !$this->data->getHasHeaders()) {
|
if ($this->parseRow($index)) {
|
||||||
$this->rows++;
|
$this->rows++;
|
||||||
Log::debug('Now at row ' . $index);
|
|
||||||
$result = $this->importRow($row);
|
$result = $this->importRow($row);
|
||||||
if (!($result === true)) {
|
if (!($result === true)) {
|
||||||
Log::error('Caught error at row #' . $index . ': ' . $result);
|
Log::error('Caught error at row #' . $index . ': ' . $result);
|
||||||
@@ -90,6 +87,16 @@ class Importer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $index
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function parseRow($index)
|
||||||
|
{
|
||||||
|
return (($this->data->getHasHeaders() && $index > 1) || !$this->data->getHasHeaders());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $row
|
* @param $row
|
||||||
*
|
*
|
||||||
@@ -107,18 +114,8 @@ class Importer
|
|||||||
$class = Config::get('csv.roles.' . $role . '.converter');
|
$class = Config::get('csv.roles.' . $role . '.converter');
|
||||||
$field = Config::get('csv.roles.' . $role . '.field');
|
$field = Config::get('csv.roles.' . $role . '.field');
|
||||||
|
|
||||||
if (is_null($class)) {
|
/** @var ConverterInterface $converter */
|
||||||
throw new FireflyException('No converter for field of type "' . $role . '".');
|
$converter = App::make('FireflyIII\Helpers\Csv\Converter\\' . $class);
|
||||||
}
|
|
||||||
if (is_null($field)) {
|
|
||||||
throw new FireflyException('No place to store value of type "' . $role . '".');
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
/** @var ConverterInterface $converter */
|
|
||||||
$converter = App::make('FireflyIII\Helpers\Csv\Converter\\' . $class);
|
|
||||||
} catch (ReflectionException $e) {
|
|
||||||
throw new FireflyException('Cannot continue with column of type "' . $role . '" because class "' . $class . '" cannot be found.');
|
|
||||||
}
|
|
||||||
$converter->setData($data); // the complete array so far.
|
$converter->setData($data); // the complete array so far.
|
||||||
$converter->setField($field);
|
$converter->setField($field);
|
||||||
$converter->setIndex($index);
|
$converter->setIndex($index);
|
||||||
@@ -128,7 +125,8 @@ class Importer
|
|||||||
$data[$field] = $converter->convert();
|
$data[$field] = $converter->convert();
|
||||||
|
|
||||||
}
|
}
|
||||||
$data = $this->postProcess($data, $row);
|
// post processing and validating.
|
||||||
|
$data = $this->postProcess($data);
|
||||||
$result = $this->validateData($data);
|
$result = $this->validateData($data);
|
||||||
if ($result === true) {
|
if ($result === true) {
|
||||||
$result = $this->createTransactionJournal($data);
|
$result = $this->createTransactionJournal($data);
|
||||||
@@ -168,37 +166,42 @@ class Importer
|
|||||||
* Row denotes the original data.
|
* Row denotes the original data.
|
||||||
*
|
*
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @param array $row
|
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function postProcess(array $data, array $row)
|
protected function postProcess(array $data)
|
||||||
{
|
{
|
||||||
|
// fix two simple fields:
|
||||||
bcscale(2);
|
bcscale(2);
|
||||||
$data['description'] = trim($data['description']);
|
$data['description'] = trim($data['description']);
|
||||||
$data['amount'] = bcmul($data['amount'], $data['amount-modifier']);
|
$data['amount'] = bcmul($data['amount'], $data['amount-modifier']);
|
||||||
|
|
||||||
|
|
||||||
// get opposing account, which is quite complex:
|
|
||||||
$data['opposing-account-object'] = $this->processOpposingAccount($data);
|
|
||||||
|
|
||||||
if (strlen($data['description']) == 0) {
|
if (strlen($data['description']) == 0) {
|
||||||
$data['description'] = trans('firefly.csv_empty_description');
|
$data['description'] = trans('firefly.csv_empty_description');
|
||||||
}
|
}
|
||||||
|
|
||||||
// fix currency
|
// fix currency
|
||||||
if (is_null($data['currency'])) {
|
if (is_null($data['currency'])) {
|
||||||
$currencyPreference = Preferences::get('currencyPreference', 'EUR');
|
$currencyPreference = Preferences::get('currencyPreference', 'EUR');
|
||||||
$data['currency'] = TransactionCurrency::whereCode($currencyPreference->data)->first();
|
$data['currency'] = TransactionCurrency::whereCode($currencyPreference->data)->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get bill id.
|
||||||
if (!is_null($data['bill'])) {
|
if (!is_null($data['bill'])) {
|
||||||
$data['bill-id'] = $data['bill']->id;
|
$data['bill-id'] = $data['bill']->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// opposing account can be difficult.
|
||||||
|
|
||||||
|
// get opposing account, which is quite complex:
|
||||||
|
$opposingAccount = new OpposingAccount($data);
|
||||||
|
$data['opposing-account-object'] = $opposingAccount->parse();
|
||||||
|
|
||||||
// do bank specific fixes:
|
// do bank specific fixes:
|
||||||
|
|
||||||
$specifix = new Specifix();
|
// $specifix = new Specifix();
|
||||||
$specifix->setData($data);
|
// $specifix->setData($data);
|
||||||
$specifix->setRow($row);
|
// $specifix->setRow($row);
|
||||||
//$specifix->fix($data, $row); // TODO
|
//$specifix->fix($data, $row); // TODO
|
||||||
// get data back:
|
// get data back:
|
||||||
//$data = $specifix->getData(); // TODO
|
//$data = $specifix->getData(); // TODO
|
||||||
@@ -206,97 +209,6 @@ class Importer
|
|||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $data
|
|
||||||
*/
|
|
||||||
protected function processOpposingAccount(array $data)
|
|
||||||
{
|
|
||||||
// first priority. try to find the account based on ID,
|
|
||||||
// if any.
|
|
||||||
if ($data['opposing-account-id'] instanceof Account) {
|
|
||||||
return $data['opposing-account-id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// second: try to find the account based on IBAN, if any.
|
|
||||||
if ($data['opposing-account-iban'] instanceof Account) {
|
|
||||||
return $data['opposing-account-iban'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$accountType = $this->getAccountType($data['amount']);
|
|
||||||
|
|
||||||
if (is_string($data['opposing-account-iban'])) {
|
|
||||||
$accounts = Auth::user()->accounts()->where('account_type_id', $accountType->id)->get();
|
|
||||||
foreach ($accounts as $entry) {
|
|
||||||
if ($entry->iban == $data['opposing-account-iban']) {
|
|
||||||
|
|
||||||
//return $entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// create if not exists:
|
|
||||||
$account = Account::firstOrCreateEncrypted(
|
|
||||||
[
|
|
||||||
'user_id' => Auth::user()->id,
|
|
||||||
'account_type_id' => $accountType->id,
|
|
||||||
'name' => $data['opposing-account-iban'],
|
|
||||||
'iban' => $data['opposing-account-iban'],
|
|
||||||
'active' => true,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
return $account;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// third: try to find account based on name, if any.
|
|
||||||
if ($data['opposing-account-name'] instanceof Account) {
|
|
||||||
return $data['opposing-account-name'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_string($data['opposing-account-name'])) {
|
|
||||||
$accounts = Auth::user()->accounts()->where('account_type_id', $accountType->id)->get();
|
|
||||||
foreach ($accounts as $entry) {
|
|
||||||
if ($entry->name == $data['opposing-account-name']) {
|
|
||||||
return $entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// create if not exists:
|
|
||||||
$account = Account::firstOrCreateEncrypted(
|
|
||||||
[
|
|
||||||
'user_id' => Auth::user()->id,
|
|
||||||
'account_type_id' => $accountType->id,
|
|
||||||
'name' => $data['opposing-account-name'],
|
|
||||||
'iban' => '',
|
|
||||||
'active' => true,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
return $account;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// if nothing, create expense/revenue, never asset. TODO
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $amount
|
|
||||||
*
|
|
||||||
* @return AccountType
|
|
||||||
*/
|
|
||||||
protected function getAccountType($amount)
|
|
||||||
{
|
|
||||||
// opposing account type:
|
|
||||||
if ($amount < 0) {
|
|
||||||
// create expense account:
|
|
||||||
|
|
||||||
return AccountType::where('type', 'Expense account')->first();
|
|
||||||
} else {
|
|
||||||
// create revenue account:
|
|
||||||
|
|
||||||
return AccountType::where('type', 'Revenue account')->first();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $data
|
* @param $data
|
||||||
*
|
*
|
||||||
@@ -326,11 +238,17 @@ class Importer
|
|||||||
if (is_null($data['date'])) {
|
if (is_null($data['date'])) {
|
||||||
$date = $data['date-rent'];
|
$date = $data['date-rent'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// defaults to deposit
|
||||||
|
$transactionType = TransactionType::where('type', 'Deposit')->first();
|
||||||
if ($data['amount'] < 0) {
|
if ($data['amount'] < 0) {
|
||||||
$transactionType = TransactionType::where('type', 'Withdrawal')->first();
|
$transactionType = TransactionType::where('type', 'Withdrawal')->first();
|
||||||
} else {
|
|
||||||
$transactionType = TransactionType::where('type', 'Deposit')->first();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($data['opposing-account-object']->accountType->type == 'Asset account') {
|
||||||
|
$transactionType = TransactionType::where('type', 'Transfer')->first();
|
||||||
|
}
|
||||||
|
|
||||||
$errors = new MessageBag;
|
$errors = new MessageBag;
|
||||||
$journal = TransactionJournal::create(
|
$journal = TransactionJournal::create(
|
||||||
[
|
[
|
||||||
@@ -378,6 +296,11 @@ class Importer
|
|||||||
if (!is_null($data['category'])) {
|
if (!is_null($data['category'])) {
|
||||||
$journal->categories()->save($data['category']);
|
$journal->categories()->save($data['category']);
|
||||||
}
|
}
|
||||||
|
if (!is_null($data['tags'])) {
|
||||||
|
foreach ($data['tags'] as $tag) {
|
||||||
|
$journal->tags()->save($tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $journal;
|
return $journal;
|
||||||
|
|
||||||
@@ -391,6 +314,4 @@ class Importer
|
|||||||
{
|
{
|
||||||
$this->data = $data;
|
$this->data = $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
32
app/Helpers/Csv/Mapper/AnyAccount.php
Normal file
32
app/Helpers/Csv/Mapper/AnyAccount.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Helpers\Csv\Mapper;
|
||||||
|
|
||||||
|
use Auth;
|
||||||
|
use FireflyIII\Models\Account;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class AnyAccount
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Helpers\Csv\Mapper
|
||||||
|
*/
|
||||||
|
class AnyAccount implements MapperInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getMap()
|
||||||
|
{
|
||||||
|
$result = Auth::user()->accounts()->with('accountType')->orderBy('accounts.name', 'ASC')->get(['accounts.*']);
|
||||||
|
|
||||||
|
$list = [];
|
||||||
|
/** @var Account $account */
|
||||||
|
foreach ($result as $account) {
|
||||||
|
$list[$account->id] = $account->name . ' (' . $account->accountType->type . ')';
|
||||||
|
}
|
||||||
|
asort($list);
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
}
|
@@ -31,6 +31,8 @@ class AssetAccount implements MapperInterface
|
|||||||
$list[$account->id] = $account->name;
|
$list[$account->id] = $account->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asort($list);
|
||||||
|
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
}
|
}
|
32
app/Helpers/Csv/Mapper/Bill.php
Normal file
32
app/Helpers/Csv/Mapper/Bill.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Helpers\Csv\Mapper;
|
||||||
|
|
||||||
|
use Auth;
|
||||||
|
use FireflyIII\Models\Bill as BillModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Bill
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Helpers\Csv\Mapper
|
||||||
|
*/
|
||||||
|
class Bill implements MapperInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getMap()
|
||||||
|
{
|
||||||
|
$result = Auth::user()->bills()->get(['bills.*']);
|
||||||
|
$list = [];
|
||||||
|
|
||||||
|
/** @var BillModel $bill */
|
||||||
|
foreach ($result as $bill) {
|
||||||
|
$list[$bill->id] = $bill->name . ' [' . $bill->match . ']';
|
||||||
|
}
|
||||||
|
asort($list);
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
}
|
32
app/Helpers/Csv/Mapper/Budget.php
Normal file
32
app/Helpers/Csv/Mapper/Budget.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Helpers\Csv\Mapper;
|
||||||
|
|
||||||
|
use Auth;
|
||||||
|
use FireflyIII\Models\Budget as BudgetModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Budget
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Helpers\Csv\Mapper
|
||||||
|
*/
|
||||||
|
class Budget implements MapperInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getMap()
|
||||||
|
{
|
||||||
|
$result = Auth::user()->budgets()->get(['budgets.*']);
|
||||||
|
$list = [];
|
||||||
|
|
||||||
|
/** @var BudgetModel $budget */
|
||||||
|
foreach ($result as $budget) {
|
||||||
|
$list[$budget->id] = $budget->name;
|
||||||
|
}
|
||||||
|
asort($list);
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
}
|
32
app/Helpers/Csv/Mapper/Category.php
Normal file
32
app/Helpers/Csv/Mapper/Category.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Helpers\Csv\Mapper;
|
||||||
|
|
||||||
|
use Auth;
|
||||||
|
use FireflyIII\Models\Category as CategoryModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Category
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Helpers\Csv\Mapper
|
||||||
|
*/
|
||||||
|
class Category implements MapperInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getMap()
|
||||||
|
{
|
||||||
|
$result = Auth::user()->categories()->get(['categories.*']);
|
||||||
|
$list = [];
|
||||||
|
|
||||||
|
/** @var CategoryModel $category */
|
||||||
|
foreach ($result as $category) {
|
||||||
|
$list[$category->id] = $category->name;
|
||||||
|
}
|
||||||
|
asort($list);
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
}
|
32
app/Helpers/Csv/Mapper/Tag.php
Normal file
32
app/Helpers/Csv/Mapper/Tag.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Helpers\Csv\Mapper;
|
||||||
|
|
||||||
|
use Auth;
|
||||||
|
use FireflyIII\Models\Tag as TagModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Tag
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Helpers\Csv\Mapper
|
||||||
|
*/
|
||||||
|
class Tag implements MapperInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getMap()
|
||||||
|
{
|
||||||
|
$result = Auth::user()->budgets()->get(['tags.*']);
|
||||||
|
$list = [];
|
||||||
|
|
||||||
|
/** @var TagModel $tag */
|
||||||
|
foreach ($result as $tag) {
|
||||||
|
$list[$tag->id] = $tag->tag;
|
||||||
|
}
|
||||||
|
asort($list);
|
||||||
|
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
}
|
137
app/Helpers/Csv/OpposingAccount.php
Normal file
137
app/Helpers/Csv/OpposingAccount.php
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Helpers\Csv;
|
||||||
|
|
||||||
|
use Auth;
|
||||||
|
use FireflyIII\Models\Account;
|
||||||
|
use FireflyIII\Models\AccountType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class OpposingAccount
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Helpers\Csv
|
||||||
|
*/
|
||||||
|
class OpposingAccount
|
||||||
|
{
|
||||||
|
/** @var array */
|
||||||
|
protected $data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
*/
|
||||||
|
public function __construct(array $data)
|
||||||
|
{
|
||||||
|
$this->data = $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \FireflyIII\Models\Account|null
|
||||||
|
*/
|
||||||
|
public function parse()
|
||||||
|
{
|
||||||
|
// first priority. try to find the account based on ID,
|
||||||
|
// if any.
|
||||||
|
if ($this->data['opposing-account-id'] instanceof Account) {
|
||||||
|
|
||||||
|
return $this->data['opposing-account-id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// second: try to find the account based on IBAN, if any.
|
||||||
|
if ($this->data['opposing-account-iban'] instanceof Account) {
|
||||||
|
return $this->data['opposing-account-iban'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (is_string($this->data['opposing-account-iban'])) {
|
||||||
|
|
||||||
|
return $this->parseIbanString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// third: try to find account based on name, if any.
|
||||||
|
if ($this->data['opposing-account-name'] instanceof Account) {
|
||||||
|
|
||||||
|
return $this->data['opposing-account-name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($this->data['opposing-account-name'])) {
|
||||||
|
return $this->parseNameString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// if nothing, create expense/revenue, never asset. TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Account|null
|
||||||
|
*/
|
||||||
|
protected function parseIbanString()
|
||||||
|
{
|
||||||
|
|
||||||
|
// create by name and/or iban.
|
||||||
|
$accountType = $this->getAccountType();
|
||||||
|
$accounts = Auth::user()->accounts()->where('account_type_id', $accountType->id)->get();
|
||||||
|
foreach ($accounts as $entry) {
|
||||||
|
if ($entry->iban == $this->data['opposing-account-iban']) {
|
||||||
|
|
||||||
|
return $entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// create if not exists:
|
||||||
|
$account = Account::firstOrCreateEncrypted(
|
||||||
|
[
|
||||||
|
'user_id' => Auth::user()->id,
|
||||||
|
'account_type_id' => $accountType->id,
|
||||||
|
'name' => $this->data['opposing-account-iban'],
|
||||||
|
'iban' => $this->data['opposing-account-iban'],
|
||||||
|
'active' => true,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
return $account;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return AccountType
|
||||||
|
*/
|
||||||
|
protected function getAccountType()
|
||||||
|
{
|
||||||
|
// opposing account type:
|
||||||
|
if ($this->data['amount'] < 0) {
|
||||||
|
// create expense account:
|
||||||
|
|
||||||
|
return AccountType::where('type', 'Expense account')->first();
|
||||||
|
} else {
|
||||||
|
// create revenue account:
|
||||||
|
|
||||||
|
return AccountType::where('type', 'Revenue account')->first();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Account|null
|
||||||
|
*/
|
||||||
|
protected function parseNameString()
|
||||||
|
{
|
||||||
|
$accountType = $this->getAccountType();
|
||||||
|
$accounts = Auth::user()->accounts()->where('account_type_id', $accountType->id)->get();
|
||||||
|
foreach ($accounts as $entry) {
|
||||||
|
if ($entry->name == $this->data['opposing-account-name']) {
|
||||||
|
return $entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// create if not exists:
|
||||||
|
$account = Account::firstOrCreateEncrypted(
|
||||||
|
[
|
||||||
|
'user_id' => Auth::user()->id,
|
||||||
|
'account_type_id' => $accountType->id,
|
||||||
|
'name' => $this->data['opposing-account-name'],
|
||||||
|
'iban' => '',
|
||||||
|
'active' => true,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
return $account;
|
||||||
|
}
|
||||||
|
}
|
@@ -151,6 +151,7 @@ class CsvController extends Controller
|
|||||||
Session::forget('csv-map');
|
Session::forget('csv-map');
|
||||||
Session::forget('csv-roles');
|
Session::forget('csv-roles');
|
||||||
Session::forget('csv-mapped');
|
Session::forget('csv-mapped');
|
||||||
|
Session::forget('csv-specifix');
|
||||||
|
|
||||||
// get values which are yet unsaveable or unmappable:
|
// get values which are yet unsaveable or unmappable:
|
||||||
$unsupported = [];
|
$unsupported = [];
|
||||||
|
@@ -11,25 +11,29 @@ return [
|
|||||||
'name' => 'Bill ID (matching Firefly)',
|
'name' => 'Bill ID (matching Firefly)',
|
||||||
'mappable' => false,
|
'mappable' => false,
|
||||||
'field' => 'bill',
|
'field' => 'bill',
|
||||||
'converter' => 'BillId'
|
'converter' => 'BillId',
|
||||||
|
'mapper' => 'Bill',
|
||||||
],
|
],
|
||||||
'bill-name' => [
|
'bill-name' => [
|
||||||
'name' => 'Bill name',
|
'name' => 'Bill name',
|
||||||
'mappable' => true,
|
'mappable' => true,
|
||||||
'converter' => 'BillName',
|
'converter' => 'BillName',
|
||||||
'field' => 'bill',
|
'field' => 'bill',
|
||||||
|
'mapper' => 'Bill',
|
||||||
],
|
],
|
||||||
'currency-id' => [
|
'currency-id' => [
|
||||||
'name' => 'Currency ID (matching Firefly)',
|
'name' => 'Currency ID (matching Firefly)',
|
||||||
'mappable' => true,
|
'mappable' => true,
|
||||||
'converter' => 'CurrencyId',
|
'converter' => 'CurrencyId',
|
||||||
'field' => 'currency',
|
'field' => 'currency',
|
||||||
|
'mapper' => 'TransactionCurrency'
|
||||||
],
|
],
|
||||||
'currency-name' => [
|
'currency-name' => [
|
||||||
'name' => 'Currency name (matching Firefly)',
|
'name' => 'Currency name (matching Firefly)',
|
||||||
'mappable' => true,
|
'mappable' => true,
|
||||||
'converter' => 'CurrencyName',
|
'converter' => 'CurrencyName',
|
||||||
'field' => 'currency',
|
'field' => 'currency',
|
||||||
|
'mapper' => 'TransactionCurrency'
|
||||||
],
|
],
|
||||||
'currency-code' => [
|
'currency-code' => [
|
||||||
'name' => 'Currency code (ISO 4217)',
|
'name' => 'Currency code (ISO 4217)',
|
||||||
@@ -43,6 +47,7 @@ return [
|
|||||||
'mappable' => true,
|
'mappable' => true,
|
||||||
'converter' => 'CurrencySymbol',
|
'converter' => 'CurrencySymbol',
|
||||||
'field' => 'currency',
|
'field' => 'currency',
|
||||||
|
'mapper' => 'TransactionCurrency'
|
||||||
],
|
],
|
||||||
'description' => [
|
'description' => [
|
||||||
'name' => 'Description',
|
'name' => 'Description',
|
||||||
@@ -66,13 +71,15 @@ return [
|
|||||||
'name' => 'Budget ID (matching Firefly)',
|
'name' => 'Budget ID (matching Firefly)',
|
||||||
'mappable' => true,
|
'mappable' => true,
|
||||||
'converter' => 'BudgetId',
|
'converter' => 'BudgetId',
|
||||||
'field' => 'budget'
|
'field' => 'budget',
|
||||||
|
'mapper' => 'Budget',
|
||||||
],
|
],
|
||||||
'budget-name' => [
|
'budget-name' => [
|
||||||
'name' => 'Budget name',
|
'name' => 'Budget name',
|
||||||
'mappable' => true,
|
'mappable' => true,
|
||||||
'converter' => 'BudgetName',
|
'converter' => 'BudgetName',
|
||||||
'field' => 'budget'
|
'field' => 'budget',
|
||||||
|
'mapper' => 'Budget',
|
||||||
],
|
],
|
||||||
'rabo-debet-credit' => [
|
'rabo-debet-credit' => [
|
||||||
'name' => 'Rabobank specific debet/credit indicator',
|
'name' => 'Rabobank specific debet/credit indicator',
|
||||||
@@ -84,21 +91,29 @@ return [
|
|||||||
'name' => 'Category ID (matching Firefly)',
|
'name' => 'Category ID (matching Firefly)',
|
||||||
'mappable' => true,
|
'mappable' => true,
|
||||||
'converter' => 'CategoryId',
|
'converter' => 'CategoryId',
|
||||||
'field' => 'category'
|
'field' => 'category',
|
||||||
|
'mapper' => 'Category',
|
||||||
],
|
],
|
||||||
'category-name' => [
|
'category-name' => [
|
||||||
'name' => 'Category name',
|
'name' => 'Category name',
|
||||||
'mappable' => true,
|
'mappable' => true,
|
||||||
'converter' => 'CategoryName',
|
'converter' => 'CategoryName',
|
||||||
'field' => 'category'
|
'field' => 'category',
|
||||||
|
'mapper' => 'Category',
|
||||||
],
|
],
|
||||||
'tags-comma' => [
|
'tags-comma' => [
|
||||||
'name' => 'Tags (comma separated)',
|
'name' => 'Tags (comma separated)',
|
||||||
'mappable' => true,
|
'mappable' => true,
|
||||||
|
'field' => 'tags',
|
||||||
|
'converter' => 'TagsComma',
|
||||||
|
'mapper' => 'Tag',
|
||||||
],
|
],
|
||||||
'tags-space' => [
|
'tags-space' => [
|
||||||
'name' => 'Tags (space separated)',
|
'name' => 'Tags (space separated)',
|
||||||
'mappable' => true,
|
'mappable' => true,
|
||||||
|
'field' => 'tags',
|
||||||
|
'converter' => 'TagsSpace',
|
||||||
|
'mapper' => 'Tag',
|
||||||
],
|
],
|
||||||
'account-id' => [
|
'account-id' => [
|
||||||
'name' => 'Asset account ID (matching Firefly)',
|
'name' => 'Asset account ID (matching Firefly)',
|
||||||
@@ -125,19 +140,22 @@ return [
|
|||||||
'name' => 'Opposing account account ID (matching Firefly)',
|
'name' => 'Opposing account account ID (matching Firefly)',
|
||||||
'mappable' => true,
|
'mappable' => true,
|
||||||
'field' => 'opposing-account-id',
|
'field' => 'opposing-account-id',
|
||||||
'converter' => 'OpposingAccountId'
|
'converter' => 'OpposingAccountId',
|
||||||
|
'mapper' => 'AnyAccount',
|
||||||
],
|
],
|
||||||
'opposing-name' => [
|
'opposing-name' => [
|
||||||
'name' => 'Opposing account name',
|
'name' => 'Opposing account name',
|
||||||
'mappable' => true,
|
'mappable' => true,
|
||||||
'field' => 'opposing-account-name',
|
'field' => 'opposing-account-name',
|
||||||
'converter' => 'OpposingAccountName'
|
'converter' => 'OpposingAccountName',
|
||||||
|
'mapper' => 'AnyAccount',
|
||||||
],
|
],
|
||||||
'opposing-iban' => [
|
'opposing-iban' => [
|
||||||
'name' => 'Opposing account IBAN',
|
'name' => 'Opposing account IBAN',
|
||||||
'mappable' => true,
|
'mappable' => true,
|
||||||
'field' => 'opposing-account-iban',
|
'field' => 'opposing-account-iban',
|
||||||
'converter' => 'OpposingAccountIban'
|
'converter' => 'OpposingAccountIban',
|
||||||
|
'mapper' => 'AnyAccount',
|
||||||
],
|
],
|
||||||
'amount' => [
|
'amount' => [
|
||||||
'name' => 'Amount',
|
'name' => 'Amount',
|
||||||
|
Reference in New Issue
Block a user