. */ declare(strict_types=1); namespace FireflyIII\Import\Routine; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\ImportJob; use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; use FireflyIII\Support\Import\Routine\File\FileProcessorInterface; use Log; /** * Class FileRoutine */ class FileRoutine implements RoutineInterface { /** @var ImportJob */ private $importJob; /** @var ImportJobRepositoryInterface */ private $repository; /** * At the end of each run(), the import routine must set the job to the expected status. * * The final status of the routine must be "provider_finished". * * @return bool * @throws FireflyException */ public function run(): void { Log::debug(sprintf('Now in run() for file routine with status: %s', $this->importJob->status)); if ($this->importJob->status !== 'running') { throw new FireflyException('This file import job should not be started.'); // @codeCoverageIgnore } switch ($this->importJob->stage) { case 'ready_to_run': // get processor, depending on file type // is just CSV for now. $processor = $this->getProcessor(); $processor->setJob($this->importJob); $transactions = $processor->run(); $this->repository->setStatus($this->importJob, 'provider_finished'); $this->repository->setStage($this->importJob, 'final'); $this->repository->setTransactions($this->importJob, $transactions); break; default: throw new FireflyException(sprintf('Import routine cannot handle stage "%s"', $this->importJob->stage)); } } /** * @param ImportJob $job * * @return void */ public function setJob(ImportJob $job): void { $this->importJob = $job; $this->repository = app(ImportJobRepositoryInterface::class); $this->repository->setUser($job->user); } /** * Return the appropriate file routine handler for * the file type of the job. * * @return FileProcessorInterface */ private function getProcessor(): FileProcessorInterface { $config = $this->repository->getConfiguration($this->importJob); $type = $config['file-type'] ?? 'csv'; $class = config(sprintf('import.options.file.processors.%s', $type)); /** @var FileProcessorInterface $object */ $object = app($class); return $object; } // /** @var Collection */ // public $errors; // /** @var Collection */ // public $journals; // /** @var int */ // public $lines = 0; // /** @var ImportJob */ // private $job; // // /** @var ImportJobRepositoryInterface */ // private $repository; // // /** // * ImportRoutine constructor. // */ // public function __construct() // { // $this->journals = new Collection; // $this->errors = new Collection; // } // // /** // * @return Collection // */ // public function getErrors(): Collection // { // return $this->errors; // } // // /** // * @return Collection // */ // public function getJournals(): Collection // { // return $this->journals; // } // // /** // * @return int // */ // public function getLines(): int // { // return $this->lines; // } // // /** // * // */ // public function run(): bool // { // if ('configured' !== $this->getStatus()) { // Log::error(sprintf('Job %s is in state "%s" so it cannot be started.', $this->job->key, $this->getStatus())); // // return false; // } // set_time_limit(0); // Log::info(sprintf('Start with import job %s', $this->job->key)); // // // total steps: 6 // $this->setTotalSteps(6); // // $importObjects = $this->getImportObjects(); // $this->lines = $importObjects->count(); // $this->addStep(); // // // total steps can now be extended. File has been scanned. 7 steps per line: // $this->addTotalSteps(7 * $this->lines); // // // once done, use storage thing to actually store them: // Log::info(sprintf('Returned %d valid objects from file processor', $this->lines)); // // $storage = $this->storeObjects($importObjects); // $this->addStep(); // Log::debug('Back in run()'); // // Log::debug('Updated job...'); // Log::debug(sprintf('%d journals in $storage->journals', $storage->journals->count())); // $this->journals = $storage->journals; // $this->errors = $storage->errors; // // Log::debug('Going to call createImportTag()'); // // // create tag, link tag to all journals: // $this->createImportTag(); // $this->addStep(); // // // update job: // $this->setStatus('finished'); // // Log::info(sprintf('Done with import job %s', $this->job->key)); // // return true; // } // // /** // * @param ImportJob $job // */ // public function setJob(ImportJob $job) // { // $this->job = $job; // $this->repository = app(ImportJobRepositoryInterface::class); // $this->repository->setUser($job->user); // } // // /** // * @return Collection // */ // protected function getImportObjects(): Collection // { // $objects = new Collection; // $fileType = $this->getConfig()['file-type'] ?? 'csv'; // // will only respond to "file" // $class = config(sprintf('import.options.file.processors.%s', $fileType)); // /** @var FileProcessorInterface $processor */ // $processor = app($class); // $processor->setJob($this->job); // // if ('configured' === $this->getStatus()) { // // set job as "running"... // $this->setStatus('running'); // // Log::debug('Job is configured, start with run()'); // $processor->run(); // $objects = $processor->getObjects(); // } // // return $objects; // } // // /** // * Shorthand method. // */ // private function addStep() // { // $this->repository->addStepsDone($this->job, 1); // } // // /** // * Shorthand // * // * @param int $steps // */ // private function addTotalSteps(int $steps) // { // $this->repository->addTotalSteps($this->job, $steps); // } // // /** // * // */ // private function createImportTag(): Tag // { // Log::debug('Now in createImportTag()'); // // if ($this->journals->count() < 1) { // Log::info(sprintf('Will not create tag, %d journals imported.', $this->journals->count())); // // return new Tag; // } // $this->addTotalSteps($this->journals->count() + 2); // // /** @var TagRepositoryInterface $repository */ // $repository = app(TagRepositoryInterface::class); // $repository->setUser($this->job->user); // $data = [ // 'tag' => trans('import.import_with_key', ['key' => $this->job->key]), // 'date' => new Carbon, // 'description' => null, // 'latitude' => null, // 'longitude' => null, // 'zoomLevel' => null, // 'tagMode' => 'nothing', // ]; // $tag = $repository->store($data); // $this->addStep(); // $extended = $this->getExtendedStatus(); // $extended['tag'] = $tag->id; // $this->setExtendedStatus($extended); // // Log::debug(sprintf('Created tag #%d ("%s")', $tag->id, $tag->tag)); // Log::debug('Looping journals...'); // $journalIds = $this->journals->pluck('id')->toArray(); // $tagId = $tag->id; // foreach ($journalIds as $journalId) { // Log::debug(sprintf('Linking journal #%d to tag #%d...', $journalId, $tagId)); // DB::table('tag_transaction_journal')->insert(['transaction_journal_id' => $journalId, 'tag_id' => $tagId]); // $this->addStep(); // } // Log::info(sprintf('Linked %d journals to tag #%d ("%s")', $this->journals->count(), $tag->id, $tag->tag)); // $this->addStep(); // // return $tag; // } // // /** // * Shorthand method // * // * @return array // */ // private function getConfig(): array // { // return $this->repository->getConfiguration($this->job); // } // // /** // * @return array // */ // private function getExtendedStatus(): array // { // return $this->repository->getExtendedStatus($this->job); // } // // /** // * Shorthand method. // * // * @return string // */ // private function getStatus(): string // { // return $this->repository->getStatus($this->job); // } // // /** // * @param array $extended // */ // private function setExtendedStatus(array $extended): void // { // $this->repository->setExtendedStatus($this->job, $extended); // } // // /** // * Shorthand // * // * @param string $status // */ // private function setStatus(string $status): void // { // $this->repository->setStatus($this->job, $status); // } // // /** // * Shorthand // * // * @param int $steps // */ // private function setTotalSteps(int $steps) // { // $this->repository->setTotalSteps($this->job, $steps); // } // // /** // * @param Collection $objects // * // * @return ImportStorage // */ // private function storeObjects(Collection $objects): ImportStorage // { // $config = $this->getConfig(); // $storage = new ImportStorage; // $storage->setJob($this->job); // $storage->setDateFormat($config['date-format']); // $storage->setObjects($objects); // $storage->store(); // Log::info('Back in storeObjects()'); // // return $storage; // } }