Import fix asset account.

This commit is contained in:
James Cole
2015-07-09 16:37:42 +02:00
parent 18b8a05014
commit 28f601b54b
8 changed files with 246 additions and 24 deletions

View File

@@ -25,16 +25,19 @@ class Data
protected $hasHeaders;
/** @var array */
protected $map;
protected $map = [];
/** @var array */
protected $mapped;
protected $mapped = [];
/** @var Reader */
protected $reader;
/** @var array */
protected $roles;
protected $roles = [];
/** @var array */
protected $specifix;
protected $specifix = [];
/** @var int */
protected $importAccount = 0;
/**
*
@@ -48,6 +51,7 @@ class Data
$this->sessionRoles();
$this->sessionMapped();
$this->sessionSpecifix();
$this->sessionImportAccount();
}
protected function sessionHasHeaders()
@@ -57,6 +61,13 @@ class Data
}
}
protected function sessionImportAccount()
{
if (Session::has('csv-import-account')) {
$this->importAccount = intval(Session::get('csv-import-account'));
}
}
protected function sessionDateFormat()
{
if (Session::has('csv-date-format')) {
@@ -116,6 +127,15 @@ class Data
$this->dateFormat = $dateFormat;
}
/**
* @param int $importAccount
*/
public function setImportAccount($importAccount)
{
Session::put('csv-import-account', $importAccount);
$this->importAccount = $importAccount;
}
/**
* @return bool
*/

View File

