mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Extend rule set for import.
This commit is contained in:
parent
186b704509
commit
0aaf9a6fda
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@ _development
|
||||
.env.local
|
||||
result.html
|
||||
test-import.sh
|
||||
test-import-report.txt
|
||||
|
@ -19,6 +19,7 @@ use FireflyIII\Import\Logging\CommandHandler;
|
||||
use FireflyIII\Models\ImportJob;
|
||||
use Illuminate\Console\Command;
|
||||
use Log;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
|
||||
/**
|
||||
* Class Import
|
||||
@ -80,6 +81,7 @@ class Import extends Command
|
||||
// intercept logging by importer.
|
||||
$monolog = Log::getMonolog();
|
||||
$handler = new CommandHandler($this);
|
||||
|
||||
$monolog->pushHandler($handler);
|
||||
|
||||
// create import entries
|
||||
|
@ -158,10 +158,12 @@ class AccountCrud implements AccountCrudInterface
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
if ($account->name === $name) {
|
||||
Log::debug('Account name is an exact match. ', ['db' => $account->name, 'source' => $name,'id' => $account->id]);
|
||||
Log::debug('Account name is an exact match. ', ['db' => $account->name, 'source' => $name, 'id' => $account->id]);
|
||||
|
||||
return $account;
|
||||
}
|
||||
}
|
||||
Log::warning('Found nothing in findByName()', ['name' => $name, 'types' => $types]);
|
||||
Log::debug('Found nothing in findByName()', ['name' => $name, 'types' => $types]);
|
||||
|
||||
return new Account;
|
||||
}
|
||||
@ -233,7 +235,7 @@ class AccountCrud implements AccountCrudInterface
|
||||
public function store(array $data): Account
|
||||
{
|
||||
$newAccount = $this->storeAccount($data);
|
||||
if (!is_null($newAccount)) {
|
||||
if (!is_null($newAccount->id)) {
|
||||
$this->storeMetadata($newAccount, $data);
|
||||
}
|
||||
|
||||
@ -327,8 +329,8 @@ class AccountCrud implements AccountCrudInterface
|
||||
];
|
||||
$existingAccount = Account::firstOrNullEncrypted($searchData);
|
||||
if (!$existingAccount) {
|
||||
Log::error('Account create error: ' . $newAccount->getErrors()->toJson());
|
||||
abort(500);
|
||||
Log::error('Account create error', $newAccount->getErrors()->toArray());
|
||||
return new Account;
|
||||
}
|
||||
$newAccount = $existingAccount;
|
||||
|
||||
|
@ -66,9 +66,17 @@ class AssetAccountIban extends BasicConverter implements ConverterInterface
|
||||
|
||||
|
||||
$account = $repository->store(
|
||||
['name' => 'Account with IBAN ' . $value, 'iban' => $value, 'user' => $this->user->id, 'accountType' => 'asset', 'virtualBalance' => 0,
|
||||
'active' => true]
|
||||
['name' => 'Asset account with IBAN ' . $value, 'iban' => $value, 'user' => $this->user->id, 'accountType' => 'asset', 'virtualBalance' => 0,
|
||||
'active' => true, 'openingBalance' => 0]
|
||||
);
|
||||
|
||||
if (is_null($account->id)) {
|
||||
$this->setCertainty(0);
|
||||
Log::info('Could not store new asset account by IBAN', $account->getErrors()->toArray());
|
||||
|
||||
return new Account;
|
||||
}
|
||||
|
||||
$this->setCertainty(100);
|
||||
|
||||
return $account;
|
||||
|
@ -68,6 +68,14 @@ class AssetAccountName extends BasicConverter implements ConverterInterface
|
||||
['name' => $value, 'iban' => null, 'openingBalance' => 0, 'user' => $this->user->id, 'accountType' => 'asset', 'virtualBalance' => 0,
|
||||
'active' => true]
|
||||
);
|
||||
|
||||
if (is_null($account->id)) {
|
||||
$this->setCertainty(0);
|
||||
Log::info('Could not store new asset account by name', $account->getErrors()->toArray());
|
||||
|
||||
return new Account;
|
||||
}
|
||||
|
||||
$this->setCertainty(100);
|
||||
|
||||
Log::debug('Created new asset account ', ['name' => $account->name, 'id' => $account->id]);
|
||||
|
@ -32,7 +32,7 @@ class AssetAccountNumber extends BasicConverter implements ConverterInterface
|
||||
public function convert($value)
|
||||
{
|
||||
$value = trim($value);
|
||||
Log::debug('Going to convert using AssetAccountName', ['value' => $value]);
|
||||
Log::debug('Going to convert using AssetAccountNumber', ['value' => $value]);
|
||||
|
||||
if (strlen($value) === 0) {
|
||||
return new Account;
|
||||
@ -77,6 +77,14 @@ class AssetAccountNumber extends BasicConverter implements ConverterInterface
|
||||
'accountType' => 'asset',
|
||||
'virtualBalance' => 0, 'accountNumber' => $value, 'active' => true]
|
||||
);
|
||||
|
||||
if (is_null($account->id)) {
|
||||
$this->setCertainty(0);
|
||||
Log::notice('Could not store new asset account by account number', $account->getErrors()->toArray());
|
||||
|
||||
return new Account;
|
||||
}
|
||||
|
||||
$this->setCertainty(100);
|
||||
|
||||
return $account;
|
||||
|
@ -63,6 +63,7 @@ class BillId extends BasicConverter implements ConverterInterface
|
||||
}
|
||||
|
||||
// should not really happen. If the ID does not match FF, what is FF supposed to do?
|
||||
Log::info(sprintf('Could not find bill with ID %d. Will return NULL', $value));
|
||||
|
||||
$this->setCertainty(0);
|
||||
|
||||
|
@ -76,6 +76,13 @@ class BillName extends BasicConverter implements ConverterInterface
|
||||
|
||||
]
|
||||
);
|
||||
if (is_null($bill->id)) {
|
||||
$this->setCertainty(0);
|
||||
Log::info('Could not store new bill by name', $bill->getErrors()->toArray());
|
||||
|
||||
return new Bill;
|
||||
}
|
||||
|
||||
$this->setCertainty(100);
|
||||
|
||||
return $bill;
|
||||
|
@ -63,6 +63,9 @@ class BudgetId extends BasicConverter implements ConverterInterface
|
||||
|
||||
// should not really happen. If the ID does not match FF, what is FF supposed to do?
|
||||
$this->setCertainty(0);
|
||||
|
||||
Log::info(sprintf('Could not find budget with ID %d. Will return NULL', $value));
|
||||
|
||||
return new Budget;
|
||||
|
||||
}
|
||||
|
@ -62,6 +62,9 @@ class CategoryId extends BasicConverter implements ConverterInterface
|
||||
|
||||
// should not really happen. If the ID does not match FF, what is FF supposed to do?
|
||||
$this->setCertainty(0);
|
||||
|
||||
Log::info(sprintf('Could not find category with ID %d. Will return NULL', $value));
|
||||
|
||||
return new Category;
|
||||
|
||||
}
|
||||
|
@ -61,6 +61,9 @@ class CurrencyId extends BasicConverter implements ConverterInterface
|
||||
}
|
||||
$this->setCertainty(0);
|
||||
// should not really happen. If the ID does not match FF, what is FF supposed to do?
|
||||
|
||||
Log::info(sprintf('Could not find category with ID %d. Will return NULL', $value));
|
||||
|
||||
return new TransactionCurrency;
|
||||
|
||||
}
|
||||
|
@ -37,9 +37,10 @@ class Date extends BasicConverter implements ConverterInterface
|
||||
try {
|
||||
$date = Carbon::createFromFormat($this->config['date-format'], $value);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
Log::critical($e->getMessage());
|
||||
Log::critical('Cannot convert this string using the given format.', ['value' => $value, 'format' => $this->config['date-format']]);
|
||||
throw new FireflyException(sprintf('Cannot convert "%s" to a valid date using format "%s".', $value, $this->config['date-format']));
|
||||
Log::notice($e->getMessage());
|
||||
Log::notice('Cannot convert this string using the given format.', ['value' => $value, 'format' => $this->config['date-format']]);
|
||||
$this->setCertainty(0);
|
||||
return new Carbon;
|
||||
}
|
||||
Log::debug('Converted date', ['converted' => $date->toAtomString()]);
|
||||
$this->setCertainty(100);
|
||||
|
@ -56,7 +56,7 @@ class OpposingAccountIban extends BasicConverter implements ConverterInterface
|
||||
$account = $repository->findByIban($value, []);
|
||||
if (!is_null($account->id)) {
|
||||
Log::debug('Found account by IBAN', ['id' => $account->id]);
|
||||
Log::warning(
|
||||
Log::notice(
|
||||
'The match between IBAN and account is uncertain because the type of transactions may not have been determined.',
|
||||
['id' => $account->id, 'iban' => $value]
|
||||
);
|
||||
|
@ -47,6 +47,7 @@ class OpposingAccountName extends BasicConverter implements ConverterInterface
|
||||
if (!is_null($account->id)) {
|
||||
Log::debug('Found account by ID', ['id' => $account->id]);
|
||||
$this->setCertainty(100);
|
||||
|
||||
return $account;
|
||||
}
|
||||
}
|
||||
@ -55,11 +56,12 @@ class OpposingAccountName extends BasicConverter implements ConverterInterface
|
||||
$account = $repository->findByName($value, []);
|
||||
if (!is_null($account->id)) {
|
||||
Log::debug('Found opposing account by name', ['id' => $account->id]);
|
||||
Log::warning(
|
||||
Log::info(
|
||||
'The match between name and account is uncertain because the type of transactions may not have been determined.',
|
||||
['id' => $account->id, 'name' => $value]
|
||||
);
|
||||
$this->setCertainty(50);
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
@ -68,6 +70,11 @@ class OpposingAccountName extends BasicConverter implements ConverterInterface
|
||||
'openingBalance' => 0,
|
||||
]
|
||||
);
|
||||
if (is_null($account->id)) {
|
||||
$this->setCertainty(0);
|
||||
|
||||
return new Account;
|
||||
}
|
||||
$this->setCertainty(100);
|
||||
|
||||
Log::debug('Created new opposing account ', ['name' => $account->name, 'id' => $account->id]);
|
||||
|
@ -221,7 +221,7 @@ class ImportEntry
|
||||
|
||||
return;
|
||||
}
|
||||
Log::error(sprintf('Will not set %s based on certainty %d (current certainty is %d) or NULL id.', $field, $certainty, $this->certain[$field]));
|
||||
Log::info(sprintf('Will not set %s based on certainty %d (current certainty is %d) or NULL id.', $field, $certainty, $this->certain[$field]));
|
||||
|
||||
}
|
||||
|
||||
@ -239,7 +239,7 @@ class ImportEntry
|
||||
|
||||
return;
|
||||
}
|
||||
Log::error(sprintf('Will not set %s based on certainty %d (current certainty is %d).', $field, $certainty, $this->certain[$field]));
|
||||
Log::info(sprintf('Will not set %s based on certainty %d (current certainty is %d).', $field, $certainty, $this->certain[$field]));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -256,7 +256,7 @@ class ImportEntry
|
||||
|
||||
return;
|
||||
}
|
||||
Log::error(sprintf('Will not set %s based on certainty %d (current certainty is %d) or NULL id.', $field, $certainty, $this->certain[$field]));
|
||||
Log::info(sprintf('Will not set %s based on certainty %d (current certainty is %d) or NULL id.', $field, $certainty, $this->certain[$field]));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -57,9 +57,9 @@ class ImportStorage
|
||||
*/
|
||||
public function store()
|
||||
{
|
||||
foreach ($this->entries as $entry) {
|
||||
Log::debug('--- import store start ---');
|
||||
$this->storeSingle($entry);
|
||||
foreach ($this->entries as $index => $entry) {
|
||||
Log::debug(sprintf('--- import store start for row %d ---', $index));
|
||||
$this->storeSingle($index, $entry);
|
||||
}
|
||||
|
||||
}
|
||||
@ -80,19 +80,20 @@ class ImportStorage
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $index
|
||||
* @param ImportEntry $entry
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
private function storeSingle(ImportEntry $entry)
|
||||
private function storeSingle(int $index, ImportEntry $entry)
|
||||
{
|
||||
if ($entry->valid === false) {
|
||||
Log::error('Cannot import entry, because valid=false');
|
||||
Log::error(sprintf('Cannot import row %d, because valid=false', $index));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Log::debug('Going to store entry!');
|
||||
Log::debug(sprintf('Going to store row %d', $index));
|
||||
$billId = is_null($entry->fields['bill']) ? null : $entry->fields['bill']->id;
|
||||
$journalData = [
|
||||
'user_id' => $entry->user->id,
|
||||
@ -108,7 +109,12 @@ class ImportStorage
|
||||
];
|
||||
/** @var TransactionJournal $journal */
|
||||
$journal = TransactionJournal::create($journalData);
|
||||
$amount = $this->makePositive($entry->fields['amount']);
|
||||
|
||||
foreach ($journal->getErrors()->all() as $err) {
|
||||
Log::error($err);
|
||||
}
|
||||
|
||||
$amount = $this->makePositive($entry->fields['amount']);
|
||||
|
||||
Log::debug('Created journal', ['id' => $journal->id]);
|
||||
|
||||
@ -154,13 +160,30 @@ class ImportStorage
|
||||
|
||||
$one = Transaction::create($sourceData);
|
||||
$two = Transaction::create($destinationData);
|
||||
Log::debug('Created transaction 1', ['id' => $one->id, 'account' => $one->account_id,'account_name' => $source->name]);
|
||||
Log::debug('Created transaction 2', ['id' => $two->id, 'account' => $two->account_id,'account_name' => $destination->name]);
|
||||
Log::debug('Created transaction 1', ['id' => $one->id, 'account' => $one->account_id, 'account_name' => $source->name]);
|
||||
Log::debug('Created transaction 2', ['id' => $two->id, 'account' => $two->account_id, 'account_name' => $destination->name]);
|
||||
|
||||
$journal->completed = 1;
|
||||
$journal->save();
|
||||
|
||||
// now attach budget and so on.
|
||||
if (!is_null($entry->fields['budget']) && !is_null($entry->fields['budget']->id)) {
|
||||
$journal->budgets()->save($entry->fields['budget']);
|
||||
Log::debug('Attached budget', ['id' => $entry->fields['budget']->id, 'name' => $entry->fields['budget']->name]);
|
||||
$journal->save();
|
||||
}
|
||||
|
||||
if (!is_null($entry->fields['category']) && !is_null($entry->fields['category']->id)) {
|
||||
$journal->categories()->save($entry->fields['category']);
|
||||
Log::debug('Attached category', ['id' => $entry->fields['category']->id, 'name' => $entry->fields['category']->name]);
|
||||
$journal->save();
|
||||
}
|
||||
|
||||
if (!is_null($entry->fields['bill']) && !is_null($entry->fields['bill']->id)) {
|
||||
$journal->bill()->associate($entry->fields['bill']);
|
||||
Log::debug('Attached bill', ['id' => $entry->fields['bill']->id, 'name' => $entry->fields['bill']->name]);
|
||||
$journal->save();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -52,8 +52,8 @@ class ImportValidator
|
||||
{
|
||||
$newCollection = new Collection;
|
||||
/** @var ImportEntry $entry */
|
||||
foreach ($this->entries as $entry) {
|
||||
Log::debug('--- import validator start ---');
|
||||
foreach ($this->entries as $index => $entry) {
|
||||
Log::debug(sprintf('--- import validator start for row %d ---', $index));
|
||||
/*
|
||||
* X Adds the date (today) if no date is present.
|
||||
* X Determins the types of accounts involved (asset, expense, revenue).
|
||||
@ -64,14 +64,12 @@ class ImportValidator
|
||||
$entry = $this->checkAmount($entry);
|
||||
$entry = $this->setDate($entry);
|
||||
$entry = $this->setAssetAccount($entry);
|
||||
Log::debug(sprintf('Opposing account is of type %s', $entry->fields['opposing-account']->accountType->type));
|
||||
$entry = $this->setOpposingAccount($entry);
|
||||
Log::debug(sprintf('Opposing account is of type %s', $entry->fields['opposing-account']->accountType->type));
|
||||
$entry = $this->cleanDescription($entry);
|
||||
$entry = $this->setTransactionType($entry);
|
||||
$entry = $this->setTransactionCurrency($entry);
|
||||
|
||||
$newCollection->push($entry);
|
||||
$newCollection->put($index, $entry);
|
||||
}
|
||||
|
||||
return $newCollection;
|
||||
@ -118,6 +116,7 @@ class ImportValidator
|
||||
*/
|
||||
private function cleanDescription(ImportEntry $entry): ImportEntry
|
||||
{
|
||||
|
||||
if (!isset($entry->fields['description'])) {
|
||||
Log::debug('Set empty transaction description because field was not set.');
|
||||
$entry->fields['description'] = '(empty transaction description)';
|
||||
@ -130,6 +129,7 @@ class ImportValidator
|
||||
|
||||
return $entry;
|
||||
}
|
||||
$entry->fields['description'] = trim($entry->fields['description']);
|
||||
|
||||
if (strlen($entry->fields['description']) == 0) {
|
||||
Log::debug('Set empty transaction description because field was empty.');
|
||||
@ -137,8 +137,7 @@ class ImportValidator
|
||||
|
||||
return $entry;
|
||||
}
|
||||
Log::debug('Transaction description is OK.');
|
||||
$entry->fields['description'] = trim($entry->fields['description']);
|
||||
Log::debug('Transaction description is OK.', ['description' => $entry->fields['description']]);
|
||||
|
||||
return $entry;
|
||||
}
|
||||
@ -246,7 +245,7 @@ class ImportValidator
|
||||
*/
|
||||
private function setDate(ImportEntry $entry): ImportEntry
|
||||
{
|
||||
if (is_null($entry->fields['date-transaction'])) {
|
||||
if (is_null($entry->fields['date-transaction']) || $entry->certain['date-transaction'] == 0) {
|
||||
// empty date field? find alternative.
|
||||
$alternatives = ['date-book', 'date-interest', 'date-process'];
|
||||
foreach ($alternatives as $alternative) {
|
||||
@ -263,6 +262,9 @@ class ImportValidator
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
// confidence is zero?
|
||||
|
||||
Log::debug('Date-transaction is OK');
|
||||
|
||||
return $entry;
|
||||
|
@ -51,11 +51,10 @@ class CsvImporter implements ImporterInterface
|
||||
Log::debug('----- import entry build start --');
|
||||
Log::debug(sprintf('Now going to import row %d.', $index));
|
||||
$importEntry = $this->importSingleRow($index, $row);
|
||||
$collection->push($importEntry);
|
||||
$collection->put($index, $importEntry);
|
||||
}
|
||||
}
|
||||
Log::debug(sprintf('Collection contains %d entries', $collection->count()));
|
||||
Log::debug('This call should be intercepted somehow.');
|
||||
Log::debug(sprintf('Import collection contains %d entries', $collection->count()));
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ namespace FireflyIII\Import\Logging;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Monolog\Handler\AbstractProcessingHandler;
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* Class CommandHandler
|
||||
@ -32,7 +33,9 @@ class CommandHandler extends AbstractProcessingHandler
|
||||
*/
|
||||
public function __construct(Command $command)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->command = $command;
|
||||
$this->changeLevel(env('LOG_LEVEL', 'debug'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -44,6 +47,39 @@ class CommandHandler extends AbstractProcessingHandler
|
||||
*/
|
||||
protected function write(array $record)
|
||||
{
|
||||
$this->command->line((string) trim($record['formatted']));
|
||||
$this->command->line((string)trim($record['formatted']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $level
|
||||
*/
|
||||
private function changeLevel(string $level)
|
||||
{
|
||||
switch ($level) {
|
||||
case 'debug':
|
||||
$this->setLevel(Logger::DEBUG);
|
||||
break;
|
||||
case 'info':
|
||||
$this->setLevel(Logger::INFO);
|
||||
break;
|
||||
case 'notice':
|
||||
$this->setLevel(Logger::NOTICE);
|
||||
break;
|
||||
case 'warning':
|
||||
$this->setLevel(Logger::WARNING);
|
||||
break;
|
||||
case 'error':
|
||||
$this->setLevel(Logger::ERROR);
|
||||
break;
|
||||
case 'critical':
|
||||
$this->setLevel(Logger::CRITICAL);
|
||||
break;
|
||||
case 'alert':
|
||||
$this->setLevel(Logger::ALERT);
|
||||
break;
|
||||
case 'emergency':
|
||||
$this->setLevel(Logger::EMERGENCY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -79,8 +79,9 @@ class Account extends Model
|
||||
= [
|
||||
'user_id' => 'required|exists:users,id',
|
||||
'account_type_id' => 'required|exists:account_types,id',
|
||||
'name' => 'required',
|
||||
'name' => 'required|between:1,200',
|
||||
'active' => 'required|boolean',
|
||||
'iban' => 'between:1,50|iban',
|
||||
];
|
||||
/** @var bool */
|
||||
private $joinedAccountTypes;
|
||||
|
@ -17,6 +17,7 @@ use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
/**
|
||||
* FireflyIII\Models\Bill
|
||||
@ -58,17 +59,20 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereNameEncrypted($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereMatchEncrypted($value)
|
||||
* @mixin \Eloquent
|
||||
* @property string $deleted_at
|
||||
* @property string $deleted_at
|
||||
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Bill whereDeletedAt($value)
|
||||
*/
|
||||
class Bill extends Model
|
||||
{
|
||||
|
||||
use ValidatingTrait;
|
||||
|
||||
protected $dates = ['created_at', 'updated_at', 'date'];
|
||||
protected $fillable
|
||||
= ['name', 'match', 'amount_min', 'match_encrypted', 'name_encrypted', 'user_id', 'amount_max', 'date', 'repeat_freq', 'skip',
|
||||
'automatch', 'active',];
|
||||
protected $hidden = ['amount_min_encrypted', 'amount_max_encrypted', 'name_encrypted', 'match_encrypted'];
|
||||
protected $rules = ['name' => 'required|between:1,200',];
|
||||
|
||||
/**
|
||||
* @param Bill $value
|
||||
|
@ -17,6 +17,7 @@ use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
/**
|
||||
* FireflyIII\Models\Budget
|
||||
@ -51,11 +52,12 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
class Budget extends Model
|
||||
{
|
||||
|
||||
use SoftDeletes;
|
||||
use SoftDeletes, ValidatingTrait;
|
||||
|
||||
protected $dates = ['created_at', 'updated_at', 'deleted_at', 'startdate', 'enddate'];
|
||||
protected $fillable = ['user_id', 'name', 'active'];
|
||||
protected $hidden = ['encrypted'];
|
||||
protected $rules = ['name' => 'required|between:1,200',];
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
|
@ -17,6 +17,7 @@ use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
/**
|
||||
* FireflyIII\Models\Category
|
||||
@ -46,11 +47,12 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
*/
|
||||
class Category extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
use SoftDeletes, ValidatingTrait;
|
||||
|
||||
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
|
||||
protected $fillable = ['user_id', 'name'];
|
||||
protected $hidden = ['encrypted'];
|
||||
protected $rules = ['name' => 'required|between:1,200',];
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
|
@ -15,6 +15,7 @@ use Auth;
|
||||
use Crypt;
|
||||
use FireflyIII\Support\Models\TagSupport;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
/**
|
||||
* FireflyIII\Models\Tag
|
||||
@ -52,6 +53,9 @@ class Tag extends TagSupport
|
||||
{
|
||||
protected $dates = ['created_at', 'updated_at', 'date'];
|
||||
protected $fillable = ['user_id', 'tag', 'date', 'description', 'longitude', 'latitude', 'zoomLevel', 'tagMode'];
|
||||
protected $rules = ['tag' => 'required|between:1,200',];
|
||||
|
||||
use ValidatingTrait;
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
|
@ -15,6 +15,7 @@ use Auth;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Watson\Validating\ValidatingTrait;
|
||||
|
||||
/**
|
||||
* FireflyIII\Models\TransactionCurrency
|
||||
@ -38,19 +39,12 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
*/
|
||||
class TransactionCurrency extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
use SoftDeletes, ValidatingTrait;
|
||||
|
||||
|
||||
protected $fillable = ['name', 'code', 'symbol'];
|
||||
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function transactionJournals()
|
||||
{
|
||||
return $this->hasMany('FireflyIII\Models\TransactionJournal');
|
||||
}
|
||||
protected $fillable = ['name', 'code', 'symbol'];
|
||||
protected $rules = ['name' => 'required|between:1,200', 'code' => 'required|between:3,3', 'symbol' => 'required|between:1,12'];
|
||||
|
||||
/**
|
||||
* @param TransactionCurrency $currency
|
||||
@ -64,4 +58,12 @@ class TransactionCurrency extends Model
|
||||
}
|
||||
throw new NotFoundHttpException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function transactionJournals()
|
||||
{
|
||||
return $this->hasMany('FireflyIII\Models\TransactionJournal');
|
||||
}
|
||||
}
|
||||
|
@ -444,6 +444,12 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
*/
|
||||
public function store(array $data): Category
|
||||
{
|
||||
// TODO use validation, not this.
|
||||
if (strlen($data['name']) > 200 || strlen($data['name']) === 0) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
$newCategory = Category::firstOrCreateEncrypted(
|
||||
[
|
||||
'user_id' => $data['user'],
|
||||
|
@ -72,9 +72,9 @@ class TestData
|
||||
'updated_at' => $this->time,
|
||||
'user_id' => $account['user_id'],
|
||||
'account_type_id' => $account['account_type_id'],
|
||||
'name' => Crypt::encrypt($account['name']),
|
||||
'name' => $account['name'],
|
||||
'active' => 1,
|
||||
'encrypted' => 1,
|
||||
'encrypted' => 0,
|
||||
'virtual_balance' => 0,
|
||||
'iban' => isset($account['iban']) ? Crypt::encrypt($account['iban']) : null,
|
||||
];
|
||||
@ -244,6 +244,25 @@ class TestData
|
||||
DB::table('categories')->insert($insert);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function createCurrencies()
|
||||
{
|
||||
$insert = [];
|
||||
foreach ($this->data['currencies'] as $job) {
|
||||
$insert[] = [
|
||||
'created_at' => $this->time,
|
||||
'updated_at' => $this->time,
|
||||
'deleted_at' => null,
|
||||
'code' => $job['code'],
|
||||
'name' => $job['name'],
|
||||
'symbol' => $job['symbol'],
|
||||
];
|
||||
}
|
||||
DB::table('transaction_currencies')->insert($insert);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -829,6 +848,7 @@ class TestData
|
||||
$this->createMultiDeposits();
|
||||
$this->createMultiTransfers();
|
||||
$this->createImportJobs();
|
||||
$this->createCurrencies();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,10 +38,15 @@ class TestDataSeeder extends Seeder
|
||||
if ($disk->exists($fileName)) {
|
||||
Log::debug('Now seeding ' . $fileName);
|
||||
$file = json_decode($disk->get($fileName), true);
|
||||
// run the file:
|
||||
TestData::run($file);
|
||||
|
||||
if (is_array($file)) {
|
||||
// run the file:
|
||||
TestData::run($file);
|
||||
return;
|
||||
}
|
||||
Log::error('No valid data found (' . $fileName . ') for environment ' . $env);
|
||||
return;
|
||||
|
||||
}
|
||||
Log::info('No seed file (' . $fileName . ') for environment ' . $env);
|
||||
}
|
||||
|
@ -11,20 +11,78 @@
|
||||
"role": 1
|
||||
}
|
||||
],
|
||||
"accounts": [],
|
||||
"account-meta": [],
|
||||
"bills": [],
|
||||
"budgets": [],
|
||||
"accounts": [
|
||||
{
|
||||
"user_id": 1,
|
||||
"account_type_id": 3,
|
||||
"name": "ExistingAssetAccount",
|
||||
"iban": "NL62EXFK3945306779"
|
||||
},
|
||||
{
|
||||
"user_id": 1,
|
||||
"account_type_id": 4,
|
||||
"name": "ExistingOpposingAccount",
|
||||
"iban": "NL79BGWN6303364632"
|
||||
}
|
||||
],
|
||||
"account-meta": [
|
||||
{
|
||||
"account_id": 1,
|
||||
"name": "accountNumber",
|
||||
"data": "\"3945306779\""
|
||||
},
|
||||
{
|
||||
"account_id": 2,
|
||||
"name": "accountNumber",
|
||||
"data": "\"6303364632\""
|
||||
}
|
||||
],
|
||||
"bills": [
|
||||
{
|
||||
"name": "ExistingBill",
|
||||
"match": "ExistingBill",
|
||||
"amount_min": 100,
|
||||
"amount_max": 200,
|
||||
"user_id": 1,
|
||||
"date": "2015-01-01",
|
||||
"active": 1,
|
||||
"automatch": 1,
|
||||
"repeat_freq": "monthly",
|
||||
"skip": 0
|
||||
}
|
||||
],
|
||||
"budgets": [
|
||||
{
|
||||
"name": "ExistingBudget",
|
||||
"user_id": 1
|
||||
}
|
||||
],
|
||||
"budget-limits": [],
|
||||
"monthly-limits": [],
|
||||
"categories": [],
|
||||
"categories": [
|
||||
{
|
||||
"name": "ExistingCategory",
|
||||
"user_id": 1
|
||||
}
|
||||
],
|
||||
"piggy-banks": [],
|
||||
"piggy-events": [],
|
||||
"rule-groups": [],
|
||||
"rules": [],
|
||||
"rule-triggers": [],
|
||||
"rule-actions": [],
|
||||
"tags": [],
|
||||
"tags": [
|
||||
{
|
||||
"user_id": 1,
|
||||
"tag": "ExistingTag",
|
||||
"tagMode": "nothing"
|
||||
},
|
||||
{
|
||||
"user_id": 1,
|
||||
"tag": "AnotherExistingTag",
|
||||
"tagMode": "nothing"
|
||||
}
|
||||
],
|
||||
"monthly-deposits": [],
|
||||
"monthly-transfers": [],
|
||||
"monthly-withdrawals": [],
|
||||
@ -43,18 +101,67 @@
|
||||
"date-format": "Ymd",
|
||||
"delimiter": ",",
|
||||
"import-account": 0,
|
||||
"specifics": [],
|
||||
"column-count": 7,
|
||||
"specifics": {
|
||||
"RabobankDescription": 1,
|
||||
"AbnAmroDescription": 1
|
||||
},
|
||||
"column-count": 30,
|
||||
"column-roles": [
|
||||
"account-name",
|
||||
"opposing-name",
|
||||
"amount",
|
||||
"date-transaction",
|
||||
"category-name",
|
||||
"account-id",
|
||||
"account-iban",
|
||||
"account-name",
|
||||
"opposing-number",
|
||||
"bill-id",
|
||||
"bill-name",
|
||||
"budget-id",
|
||||
"budget-name",
|
||||
"description"
|
||||
"category-id",
|
||||
"category-name",
|
||||
"currency-code",
|
||||
"currency-id",
|
||||
"currency-symbol",
|
||||
"currency-name",
|
||||
"date-transaction",
|
||||
"description",
|
||||
"_ignore",
|
||||
"ing-debet-credit",
|
||||
"opposing-iban",
|
||||
"opposing-id",
|
||||
"opposing-name",
|
||||
"opposing-number",
|
||||
"rabo-debet-credit",
|
||||
"tags-comma",
|
||||
"tags-space",
|
||||
"date-interest",
|
||||
"date-book",
|
||||
"date-process",
|
||||
"external-id"
|
||||
],
|
||||
"column-do-mapping": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
@ -64,9 +171,16 @@
|
||||
false
|
||||
],
|
||||
"column-roles-complete": false,
|
||||
"column-mapping-config": [],
|
||||
"column-mapping-config": {},
|
||||
"column-mapping-complete": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"currencies": [
|
||||
{
|
||||
"name": "ExistingCurrency",
|
||||
"symbol": "#",
|
||||
"code": "EXI"
|
||||
}
|
||||
]
|
||||
}
|
@ -1007,5 +1007,6 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"import-jobs": []
|
||||
"import-jobs": [],
|
||||
"currencies": []
|
||||
}
|
@ -298,5 +298,6 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"import-jobs": []
|
||||
"import-jobs": [],
|
||||
"currencies": []
|
||||
}
|
@ -1007,5 +1007,6 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"import-jobs": []
|
||||
"import-jobs": [],
|
||||
"currencies": []
|
||||
}
|
Loading…
Reference in New Issue
Block a user