diff --git a/app/Import/Storage/ImportStorage.php b/app/Import/Storage/ImportStorage.php index 47ba783826..76e409f673 100644 --- a/app/Import/Storage/ImportStorage.php +++ b/app/Import/Storage/ImportStorage.php @@ -29,6 +29,7 @@ use FireflyIII\Import\Object\ImportJournal; use FireflyIII\Models\ImportJob; use FireflyIII\Models\Note; use FireflyIII\Models\TransactionType; +use FireflyIII\Repositories\Bill\BillRepositoryInterface; use Illuminate\Support\Collection; use Log; @@ -44,14 +45,22 @@ class ImportStorage public $errors; /** @var Collection */ public $journals; - /** @var int */ - protected $defaultCurrencyId = 1; // yes, hard coded + /** @var BillRepositoryInterface */ + protected $billRepository; // yes, hard coded + /** @var Collection */ + protected $bills; +/** @var int */ + protected $defaultCurrencyId = 1; /** @var ImportJob */ protected $job; /** @var Collection */ protected $rules; + /** @var bool */ + private $applyRules = false; /** @var string */ private $dateFormat = 'Ymd'; + /** @var bool */ + private $matchBills = false; /** @var Collection */ private $objects; /** @var array */ @@ -84,7 +93,21 @@ class ImportStorage $currency = app('amount')->getDefaultCurrencyByUser($this->job->user); $this->defaultCurrencyId = $currency->id; $this->transfers = $this->getTransfers(); - $this->rules = $this->getRules(); + $config = $job->configuration; + $this->applyRules = $config['apply_rules'] ?? false; + $this->matchBills = $config['match_bills'] ?? false; + if ($this->applyRules === true) { + Log::debug('applyRules seems to be true, get the rules.'); + $this->rules = $this->getRules(); + } + if ($this->matchBills === true) { + Log::debug('matchBills seems to be true, get the bills'); + $this->bills = $this->getBills(); + $this->billRepository = app(BillRepositoryInterface::class); + $this->billRepository->setUser($job->user); + } + Log::debug(sprintf('Value of apply rules is %s', var_export($this->applyRules, true))); + Log::debug(sprintf('Value of match bills is %s', var_export($this->matchBills, true))); } /** @@ -202,8 +225,26 @@ class ImportStorage // Another step done! $this->job->addStepsDone(1); - // run rules: - $this->applyRules($journal); + // run rules if config calls for it: + if ($this->applyRules === true) { + Log::info('Will apply rules to this journal.'); + $this->applyRules($journal); + } + if (!($this->applyRules === true)) { + Log::info('Will NOT apply rules to this journal.'); + } + + // match bills if config calls for it. + if ($this->matchBills === true) { + //$this->/applyRules($journal); + Log::info('Cannot match bills (yet).'); + $this->matchBills($journal); + } + + if (!($this->matchBills === true)) { + Log::info('Cannot match bills (yet), but do not have to.'); + } + // Another step done! $this->job->addStepsDone(1); $this->journals->push($journal); diff --git a/app/Import/Storage/ImportSupport.php b/app/Import/Storage/ImportSupport.php index 248fd2074f..d5640aa98c 100644 --- a/app/Import/Storage/ImportSupport.php +++ b/app/Import/Storage/ImportSupport.php @@ -38,6 +38,7 @@ use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournalMeta; use FireflyIII\Models\TransactionType; +use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Tag\TagRepositoryInterface; use FireflyIII\TransactionRules\Processor; use Illuminate\Database\Query\JoinClause; @@ -49,6 +50,10 @@ use Log; */ trait ImportSupport { + /** @var BillRepositoryInterface */ + protected $billRepository; + /** @var Collection */ + protected $bills; /** @var int */ protected $defaultCurrencyId = 1; /** @var ImportJob */ @@ -81,6 +86,29 @@ trait ImportSupport return true; } + /** + * @param TransactionJournal $journal + * + * @return bool + */ + protected function matchBills(TransactionJournal $journal): bool + { + if(!is_null($journal->bill_id)) { + Log::debug('Journal is already linked to a bill, will not scan.'); + return true; + } + if ($this->bills->count() > 0) { + $this->bills->each( + function (Bill $bill) use ($journal) { + Log::debug(sprintf('Going to match bill #%d to journal %d.', $bill->id, $journal->id)); + $this->billRepository->scan($bill, $journal); + } + ); + } + + return true; + } + /** * @param array $parameters * @@ -107,6 +135,17 @@ trait ImportSupport return true; } + /** + * @return Collection + */ + private function getBills(): Collection + { + $set = Bill::where('user_id', $this->job->user->id)->where('active', 1)->where('automatch', 1)->get(['bills.*']); + Log::debug(sprintf('Found %d user bills.', $set->count())); + + return $set; + } + /** * This method finds out what the import journal's currency should be. The account itself * is favoured (and usually it stops there). If no preference is found, the journal has a say @@ -224,7 +263,7 @@ trait ImportSupport * @param Account $account * * @return string - * + *x * @throws FireflyException * * @see ImportSupport::getOpposingAccount() diff --git a/app/Support/Import/Configuration/Csv/Initial.php b/app/Support/Import/Configuration/Csv/Initial.php index dff977be5c..88a3ca00e2 100644 --- a/app/Support/Import/Configuration/Csv/Initial.php +++ b/app/Support/Import/Configuration/Csv/Initial.php @@ -113,6 +113,8 @@ class Initial implements ConfigurationInterface $config['date-format'] = $data['date_format']; $config['delimiter'] = $data['csv_delimiter']; $config['delimiter'] = 'tab' === $config['delimiter'] ? "\t" : $config['delimiter']; + $config['apply_rules'] = isset($data['apply_rules']) && 1 === intval($data['apply_rules']) ? true : false; + $config['match_bills'] = isset($data['match_bills']) && 1 === intval($data['match_bills']) ? true : false; Log::debug('Entered import account.', ['id' => $importId]); diff --git a/resources/lang/en_US/csv.php b/resources/lang/en_US/csv.php index 094df1e9a2..4586dd6ac5 100644 --- a/resources/lang/en_US/csv.php +++ b/resources/lang/en_US/csv.php @@ -24,6 +24,12 @@ return [ 'initial_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.', 'initial_submit' => 'Continue with step 2/3', + // new options: + 'apply_rules_title' => 'Apply rules', + 'apply_rules_description' => 'Apply your rules. Note that this slows the import significantly.', + 'match_bills_title' => 'Match bills', + 'match_bills_description' => 'Match your bills to newly created withdrawals. Note that this slows the import significantly.', + // roles config 'roles_title' => 'Import setup (2/3) - Define each column\'s role', 'roles_text' => 'Each column in your CSV file contains certain data. Please indicate what kind of data the importer should expect. The option to "map" data means that you will link each entry found in the column to a value in your database. An often mapped column is the column that contains the IBAN of the opposing account. That can be easily matched to IBAN\'s present in your database already.', diff --git a/resources/views/import/csv/initial.twig b/resources/views/import/csv/initial.twig index 56a11fc08e..dce077adea 100644 --- a/resources/views/import/csv/initial.twig +++ b/resources/views/import/csv/initial.twig @@ -34,12 +34,42 @@