@@ -171,6 +171,7 @@ class Importer
// some extra's:
$filler['bill-id'] = null;
$filler['opposing-account-object'] = null;
$filler['asset-account-object'] = null;
$filler['amount-modifier'] = '1';
return $filler;
@@ -241,7 +242,7 @@ class Importer
$date = $this->importData['date-rent'];
}
if (!($this->importData['asset-account'] instanceof Account)) {
if (!($this->importData['asset-account-object'] instanceof Account)) {
return 'No asset account to import into.';
}
@@ -252,10 +253,13 @@ class Importer
'description' => $this->importData['description'], 'completed' => 0, 'date' => $date, 'bill_id' => $this->importData['bill-id'],]
);
if ($journal->getErrors()->count() == 0) {
$accountId = $this->importData['asset-account']->id; // create first transaction:
// first transaction
$accountId = $this->importData['asset-account-object']->id; // create first transaction:
$amount = $this->importData['amount'];
$transaction = Transaction::create(['transaction_journal_id' => $journal->id, 'account_id' => $accountId, 'amount' => $amount]);
$errors = $transaction->getErrors();
// second transaction
$accountId = $this->importData['opposing-account-object']->id; // create second transaction:
$amount = bcmul($this->importData['amount'], -1);
$transaction = Transaction::create(['transaction_journal_id' => $journal->id, 'account_id' => $accountId, 'amount' => $amount]);

View File

@@ -0,0 +1,185 @@
<?php
namespace FireflyIII\Helpers\Csv\PostProcessing;
use Auth;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use Log;
use Validator;
/**
* Class AssetAccount
*
* @package FireflyIII\Helpers\Csv\PostProcessing
*/
class AssetAccount implements PostProcessorInterface
{
/** @var array */
protected $data;
/**
* @return array
*/
public function process()
{
$result = $this->checkIdNameObject(); // has object in ID or Name?
if (!is_null($result)) {
return $result;
}
$result = $this->checkIbanString();
if (!is_null($result)) {
return $result;
}
$result = $this->checkNameString();
if (!is_null($result)) {
return $result;
}
return null;
}
/**
* @param array $data
*/
public function setData(array $data)
{
$this->data = $data;
}
/**
* @return array
*/
protected function checkIdNameObject()
{
if ($this->data['asset-account-id'] instanceof Account) { // first priority. try to find the account based on ID, if any
$this->data['asset-account-object'] = $this->data['asset-account-id'];
return $this->data;
}
if ($this->data['asset-account-iban'] instanceof Account) { // second: try to find the account based on IBAN, if any.
$this->data['asset-account-object'] = $this->data['asset-account-iban'];
return $this->data;
}
return null;
}
/**
* @return array|null
*/
protected function checkIbanString()
{
$rules = ['iban' => 'iban'];
$check = ['iban' => $this->data['asset-account-iban']];
$validator = Validator::make($check, $rules);
if (!$validator->fails()) {
$this->data['asset-account-object'] = $this->parseIbanString();
return $this->data;
}
return null;
}
/**
* @return Account|null
*/
protected function parseIbanString()
{
// create by name and/or iban.
$accounts = Auth::user()->accounts()->get();
foreach ($accounts as $entry) {
if ($entry->iban == $this->data['asset-account-iban']) {
return $entry;
}
}
$account = $this->createAccount();
return $account;
}
/**
* @return Account|null
*/
protected function createAccount()
{
$accountType = $this->getAccountType();
// create if not exists:
$name = is_string($this->data['asset-account-name']) && strlen($this->data['asset-account-name']) > 0 ? $this->data['asset-account-name']
: $this->data['asset-account-iban'];
$account = Account::firstOrCreateEncrypted(
[
'user_id' => Auth::user()->id,
'account_type_id' => $accountType->id,
'name' => $name,
'iban' => $this->data['asset-account-iban'],
'active' => true,
]
);
return $account;
}
/**
*
* @return AccountType
*/
protected function getAccountType()
{
return AccountType::where('type', 'Asset account')->first();
}
/**
* @return array|null
*/
protected function checkNameString()
{
if ($this->data['asset-account-name'] instanceof Account) { // third: try to find account based on name, if any.
$this->data['asset-account-object'] = $this->data['asset-account-name'];
return $this->data;
}
if (is_string($this->data['asset-account-name'])) {
$this->data['asset-account-object'] = $this->parseNameString();
return $this->data;
}
return null;
}
/**
* @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['asset-account-name']) {
Log::debug('Found an asset account with this name (#' . $entry->id . ': ' . $entry->name . ')');
return $entry;
}
}
// create if not exists:
$account = Account::firstOrCreateEncrypted(
[
'user_id' => Auth::user()->id,
'account_type_id' => $accountType->id,
'name' => $this->data['asset-account-name'],
'iban' => '',
'active' => true,
]
);
return $account;
}
}

View File

@@ -3,10 +3,12 @@
namespace FireflyIII\Http\Controllers;
use Config;
use ExpandedForm;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Csv\Data;
use FireflyIII\Helpers\Csv\Importer;
use FireflyIII\Helpers\Csv\WizardInterface;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Illuminate\Http\Request;
use Input;
use Log;
@@ -55,7 +57,7 @@ class CsvController extends Controller
public function columnRoles()
{
$fields = ['csv-file', 'csv-date-format', 'csv-has-headers'];
$fields = ['csv-file', 'csv-date-format', 'csv-has-headers','csv-import-account'];
if (!$this->wizard->sessionHasValues($fields)) {
Session::flash('warning', 'Could not recover upload.');
@@ -142,13 +144,14 @@ class CsvController extends Controller
*
* @return \Illuminate\View\View
*/
public function index()
public function index(AccountRepositoryInterface $repository)
{
$subTitle = trans('firefly.csv_import');
Session::forget('csv-date-format');
Session::forget('csv-has-headers');
Session::forget('csv-file');
Session::forget('csv-import-account');
Session::forget('csv-map');
Session::forget('csv-roles');
Session::forget('csv-mapped');
@@ -160,11 +163,14 @@ class CsvController extends Controller
$specifix[$entry] = trans('firefly.csv_specifix_' . $entry);
}
// get a list of asset accounts:
$accounts = ExpandedForm::makeSelectList($repository->getAccounts(['Asset account', 'Default account']));
// can actually upload?
$uploadPossible = is_writable(storage_path('upload'));
$path = storage_path('upload');
return view('csv.index', compact('subTitle', 'uploadPossible', 'path', 'specifix'));
return view('csv.index', compact('subTitle', 'uploadPossible', 'path', 'specifix', 'accounts'));
}
/**
@@ -366,19 +372,17 @@ class CsvController extends Controller
return redirect(route('csv.index'));
}
$fullPath = $this->wizard->storeCsvFile($request->file('csv')->getRealPath());
$settings = [];
$settings['date-format'] = Input::get('date_format');
$settings['has-headers'] = intval(Input::get('has_headers')) === 1;
$settings['specifix'] = Input::get('specifix');
$settings['map'] = [];
$settings['mapped'] = [];
$settings['roles'] = [];
$fullPath = $this->wizard->storeCsvFile($request->file('csv')->getRealPath());
$settings = [];
$settings['date-format'] = Input::get('date_format');
$settings['has-headers'] = intval(Input::get('has_headers')) === 1;
$settings['specifix'] = Input::get('specifix');
$settings['import-account'] = intval(Input::get('csv_import_account'));
$settings['map'] = [];
$settings['mapped'] = [];
$settings['roles'] = [];
/*
* Process config file if present.
*/
if ($request->hasFile('csv_config')) {
if ($request->hasFile('csv_config')) { // Process config file if present.
$data = file_get_contents($request->file('csv_config')->getRealPath());
$json = json_decode($data, true);
if (is_array($json)) {
@@ -393,6 +397,7 @@ class CsvController extends Controller
$this->data->setMapped($settings['mapped']);
$this->data->setRoles($settings['roles']);
$this->data->setSpecifix($settings['specifix']);
$this->data->setImportAccount($settings['import-account']);
return redirect(route('csv.column-roles'));

View File

@@ -131,21 +131,21 @@ return [
'name' => 'Asset account ID (matching Firefly)',
'mappable' => true,
'mapper' => 'AssetAccount',
'field' => 'asset-account',
'field' => 'asset-account-id',
'converter' => 'AccountId'
],
'account-name' => [
'name' => 'Asset account name',
'mappable' => true,
'mapper' => 'AssetAccount',
'field' => 'asset-account',
'field' => 'asset-account-name',
'converter' => 'AssetAccountName'
],
'account-iban' => [
'name' => 'Asset account IBAN',
'mappable' => true,
'converter' => 'AssetAccountIban',
'field' => 'asset-account',
'field' => 'asset-account-iban',
'mapper' => 'AssetAccount'
],
'opposing-id' => [

View File

@@ -117,6 +117,9 @@ return [
'csv_column_tags-space' => 'Tags (space separated)',
'csv_specifix_RabobankDescription' => 'Select this when you\'re importing Rabobank CSV export files.',
'csv_specifix_Dummy' => 'Checking this has no effect whatsoever.',
'csv_import_account_help' => 'If your CSV file does NOT contain information about your asset account(s), use this dropdown to select to which' .
' account the transactions in the CSV belong to.',
// create new stuff:
'create_new_withdrawal' => 'Create new withdrawal',

View File

@@ -51,6 +51,7 @@ return [
'date_format' => 'Date format',
'csv_config' => 'CSV import configuration',
'specifix' => 'Bank- or file specific fixes',
'csv_import_account' => 'Default import account',
'store_new_withdrawal' => 'Store new withdrawal',
'store_new_deposit' => 'Store new deposit',

View File

@@ -61,8 +61,12 @@
{{ ExpandedForm.file('csv_config',{helpText: 'csv_csv_config_file_help'|_}) }}
{{ ExpandedForm.select('csv_import_account', accounts, 0, {helpText: 'csv_import_account_help'|_} ) }}
{{ ExpandedForm.multiCheckbox('specifix', specifix) }}
{% if not uploadPossible %}
<div class="form-group" id="csv_holder">
<div class="col-sm-4">