mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 02:36:28 +00:00 
			
		
		
		
	First attempt, trying to build an import stuff routine.
This commit is contained in:
		| @@ -38,6 +38,10 @@ class HomeController extends BaseController | ||||
|      */ | ||||
|     public function index() | ||||
|     { | ||||
|         Queue::push(function($job) | ||||
|         { | ||||
|             Log::debug('This is a job!'); | ||||
|         }); | ||||
|  | ||||
|         \Event::fire('limits.check'); | ||||
|         \Event::fire('piggybanks.check'); | ||||
|   | ||||
							
								
								
									
										44
									
								
								app/controllers/MigrateController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/controllers/MigrateController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Class MigrateController | ||||
|  */ | ||||
| class MigrateController extends BaseController | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function index() | ||||
|     { | ||||
|         return View::make('migrate.index')->with('index', 'Migration'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function upload() | ||||
|     { | ||||
|         if (Input::hasFile('file') && Input::file('file')->isValid()) { | ||||
|             // move file to storage: | ||||
|             // ->move($destinationPath, $fileName); | ||||
|             $path     = storage_path(); | ||||
|             $fileName = 'firefly-iii-import-' . date('Y-m-d-H-i') . '.json'; | ||||
|             $fullName = $path . DIRECTORY_SEPARATOR . $fileName; | ||||
|             if (is_writable($path)) { | ||||
|                 Input::file('file')->move($path, $fileName); | ||||
|                 // so now we push something in a queue and do something with it! Yay! | ||||
|                 Queue::push('Firefly\Queue\Import@start', ['file' => $fullName,'user' => \Auth::user()->id]); | ||||
|                 exit; | ||||
|             } | ||||
|             Session::flash('error', 'Could not save file to storage.'); | ||||
|             return Redirect::route('migrate.index'); | ||||
|  | ||||
|         } else { | ||||
|             Session::flash('error', 'Please upload a file.'); | ||||
|             return Redirect::route('migrate.index'); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
| }  | ||||
| @@ -0,0 +1,39 @@ | ||||
| <?php | ||||
|  | ||||
| use Illuminate\Database\Schema\Blueprint; | ||||
| use Illuminate\Database\Migrations\Migration; | ||||
|  | ||||
| class CreateImportmapsTable extends Migration { | ||||
|  | ||||
| 	/** | ||||
| 	 * Run the migrations. | ||||
| 	 * | ||||
| 	 * @return void | ||||
| 	 */ | ||||
| 	public function up() | ||||
| 	{ | ||||
| 		Schema::create('importmaps', function(Blueprint $table) | ||||
| 		{ | ||||
| 			$table->increments('id'); | ||||
| 			$table->timestamps(); | ||||
|             $table->integer('user_id')->unsigned(); | ||||
|             $table->string('file',500); | ||||
|  | ||||
|             // connect maps to users | ||||
|             $table->foreign('user_id') | ||||
|                   ->references('id')->on('users') | ||||
|                   ->onDelete('cascade'); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Reverse the migrations. | ||||
| 	 * | ||||
| 	 * @return void | ||||
| 	 */ | ||||
| 	public function down() | ||||
| 	{ | ||||
| 		Schema::drop('importmaps'); | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,42 @@ | ||||
| <?php | ||||
|  | ||||
| use Illuminate\Database\Schema\Blueprint; | ||||
| use Illuminate\Database\Migrations\Migration; | ||||
|  | ||||
| class CreateImportentriesTable extends Migration { | ||||
|  | ||||
| 	/** | ||||
| 	 * Run the migrations. | ||||
| 	 * | ||||
| 	 * @return void | ||||
| 	 */ | ||||
| 	public function up() | ||||
| 	{ | ||||
| 		Schema::create('importentries', function(Blueprint $table) | ||||
| 		{ | ||||
| 			$table->increments('id'); | ||||
| 			$table->timestamps(); | ||||
|             $table->string('class',200); | ||||
|             $table->integer('importmap_id')->unsigned(); | ||||
|             $table->integer('old')->unsigned(); | ||||
|             $table->integer('new')->unsigned(); | ||||
|  | ||||
|             // map import entries to import map. | ||||
|             // connect accounts to account_types | ||||
|             $table->foreign('importmap_id') | ||||
|                   ->references('id')->on('importmaps') | ||||
|                   ->onDelete('cascade'); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Reverse the migrations. | ||||
| 	 * | ||||
| 	 * @return void | ||||
| 	 */ | ||||
| 	public function down() | ||||
| 	{ | ||||
| 		Schema::drop('importentries'); | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -11,16 +11,20 @@ class AccountTypeSeeder extends Seeder | ||||
|         DB::table('account_types')->delete(); | ||||
|  | ||||
|         AccountType::create( | ||||
|             ['type' => 'Default account','editable' => true] | ||||
|                    ['type' => 'Default account', 'editable' => true] | ||||
|         ); | ||||
|         AccountType::create( | ||||
|             ['type' => 'Cash account','editable' => false] | ||||
|                    ['type' => 'Cash account', 'editable' => false] | ||||
|         ); | ||||
|         AccountType::create( | ||||
|             ['type' => 'Initial balance account','editable' => false] | ||||
|                    ['type' => 'Initial balance account', 'editable' => false] | ||||
|         ); | ||||
|         AccountType::create( | ||||
|             ['type' => 'Beneficiary account','editable' => true] | ||||
|                    ['type' => 'Beneficiary account', 'editable' => true] | ||||
|         ); | ||||
|  | ||||
|         AccountType::create( | ||||
|                    ['type' => 'Import account', 'editable' => false] | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|   | ||||
							
								
								
									
										623
									
								
								app/lib/Firefly/Queue/Import.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										623
									
								
								app/lib/Firefly/Queue/Import.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,623 @@ | ||||
| <?php | ||||
|  | ||||
| namespace Firefly\Queue; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use Firefly\Exception\FireflyException; | ||||
| use Illuminate\Queue\Jobs\SyncJob; | ||||
|  | ||||
| /** | ||||
|  * Class Import | ||||
|  * @package Firefly\Queue | ||||
|  */ | ||||
| class Import | ||||
| { | ||||
|     /** @var \Firefly\Storage\Account\AccountRepositoryInterface */ | ||||
|     protected $_accounts; | ||||
|  | ||||
|     /** @var \Firefly\Storage\Import\ImportRepositoryInterface */ | ||||
|     protected $_repository; | ||||
|  | ||||
|     /** @var \Firefly\Storage\Budget\BudgetRepositoryInterface */ | ||||
|     protected $_budgets; | ||||
|  | ||||
|     /** @var \Firefly\Storage\Category\CategoryRepositoryInterface */ | ||||
|     protected $_categories; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this->_accounts   = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|         $this->_repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); | ||||
|         $this->_budgets    = \App::make('Firefly\Storage\Budget\BudgetRepositoryInterface'); | ||||
|         $this->_categories = \App::make('Firefly\Storage\Category\CategoryRepositoryInterface'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Import a personal account or beneficiary as a new account. | ||||
|      * | ||||
|      * @param SyncJob $job | ||||
|      * @param array $payload | ||||
|      */ | ||||
|     public function importAccount(SyncJob $job, array $payload) | ||||
|     { | ||||
|  | ||||
|         /** @var \Importmap $importMap */ | ||||
|         $importMap = $this->_repository->findImportmap($payload['mapID']); | ||||
|  | ||||
|         // maybe we've already imported this account: | ||||
|         $importEntry = $this->_repository->findImportEntry($importMap, 'Account', intval($payload['data']['id'])); | ||||
|  | ||||
|         // if so, delete job and return: | ||||
|         if (!is_null($importEntry)) { | ||||
|             $job->delete(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // if we try to import a beneficiary, Firefly will "merge" already, | ||||
|         // so we don't care: | ||||
|         if (isset($payload['data']['account_type']) && $payload['data']['account_type'] == 'Beneficiary account') { | ||||
|             // store beneficiary | ||||
|             $acct = $this->_accounts->createOrFindBeneficiary($payload['data']['name']); | ||||
|             \Log::debug('Imported ' . $payload['class'] . ' "' . $payload['data']['name'] . '".'); | ||||
|             $this->_repository->store($importMap, 'Account', $payload['data']['id'], $acct->id); | ||||
|             $job->delete(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // but we cannot merge accounts, so we need to search first: | ||||
|         $acct = $this->_accounts->findByName($payload['data']['name']); | ||||
|         if (is_null($acct)) { | ||||
|             // store new one! | ||||
|             $acct = $this->_accounts->store((array)$payload['data']); | ||||
|             \Log::debug('Imported ' . $payload['class'] . ' "' . $payload['data']['name'] . '".'); | ||||
|             $this->_repository->store($importMap, 'Account', $payload['data']['id'], $acct->id); | ||||
|         } else { | ||||
|             // use previous one! | ||||
|             \Log::debug('Already imported ' . $payload['class'] . ' "' . $payload['data']['name'] . '".'); | ||||
|             $this->_repository->store($importMap, 'Account', $payload['data']['id'], $acct->id); | ||||
|         } | ||||
|  | ||||
|         // and delete the job | ||||
|         $job->delete(); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Import a budget into Firefly. | ||||
|      * | ||||
|      * @param SyncJob $job | ||||
|      * @param array $payload | ||||
|      */ | ||||
|     public function importBudget(SyncJob $job, array $payload) | ||||
|     { | ||||
|         /** @var \Importmap $importMap */ | ||||
|         $importMap = $this->_repository->findImportmap($payload['mapID']); | ||||
|  | ||||
|         // maybe we've already imported this budget: | ||||
|         $bdg = $this->_budgets->findByName($payload['data']['name']); | ||||
|  | ||||
|         if (is_null($bdg)) { | ||||
|             // we have not! | ||||
|             $bdg = $this->_budgets->store((array)$payload['data']); | ||||
|             $this->_repository->store($importMap, 'Budget', $payload['data']['id'], $bdg->id); | ||||
|             \Log::debug('Imported budget "' . $payload['data']['name'] . '".'); | ||||
|         } else { | ||||
|             // we have! | ||||
|             $this->_repository->store($importMap, 'Budget', $payload['data']['id'], $bdg->id); | ||||
|             \Log::debug('Already had budget "' . $payload['data']['name'] . '".'); | ||||
|         } | ||||
|  | ||||
|         // delete job. | ||||
|         $job->delete(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Import a category into Firefly. | ||||
|      * | ||||
|      * @param SyncJob $job | ||||
|      * @param array $payload | ||||
|      */ | ||||
|     public function importCategory(SyncJob $job, array $payload) | ||||
|     { | ||||
|  | ||||
|         /** @var \Importmap $importMap */ | ||||
|         $importMap = $this->_repository->findImportmap($payload['mapID']); | ||||
|  | ||||
|         // try to find budget: | ||||
|         $current = $this->_categories->findByName($payload['data']['name']); | ||||
|         if (is_null($current)) { | ||||
|             $cat = $this->_categories->store((array)$payload['data']); | ||||
|             $this->_repository->store($importMap, 'Category', $payload['data']['id'], $cat->id); | ||||
|             \Log::debug('Imported category "' . $payload['data']['name'] . '".'); | ||||
|         } else { | ||||
|             $this->_repository->store($importMap, 'Category', $payload['data']['id'], $current->id); | ||||
|             \Log::debug('Already had category "' . $payload['data']['name'] . '".'); | ||||
|         } | ||||
|  | ||||
|         $job->delete(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param SyncJob $job | ||||
|      * @param array $payload | ||||
|      * @throws \Firefly\Exception\FireflyException | ||||
|      */ | ||||
|     public function importComponent(SyncJob $job, array $payload) | ||||
|     { | ||||
|  | ||||
|         \Log::debug('Going to import component "' . $payload['data']['name'] . '".'); | ||||
|         switch ($payload['data']['type']['type']) { | ||||
|             case 'beneficiary': | ||||
|                 $jobFunction                     = 'Firefly\Queue\Import@importAccount'; | ||||
|                 $payload['class']                = 'Account'; | ||||
|                 $payload['data']['account_type'] = 'Beneficiary account'; | ||||
|                 \Log::debug('It is a beneficiary.'); | ||||
|                 break; | ||||
|             case 'budget': | ||||
|                 $jobFunction = 'Firefly\Queue\Import@importBudget'; | ||||
|                 \Log::debug('It is a budget.'); | ||||
|                 break; | ||||
|             case 'category': | ||||
|                 $jobFunction = 'Firefly\Queue\Import@importCategory'; | ||||
|                 \Log::debug('It is a category.'); | ||||
|                 break; | ||||
|             case 'payer': | ||||
|                 // ignored! | ||||
|                 break; | ||||
|             default: | ||||
|                 throw new FireflyException('No import case for "' . $payload['data']['type']['type'] . '"!'); | ||||
|         } | ||||
|         if (isset($jobFunction)) { | ||||
|             \Queue::push($jobFunction, $payload); | ||||
|         } | ||||
|         $job->delete(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param SyncJob $job | ||||
|      * @param array $payload | ||||
|      */ | ||||
|     public function importComponentTransaction(SyncJob $job, array $payload) | ||||
|     { | ||||
|         if ($job->attempts() > 1) { | ||||
|             \Log::info('Job running for ' . $job->attempts() . 'th time!'); | ||||
|         } | ||||
|  | ||||
|         $oldComponentId   = intval($payload['data']['component_id']); | ||||
|         $oldTransactionId = intval($payload['data']['transaction_id']); | ||||
|  | ||||
|         /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ | ||||
|         $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); | ||||
|  | ||||
|  | ||||
|         /** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $journals */ | ||||
|         $journals = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); | ||||
|  | ||||
|         /** @var \Firefly\Storage\Category\CategoryRepositoryInterface $categories */ | ||||
|         $categories = \App::make('Firefly\Storage\Category\CategoryRepositoryInterface'); | ||||
|  | ||||
|         /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ | ||||
|         $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|  | ||||
|  | ||||
|         /** @var \Importmap $importMap */ | ||||
|         $importMap = $repository->findImportmap($payload['mapID']); | ||||
|  | ||||
|         $oldTransactionMap = $repository->findImportEntry($importMap, 'Transaction', $oldTransactionId); | ||||
|  | ||||
|         // we don't know what the component is, so we need to search for it in a set | ||||
|         // of possible types (Account / Beneficiary, Budget, Category) | ||||
|         /** @var \Importentry $oldComponentMap */ | ||||
|         $oldComponentMap = $repository->findImportComponentMap($importMap, $oldComponentId); | ||||
|  | ||||
|         if (is_null($oldComponentMap)) { | ||||
|             \Log::debug('Could not run this one, waiting for five seconds...'); | ||||
|             $job->release(5); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $journal = $journals->find($oldTransactionMap->new); | ||||
|         \Log::debug('Going to update ' . $journal->description); | ||||
|  | ||||
|         // find the cash account: | ||||
|  | ||||
|  | ||||
|         switch ($oldComponentMap->class) { | ||||
|             case 'Budget': | ||||
|                 // budget thing link: | ||||
|                 $budget = $this->_budgets->find($oldComponentMap->new); | ||||
|  | ||||
|                 \Log::debug('Updating transactions Budget.'); | ||||
|                 $journal->budgets()->save($budget); | ||||
|                 $journal->save(); | ||||
|                 \Log::debug('Updated transactions Budget.'); | ||||
|  | ||||
|                 break; | ||||
|             case 'Category': | ||||
|                 $category = $categories->find($oldComponentMap->new); | ||||
|                 $journal  = $journals->find($oldTransactionMap->new); | ||||
|                 \Log::info('Updating transactions Category.'); | ||||
|                 $journal->categories()->save($category); | ||||
|                 $journal->save(); | ||||
|                 \Log::info('Updated transactions Category.'); | ||||
|                 break; | ||||
|             case 'Account': | ||||
|                 \Log::info('Updating transactions Account.'); | ||||
|                 $account = $accounts->find($oldComponentMap->new); | ||||
|                 $journal = $journals->find($oldTransactionMap->new); | ||||
|                 if (is_null($account)) { | ||||
|                     \Log::debug('Cash account is needed.'); | ||||
|                     $account = $accounts->getCashAccount(); | ||||
|                     \Log::info($account); | ||||
|                 } | ||||
|  | ||||
|                 foreach ($journal->transactions as $transaction) { | ||||
|                     if ($transaction->account()->first()->account_type_id == 5) { | ||||
|                         $transaction->account()->associate($account); | ||||
|                         $transaction->save(); | ||||
|                         \Log::debug('Updated transactions (#' . $journal->id . '), #' . $transaction->id . '\'s Account.'); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param SyncJob $job | ||||
|      * @param array $payload | ||||
|      */ | ||||
|     public function importLimit(SyncJob $job, array $payload) | ||||
|     { | ||||
|  | ||||
|         /** @var \Firefly\Storage\Limit\LimitRepositoryInterface $limits */ | ||||
|         $limits = \App::make('Firefly\Storage\Limit\LimitRepositoryInterface'); | ||||
|  | ||||
|         /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ | ||||
|         $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); | ||||
|  | ||||
|         /** @var \Firefly\Storage\Budget\BudgetRepositoryInterface $budgets */ | ||||
|         $budgets = \App::make('Firefly\Storage\Budget\BudgetRepositoryInterface'); | ||||
|  | ||||
|         /** @var \Importmap $importMap */ | ||||
|         $importMap = $repository->findImportmap($payload['mapID']); | ||||
|  | ||||
|  | ||||
|         // find the budget this limit is part of: | ||||
|         $importEntry = $repository->findImportEntry($importMap, 'Budget', intval($payload['data']['component_id'])); | ||||
|  | ||||
|         // budget is not yet imported: | ||||
|         if (is_null($importEntry)) { | ||||
|             \Log::debug('Released job for work in five seconds...'); | ||||
|             $job->release(5); | ||||
|             return; | ||||
|         } | ||||
|         // find similar limit: | ||||
|         \Log::debug('Trying to find budget with ID #' . $importEntry->new . ', based on entry #' . $importEntry->id); | ||||
|         $budget = $budgets->find($importEntry->new); | ||||
|         if (!is_null($budget)) { | ||||
|             $current = $limits->findByBudgetAndDate($budget, new Carbon($payload['data']['date'])); | ||||
|             if (is_null($current)) { | ||||
|                 // create it! | ||||
|                 $payload['data']['budget_id'] = $budget->id; | ||||
|                 $payload['data']['startdate'] = $payload['data']['date']; | ||||
|                 $payload['data']['period']    = 'monthly'; | ||||
|                 $lim                          = $limits->store((array)$payload['data']); | ||||
|                 $repository->store($importMap, 'Limit', $payload['data']['id'], $lim->id); | ||||
|                 \Event::fire('limits.store', [$lim]); | ||||
|                 \Log::debug('Imported ' . $payload['class'] . ', for ' . $budget->name . ' (' . $lim->startdate . ').'); | ||||
|             } else { | ||||
|                 // already has! | ||||
|                 $repository->store($importMap, 'Budget', $payload['data']['id'], $current->id); | ||||
|                 \Log::debug('Already had ' . $payload['class'] . ', for ' . $budget->name . ' (' . $current->startdate . ').'); | ||||
|             } | ||||
|         } else { | ||||
|             // cannot import component limit, no longer supported. | ||||
|             \Log::error('Cannot import limit for other than budget!'); | ||||
|         } | ||||
|         $job->delete(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param SyncJob $job | ||||
|      * @param array $payload | ||||
|      */ | ||||
|     public function importPiggybank(SyncJob $job, array $payload) | ||||
|     { | ||||
|         /** @var \Firefly\Storage\Piggybank\PiggybankRepositoryInterface $piggybanks */ | ||||
|         $piggybanks = \App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface'); | ||||
|  | ||||
|         /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ | ||||
|         $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); | ||||
|  | ||||
|         /** @var \Importmap $importMap */ | ||||
|         $importMap = $repository->findImportmap($payload['mapID']); | ||||
|  | ||||
|         /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ | ||||
|         $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|  | ||||
|         // try to find related piggybank: | ||||
|         $current = $piggybanks->findByName($payload['data']['name']); | ||||
|  | ||||
|         // we need an account to go with this piggy bank: | ||||
|         $set = $accounts->getActiveDefault(); | ||||
|         if (count($set) > 0) { | ||||
|             $account                       = $set[0]; | ||||
|             $payload['data']['account_id'] = $account->id; | ||||
|         } else { | ||||
|             \Log::debug('Released job for work in five seconds...'); | ||||
|             $job->release(5); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (is_null($current)) { | ||||
|             $payload['data']['targetamount']  = floatval($payload['data']['target']); | ||||
|             $payload['data']['repeats']       = 0; | ||||
|             $payload['data']['rep_every']     = 1; | ||||
|             $payload['data']['reminder_skip'] = 1; | ||||
|             $payload['data']['rep_times']     = 1; | ||||
|             $piggy                            = $piggybanks->store((array)$payload['data']); | ||||
|             $repository->store($importMap, 'Piggybank', $payload['data']['id'], $piggy->id); | ||||
|             \Log::debug('Imported ' . $payload['class'] . ' "' . $payload['data']['name'] . '".'); | ||||
|             \Event::fire('piggybanks.store', [$piggy]); | ||||
|         } else { | ||||
|             $repository->store($importMap, 'Piggybank', $payload['data']['id'], $current->id); | ||||
|             \Log::debug('Already had ' . $payload['class'] . ' "' . $payload['data']['name'] . '".'); | ||||
|         } | ||||
|         $job->delete(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param SyncJob $job | ||||
|      * @param array $payload | ||||
|      */ | ||||
|     public function importPredictable(SyncJob $job, array $payload) | ||||
|     { | ||||
|         /** @var \Firefly\Storage\RecurringTransaction\RecurringTransactionRepositoryInterface $piggybanks */ | ||||
|         $recurring = \App::make('Firefly\Storage\RecurringTransaction\RecurringTransactionRepositoryInterface'); | ||||
|  | ||||
|         /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ | ||||
|         $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); | ||||
|  | ||||
|         /** @var \Importmap $importMap */ | ||||
|         $importMap = $repository->findImportmap($payload['mapID']); | ||||
|  | ||||
|  | ||||
|         // try to find related recurring transaction: | ||||
|         $current = $recurring->findByName($payload['data']['description']); | ||||
|         if (is_null($current)) { | ||||
|  | ||||
|             $payload['data']['name']        = $payload['data']['description']; | ||||
|             $payload['data']['match']       = join(',', explode(' ', $payload['data']['description'])); | ||||
|             $pct                            = intval($payload['data']['pct']); | ||||
|             $payload['data']['amount_min']  = floatval($payload['data']['amount']) * ($pct / 100) * -1; | ||||
|             $payload['data']['amount_max']  = floatval($payload['data']['amount']) * (1 + ($pct / 100)) * -1; | ||||
|             $payload['data']['date']        = date('Y-m-') . $payload['data']['dom']; | ||||
|             $payload['data']['repeat_freq'] = 'monthly'; | ||||
|             $payload['data']['active']      = intval($payload['data']['inactive']) == 1 ? 0 : 1; | ||||
|             $payload['data']['automatch']   = 1; | ||||
|  | ||||
|             $recur = $recurring->store((array)$payload['data']); | ||||
|  | ||||
|             $repository->store($importMap, 'RecurringTransaction', $payload['data']['id'], $recur->id); | ||||
|             \Log::debug('Imported ' . $payload['class'] . ' "' . $payload['data']['name'] . '".'); | ||||
|         } else { | ||||
|             $repository->store($importMap, 'RecurringTransaction', $payload['data']['id'], $current->id); | ||||
|             \Log::debug('Already had ' . $payload['class'] . ' "' . $payload['data']['description'] . '".'); | ||||
|         } | ||||
|         $job->delete(); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param SyncJob $job | ||||
|      * @param array $payload | ||||
|      */ | ||||
|     public function importSetting(SyncJob $job, array $payload) | ||||
|     { | ||||
|         switch ($payload['data']['name']) { | ||||
|             default: | ||||
|                 $job->delete(); | ||||
|                 return; | ||||
|                 break; | ||||
|             case 'piggyAccount': | ||||
|                 // if we have this account, update all piggy banks: | ||||
|                 $accountID = intval($payload['data']['value']); | ||||
|  | ||||
|                 /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ | ||||
|                 $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); | ||||
|  | ||||
|                 /** @var \Importmap $importMap */ | ||||
|                 $importMap = $repository->findImportmap($payload['mapID']); | ||||
|  | ||||
|  | ||||
|                 $importEntry = $repository->findImportEntry($importMap, 'Account', $accountID); | ||||
|                 if ($importEntry) { | ||||
|                     /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ | ||||
|                     $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|  | ||||
|                     /** @var \Firefly\Storage\Piggybank\PiggybankRepositoryInterface $piggybanks */ | ||||
|                     $piggybanks = \App::make('Firefly\Storage\Piggybank\PiggybankRepositoryInterface'); | ||||
|  | ||||
|                     $all     = $piggybanks->get(); | ||||
|                     $account = $accounts->find($importEntry->new); | ||||
|  | ||||
|                     \Log::debug('Updating all piggybanks, found the right setting.'); | ||||
|                     foreach ($all as $piggy) { | ||||
|                         $piggy->account()->associate($account); | ||||
|                         unset($piggy->leftInAccount); //?? | ||||
|                         $piggy->save(); | ||||
|                     } | ||||
|                 } else { | ||||
|                     $job->release(5); | ||||
|                 } | ||||
|                 break; | ||||
|         } | ||||
|         $job->delete(); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param SyncJob $job | ||||
|      * @param array $payload | ||||
|      */ | ||||
|     public function importTransaction(SyncJob $job, array $payload) | ||||
|     { | ||||
|         /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ | ||||
|         $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); | ||||
|  | ||||
|         /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ | ||||
|         $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|  | ||||
|         /** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $journals */ | ||||
|         $journals = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); | ||||
|  | ||||
|  | ||||
|         /** @var \Importmap $importMap */ | ||||
|         $importMap = $repository->findImportmap($payload['mapID']); | ||||
|  | ||||
|         // find or create the account type for the import account. | ||||
|         // find or create the account for the import account. | ||||
|         $accountType   = $accounts->findAccountType('Import account'); | ||||
|         $importAccount = $accounts->createOrFind('Import account', $accountType); | ||||
|  | ||||
|  | ||||
|         // if amount is more than zero, move from $importAccount | ||||
|         $amount = floatval($payload['data']['amount']); | ||||
|  | ||||
|         $accountEntry    = $repository->findImportEntry($importMap, 'Account', intval($payload['data']['account_id'])); | ||||
|         $personalAccount = $accounts->find($accountEntry->new); | ||||
|  | ||||
|         if ($amount < 0) { | ||||
|             // if amount is less than zero, move to $importAccount | ||||
|             $accountFrom = $personalAccount; | ||||
|             $accountTo   = $importAccount; | ||||
|         } else { | ||||
|             $accountFrom = $importAccount; | ||||
|             $accountTo   = $personalAccount; | ||||
|         } | ||||
|         $amount = $amount < 0 ? $amount * -1 : $amount; | ||||
|         $date   = new Carbon($payload['data']['date']); | ||||
|  | ||||
|         // find a journal? | ||||
|         $current = $repository->findImportEntry($importMap, 'Transaction', intval($payload['data']['id'])); | ||||
|  | ||||
|  | ||||
|         if (is_null($current)) { | ||||
|             $journal = $journals->createSimpleJournal($accountFrom, $accountTo, | ||||
|                 $payload['data']['description'], $amount, $date); | ||||
|             $repository->store($importMap, 'Transaction', $payload['data']['id'], $journal->id); | ||||
|             \Log::debug('Imported transaction "' . $payload['data']['description'] . '" (' . $journal->date->format('Y-m-d') . ').'); | ||||
|         } else { | ||||
|             // do nothing. | ||||
|             \Log::debug('ALREADY imported transaction "' . $payload['data']['description'] . '".'); | ||||
|         } | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param SyncJob $job | ||||
|      * @param array $payload | ||||
|      */ | ||||
|     public function importTransfer(SyncJob $job, array $payload) | ||||
|     { | ||||
|         /** @var \Firefly\Storage\Import\ImportRepositoryInterface $repository */ | ||||
|         $repository = \App::make('Firefly\Storage\Import\ImportRepositoryInterface'); | ||||
|  | ||||
|         /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ | ||||
|         $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|  | ||||
|         /** @var \Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface $journals */ | ||||
|         $journals = \App::make('Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface'); | ||||
|  | ||||
|  | ||||
|         /** @var \Importmap $importMap */ | ||||
|         $importMap = $repository->findImportmap($payload['mapID']); | ||||
|  | ||||
|         // from account: | ||||
|         $oldFromAccountID    = intval($payload['data']['accountfrom_id']); | ||||
|         $oldFromAccountEntry = $repository->findImportEntry($importMap, 'Account', $oldFromAccountID); | ||||
|         $accountFrom         = $accounts->find($oldFromAccountEntry->new); | ||||
|  | ||||
|         // to account: | ||||
|         $oldToAccountID    = intval($payload['data']['accountto_id']); | ||||
|         $oldToAccountEntry = $repository->findImportEntry($importMap, 'Account', $oldToAccountID); | ||||
|         $accountTo         = $accounts->find($oldToAccountEntry->new); | ||||
|         if (!is_null($accountFrom) && !is_null($accountTo)) { | ||||
|             $amount  = floatval($payload['data']['amount']); | ||||
|             $date    = new Carbon($payload['data']['date']); | ||||
|             $journal = $journals->createSimpleJournal($accountFrom, $accountTo, $payload['data']['description'], | ||||
|                 $amount, $date); | ||||
|             \Log::debug('Imported transfer "' . $payload['data']['description'] . '".'); | ||||
|             $job->delete(); | ||||
|         } else { | ||||
|             $job->release(5); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param SyncJob $job | ||||
|      * @param $payload | ||||
|      */ | ||||
|     public function start(SyncJob $job, array $payload) | ||||
|     { | ||||
|         \Log::debug('Start with job "start"'); | ||||
|         $user     = \User::find($payload['user']); | ||||
|         $filename = $payload['file']; | ||||
|         if (file_exists($filename)) { | ||||
|             // we are able to process the file! | ||||
|  | ||||
|             // make an import map. Which is some kind of object because we use queues. | ||||
|             $importMap = new \Importmap; | ||||
|             $importMap->user()->associate($user); | ||||
|             $importMap->file = $filename; | ||||
|             $importMap->save(); | ||||
|  | ||||
|             // we can now launch a billion jobs importing every little thing into Firefly III | ||||
|             $raw  = file_get_contents($filename); | ||||
|             $JSON = json_decode($raw); | ||||
|  | ||||
|             $classes = ['accounts', 'components', 'limits', 'piggybanks', | ||||
|                 'predictables', 'settings', 'transactions', 'transfers']; | ||||
|  | ||||
|             foreach ($classes as $classes_plural) { | ||||
|                 $class = ucfirst(\Str::singular($classes_plural)); | ||||
|                 \Log::debug('Create job to import all ' . $classes_plural); | ||||
|                 foreach ($JSON->$classes_plural as $entry) { | ||||
|                     //\Log::debug('Create job to import single ' . $class); | ||||
|                     $fn          = 'import' . $class; | ||||
|                     $jobFunction = 'Firefly\Queue\Import@' . $fn; | ||||
|                     \Queue::push($jobFunction, ['data' => $entry, 'class' => $class, 'mapID' => $importMap->id]); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // accounts, components, limits, piggybanks, predictables, settings, transactions, transfers | ||||
|             // component_predictables, component_transactions, component_transfers | ||||
|  | ||||
|             $count = count($JSON->component_transaction); | ||||
|             foreach ($JSON->component_transaction as $index => $entry) { | ||||
|                 //\Log::debug('Create job to import components_transaction! Yay! (' . $index . '/' . $count . ') '); | ||||
|                 $fn          = 'importComponentTransaction'; | ||||
|                 $jobFunction = 'Firefly\Queue\Import@' . $fn; | ||||
|                 \Queue::push($jobFunction, ['data' => $entry, 'mapID' => $importMap->id]); | ||||
|             } | ||||
|  | ||||
|  | ||||
|         } | ||||
|  | ||||
|  | ||||
|         echo 'Done'; | ||||
|         \Log::debug('Done with job "start"'); | ||||
|         exit; | ||||
|  | ||||
|         // this is it, close the job: | ||||
|         $job->delete(); | ||||
|     } | ||||
| }  | ||||
| @@ -46,11 +46,23 @@ interface AccountRepositoryInterface | ||||
|     public function find($accountId); | ||||
|  | ||||
|     /** | ||||
|      * @param $name | ||||
|      * | ||||
|      * @param $type | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function findByName($name); | ||||
|     public function findAccountType($type); | ||||
|  | ||||
|     /** | ||||
|      * @param $name | ||||
|      * @param \AccountType $type | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function findByName($name, \AccountType $type = null); | ||||
|  | ||||
|     /** | ||||
|      * @param $name | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function findByNameAny($name); | ||||
|  | ||||
|     /** | ||||
|      * @return mixed | ||||
|   | ||||
| @@ -148,6 +148,14 @@ class EloquentAccountRepository implements AccountRepositoryInterface | ||||
|                     ->get(['accounts.*']); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param $type | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function findAccountType($type) { | ||||
|         return \AccountType::where('type',$type)->first(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return array|mixed | ||||
|      */ | ||||
| @@ -203,6 +211,14 @@ class EloquentAccountRepository implements AccountRepositoryInterface | ||||
|     { | ||||
|         $type = \AccountType::where('type', 'Cash account')->first(); | ||||
|         $cash = \Auth::user()->accounts()->where('account_type_id', $type->id)->first(); | ||||
|         if(is_null($cash)) { | ||||
|             $cash = new \Account; | ||||
|             $cash->accountType()->associate($type); | ||||
|             $cash->user()->associate(\Auth::user()); | ||||
|             $cash->name = 'Cash account'; | ||||
|             $cash->active = 1; | ||||
|             $cash->save(); | ||||
|         } | ||||
|  | ||||
|         return $cash; | ||||
|  | ||||
| @@ -234,6 +250,9 @@ class EloquentAccountRepository implements AccountRepositoryInterface | ||||
|             && get_class($data['account_type']) == 'AccountType' | ||||
|         ) { | ||||
|             $accountType = $data['account_type']; | ||||
|         } else if (isset($data['account_type']) && is_string($data['account_type'])) { | ||||
|             $accountType = \AccountType::where('type', $data['account_type'])->first(); | ||||
|  | ||||
|         } else { | ||||
|             $accountType = \AccountType::where('type', 'Default account')->first(); | ||||
|         } | ||||
| @@ -243,7 +262,12 @@ class EloquentAccountRepository implements AccountRepositoryInterface | ||||
|          */ | ||||
|         $account = new \Account; | ||||
|         $account->accountType()->associate($accountType); | ||||
|         $account->user()->associate(\Auth::user()); | ||||
|         if (\Auth::check()) { | ||||
|             $account->user()->associate(\Auth::user()); | ||||
|         } else { | ||||
|             $account->user_id = $data['user_id']; | ||||
|         } | ||||
|  | ||||
|         $account->name = $data['name']; | ||||
|         $account->active | ||||
|                        = isset($data['active']) && intval($data['active']) >= 0 && intval($data['active']) <= 1 ? intval( | ||||
| @@ -256,7 +280,9 @@ class EloquentAccountRepository implements AccountRepositoryInterface | ||||
|             if (isset($data['openingbalance']) && isset($data['openingbalancedate'])) { | ||||
|                 $amount = floatval($data['openingbalance']); | ||||
|                 $date   = new Carbon($data['openingbalancedate']); | ||||
|                 $this->_createInitialBalance($account, $amount, $date); | ||||
|                 if ($amount != 0) { | ||||
|                     $this->_createInitialBalance($account, $amount, $date); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -302,6 +328,20 @@ class EloquentAccountRepository implements AccountRepositoryInterface | ||||
|         return $account; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Used for import | ||||
|      * | ||||
|      * @param              $name | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function findByNameAny($name) | ||||
|     { | ||||
|         return \Auth::user()->accounts() | ||||
|                     ->where('name', 'like', '%' . $name . '%') | ||||
|                     ->first(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param \Account $account | ||||
|      * @param int $amount | ||||
|   | ||||
| @@ -23,6 +23,13 @@ interface BudgetRepositoryInterface | ||||
|      */ | ||||
|     public function find($budgetId); | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param $budgetName | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function findByName($budgetName); | ||||
|  | ||||
|     /** | ||||
|      * @return mixed | ||||
|      */ | ||||
|   | ||||
| @@ -35,6 +35,12 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface | ||||
|         return \Auth::user()->budgets()->find($budgetId); | ||||
|     } | ||||
|  | ||||
|     public function findByName($budgetName) | ||||
|     { | ||||
|  | ||||
|         return \Auth::user()->budgets()->whereName($budgetName)->first(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return mixed | ||||
|      */ | ||||
| @@ -88,7 +94,7 @@ class EloquentBudgetRepository implements BudgetRepositoryInterface | ||||
|         $budget->save(); | ||||
|  | ||||
|         // if limit, create limit (repetition itself will be picked up elsewhere). | ||||
|         if (floatval($data['amount']) > 0) { | ||||
|         if (isset($data['amount']) && floatval($data['amount']) > 0) { | ||||
|             $limit = new \Limit; | ||||
|             $limit->budget()->associate($budget); | ||||
|             $startDate = new Carbon; | ||||
|   | ||||
							
								
								
									
										39
									
								
								app/lib/Firefly/Storage/Import/EloquentImportRepository.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/lib/Firefly/Storage/Import/EloquentImportRepository.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| <?php | ||||
|  | ||||
| namespace Firefly\Storage\Import; | ||||
|  | ||||
|  | ||||
| class EloquentImportRepository implements ImportRepositoryInterface | ||||
| { | ||||
|  | ||||
|     public function findImportComponentMap(\Importmap $map, $oldComponentId) | ||||
|     { | ||||
|         $entry = \Importentry::where('importmap_id', $map->id) | ||||
|                              ->whereIn('class', ['Budget', 'Category', 'Account', 'Component']) | ||||
|                              ->where('old', intval($oldComponentId))->first(); | ||||
|  | ||||
|         return $entry; | ||||
|     } | ||||
|  | ||||
|     public function findImportEntry(\Importmap $map, $class, $oldID) | ||||
|     { | ||||
|  | ||||
|         return \Importentry::where('importmap_id', $map->id)->where('class', $class)->where('old', $oldID)->first(); | ||||
|     } | ||||
|  | ||||
|     public function findImportMap($id) | ||||
|     { | ||||
|         return \Importmap::find($id); | ||||
|     } | ||||
|  | ||||
|     public function store(\Importmap $map, $class, $oldID, $newID) | ||||
|     { | ||||
|         $entry = new \Importentry; | ||||
|         $entry->importmap()->associate($map); | ||||
|         $entry->class = $class; | ||||
|         $entry->old   = intval($oldID); | ||||
|         $entry->new   = intval($newID); | ||||
|         $entry->save(); | ||||
|     } | ||||
|  | ||||
| }  | ||||
							
								
								
									
										27
									
								
								app/lib/Firefly/Storage/Import/ImportRepositoryInterface.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								app/lib/Firefly/Storage/Import/ImportRepositoryInterface.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| <?php | ||||
|  | ||||
| namespace Firefly\Storage\Import; | ||||
|  | ||||
| /** | ||||
|  * Interface ImportRepositoryInterface | ||||
|  * @package Firefly\Storage\Import | ||||
|  */ | ||||
| interface ImportRepositoryInterface | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param \Importmap $map | ||||
|      * @param $class | ||||
|      * @param $oldID | ||||
|      * @param $newID | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function store(\Importmap $map, $class, $oldID, $newID); | ||||
|  | ||||
|     public function findImportMap($id); | ||||
|  | ||||
|     public function findImportEntry(\Importmap $map, $class, $oldID); | ||||
|  | ||||
|     public function findImportComponentMap(\Importmap $map, $oldComponentId); | ||||
| }  | ||||
| @@ -13,6 +13,9 @@ use Carbon\Carbon; | ||||
| class EloquentLimitRepository implements LimitRepositoryInterface | ||||
| { | ||||
|  | ||||
|     public function findByBudgetAndDate(\Budget $budget, Carbon $date) { | ||||
|         return \Limit::whereComponentId($budget->id)->where('startdate',$date->format('Y-m-d'))->first(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param \Limit $limit | ||||
|   | ||||
| @@ -12,6 +12,36 @@ use Carbon\Carbon; | ||||
| interface LimitRepositoryInterface | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param \Limit $limit | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function destroy(\Limit $limit); | ||||
|  | ||||
|     /** | ||||
|      * @param $limitId | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function find($limitId); | ||||
|  | ||||
|     /** | ||||
|      * @param \Budget $budget | ||||
|      * @param Carbon $date | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function findByBudgetAndDate(\Budget $budget, Carbon $date); | ||||
|  | ||||
|     /** | ||||
|      * @param \Budget $budget | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function getTJByBudgetAndDateRange(\Budget $budget, Carbon $start, Carbon $end); | ||||
|  | ||||
|     /** | ||||
|      * @param $data | ||||
|      * | ||||
| @@ -26,27 +56,4 @@ interface LimitRepositoryInterface | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function update(\Limit $limit, $data); | ||||
|  | ||||
|     /** | ||||
|      * @param \Budget $budget | ||||
|      * @param Carbon  $start | ||||
|      * @param Carbon  $end | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function getTJByBudgetAndDateRange(\Budget $budget, Carbon $start, Carbon $end); | ||||
|  | ||||
|     /** | ||||
|      * @param $limitId | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function find($limitId); | ||||
|  | ||||
|     /** | ||||
|      * @param \Limit $limit | ||||
|      * | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function destroy(\Limit $limit); | ||||
| }  | ||||
| @@ -21,14 +21,14 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface | ||||
|     public function count() | ||||
|     { | ||||
|         return \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where( | ||||
|             'accounts.user_id', \Auth::user()->id | ||||
|                          'accounts.user_id', \Auth::user()->id | ||||
|         )->count(); | ||||
|     } | ||||
|  | ||||
|     public function countNonrepeating() | ||||
|     { | ||||
|         return \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where( | ||||
|             'accounts.user_id', \Auth::user()->id | ||||
|                          'accounts.user_id', \Auth::user()->id | ||||
|         )->where('repeats', 0)->count(); | ||||
|  | ||||
|     } | ||||
| @@ -36,7 +36,7 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface | ||||
|     public function countRepeating() | ||||
|     { | ||||
|         return \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where( | ||||
|             'accounts.user_id', \Auth::user()->id | ||||
|                          'accounts.user_id', \Auth::user()->id | ||||
|         )->where('repeats', 1)->count(); | ||||
|     } | ||||
|  | ||||
| @@ -60,10 +60,17 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface | ||||
|     public function find($piggyBankId) | ||||
|     { | ||||
|         return \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where( | ||||
|             'accounts.user_id', \Auth::user()->id | ||||
|                          'accounts.user_id', \Auth::user()->id | ||||
|         )->where('piggybanks.id', $piggyBankId)->first(['piggybanks.*']); | ||||
|     } | ||||
|  | ||||
|     public function findByName($piggyBankName) | ||||
|     { | ||||
|         return \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')->where( | ||||
|                          'accounts.user_id', \Auth::user()->id | ||||
|         )->where('piggybanks.name', $piggyBankName)->first(['piggybanks.*']); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return mixed | ||||
|      */ | ||||
| @@ -122,19 +129,19 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface | ||||
|      */ | ||||
|     public function store($data) | ||||
|     { | ||||
|         if ($data['targetdate'] == '') { | ||||
|         if (isset($data['targetdate']) && $data['targetdate'] == '') { | ||||
|             unset($data['targetdate']); | ||||
|         } | ||||
|         if ($data['reminder'] == 'none') { | ||||
|         if (isset($data['reminder']) && $data['reminder'] == 'none') { | ||||
|             unset($data['reminder']); | ||||
|         } | ||||
|         if ($data['startdate'] == '') { | ||||
|         if (isset($data['startdate']) && $data['startdate'] == '') { | ||||
|             unset($data['startdate']); | ||||
|         } | ||||
|  | ||||
|         /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ | ||||
|         $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|         $account = isset($data['account_id']) ? $accounts->find($data['account_id']) : null; | ||||
|         $account  = isset($data['account_id']) ? $accounts->find($data['account_id']) : null; | ||||
|  | ||||
|  | ||||
|         $piggyBank = new \Piggybank($data); | ||||
| @@ -142,7 +149,7 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface | ||||
|         if (!is_null($piggyBank->reminder) && is_null($piggyBank->startdate) && is_null($piggyBank->targetdate)) { | ||||
|  | ||||
|             $piggyBank->errors()->add('reminder', 'Cannot create reminders without start ~ AND target date.'); | ||||
|  | ||||
|             \Log::error('PiggyBank create-error: ' . $piggyBank->errors()->first()); | ||||
|             return $piggyBank; | ||||
|  | ||||
|         } | ||||
| @@ -150,6 +157,7 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface | ||||
|  | ||||
|         if ($piggyBank->repeats && !isset($data['targetdate'])) { | ||||
|             $piggyBank->errors()->add('targetdate', 'Target date is mandatory!'); | ||||
|             \Log::error('PiggyBank create-error: ' . $piggyBank->errors()->first()); | ||||
|  | ||||
|             return $piggyBank; | ||||
|         } | ||||
| @@ -161,13 +169,14 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface | ||||
|         if ($piggyBank->validate()) { | ||||
|             if (!is_null($piggyBank->targetdate) && $piggyBank->targetdate < $today) { | ||||
|                 $piggyBank->errors()->add('targetdate', 'Target date cannot be in the past.'); | ||||
|                 \Log::error('PiggyBank create-error: ' . $piggyBank->errors()->first()); | ||||
|  | ||||
|                 return $piggyBank; | ||||
|             } | ||||
|  | ||||
|             if (!is_null($piggyBank->reminder) && !is_null($piggyBank->targetdate)) { | ||||
|                 // first period for reminder is AFTER target date. | ||||
|                 $reminderSkip = $piggyBank->reminder_skip < 1 ? 1 : intval($piggyBank->reminder_skip); | ||||
|                 $reminderSkip  = $piggyBank->reminder_skip < 1 ? 1 : intval($piggyBank->reminder_skip); | ||||
|                 $firstReminder = new Carbon; | ||||
|                 switch ($piggyBank->reminder) { | ||||
|                     case 'day': | ||||
| @@ -188,8 +197,9 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface | ||||
|                 } | ||||
|                 if ($firstReminder > $piggyBank->targetdate) { | ||||
|                     $piggyBank->errors()->add( | ||||
|                         'reminder', 'The reminder has been set to remind you after the piggy bank will expire.' | ||||
|                               'reminder', 'The reminder has been set to remind you after the piggy bank will expire.' | ||||
|                     ); | ||||
|                     \Log::error('PiggyBank create-error: ' . $piggyBank->errors()->first()); | ||||
|  | ||||
|                     return $piggyBank; | ||||
|                 } | ||||
| @@ -197,6 +207,7 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface | ||||
|             $piggyBank->save(); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         return $piggyBank; | ||||
|     } | ||||
|  | ||||
| @@ -210,19 +221,19 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface | ||||
|     { | ||||
|         /** @var \Firefly\Storage\Account\AccountRepositoryInterface $accounts */ | ||||
|         $accounts = \App::make('Firefly\Storage\Account\AccountRepositoryInterface'); | ||||
|         $account = isset($data['account_id']) ? $accounts->find($data['account_id']) : null; | ||||
|         $account  = isset($data['account_id']) ? $accounts->find($data['account_id']) : null; | ||||
|  | ||||
|         if (!is_null($account)) { | ||||
|             $piggy->account()->associate($account); | ||||
|         } | ||||
|  | ||||
|         $piggy->name = $data['name']; | ||||
|         $piggy->targetamount = floatval($data['targetamount']); | ||||
|         $piggy->reminder = isset($data['reminder']) && $data['reminder'] != 'none' ? $data['reminder'] : null; | ||||
|         $piggy->name          = $data['name']; | ||||
|         $piggy->targetamount  = floatval($data['targetamount']); | ||||
|         $piggy->reminder      = isset($data['reminder']) && $data['reminder'] != 'none' ? $data['reminder'] : null; | ||||
|         $piggy->reminder_skip = $data['reminder_skip']; | ||||
|         $piggy->targetdate = strlen($data['targetdate']) > 0 ? new Carbon($data['targetdate']) : null; | ||||
|         $piggy->targetdate    = strlen($data['targetdate']) > 0 ? new Carbon($data['targetdate']) : null; | ||||
|         $piggy->startdate | ||||
|             = isset($data['startdate']) && strlen($data['startdate']) > 0 ? new Carbon($data['startdate']) : null; | ||||
|                               = isset($data['startdate']) && strlen($data['startdate']) > 0 ? new Carbon($data['startdate']) : null; | ||||
|  | ||||
|  | ||||
|         foreach ($piggy->piggybankrepetitions()->get() as $rep) { | ||||
| @@ -230,7 +241,7 @@ class EloquentPiggybankRepository implements PiggybankRepositoryInterface | ||||
|         } | ||||
|  | ||||
|         if ($piggy->repeats == 1) { | ||||
|             $piggy->rep_every = intval($data['rep_every']); | ||||
|             $piggy->rep_every  = intval($data['rep_every']); | ||||
|             $piggy->rep_length = $data['rep_length']; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -39,7 +39,7 @@ interface PiggybankRepositoryInterface | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function find($piggyBankId); | ||||
|  | ||||
|     public function findByName($piggyBankName); | ||||
|     /** | ||||
|      * @return mixed | ||||
|      */ | ||||
|   | ||||
| @@ -24,6 +24,11 @@ class EloquentRecurringTransactionRepository implements RecurringTransactionRepo | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     public function findByName($name) | ||||
|     { | ||||
|         return \Auth::user()->recurringtransactions()->where('name', 'LIKE', '%' . $name . '%')->first(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return mixed | ||||
|      */ | ||||
| @@ -41,8 +46,8 @@ class EloquentRecurringTransactionRepository implements RecurringTransactionRepo | ||||
|     { | ||||
|         $recurringTransaction = new \RecurringTransaction; | ||||
|         $recurringTransaction->user()->associate(\Auth::user()); | ||||
|         $recurringTransaction->name = $data['name']; | ||||
|         $recurringTransaction->match = join(' ', explode(',', $data['match'])); | ||||
|         $recurringTransaction->name       = $data['name']; | ||||
|         $recurringTransaction->match      = join(' ', explode(',', $data['match'])); | ||||
|         $recurringTransaction->amount_max = floatval($data['amount_max']); | ||||
|         $recurringTransaction->amount_min = floatval($data['amount_min']); | ||||
|  | ||||
| @@ -53,10 +58,10 @@ class EloquentRecurringTransactionRepository implements RecurringTransactionRepo | ||||
|             return $recurringTransaction; | ||||
|         } | ||||
|  | ||||
|         $recurringTransaction->date = new Carbon($data['date']); | ||||
|         $recurringTransaction->active = isset($data['active']) ? intval($data['active']) : 0; | ||||
|         $recurringTransaction->automatch = isset($data['automatch']) ? intval($data['automatch']) : 0; | ||||
|         $recurringTransaction->skip = isset($data['skip']) ? intval($data['skip']) : 0; | ||||
|         $recurringTransaction->date        = new Carbon($data['date']); | ||||
|         $recurringTransaction->active      = isset($data['active']) ? intval($data['active']) : 0; | ||||
|         $recurringTransaction->automatch   = isset($data['automatch']) ? intval($data['automatch']) : 0; | ||||
|         $recurringTransaction->skip        = isset($data['skip']) ? intval($data['skip']) : 0; | ||||
|         $recurringTransaction->repeat_freq = $data['repeat_freq']; | ||||
|  | ||||
|         if ($recurringTransaction->validate()) { | ||||
| @@ -74,8 +79,8 @@ class EloquentRecurringTransactionRepository implements RecurringTransactionRepo | ||||
|      */ | ||||
|     public function update(\RecurringTransaction $recurringTransaction, $data) | ||||
|     { | ||||
|         $recurringTransaction->name = $data['name']; | ||||
|         $recurringTransaction->match = join(' ', explode(',', $data['match'])); | ||||
|         $recurringTransaction->name       = $data['name']; | ||||
|         $recurringTransaction->match      = join(' ', explode(',', $data['match'])); | ||||
|         $recurringTransaction->amount_max = floatval($data['amount_max']); | ||||
|         $recurringTransaction->amount_min = floatval($data['amount_min']); | ||||
|  | ||||
| @@ -85,10 +90,10 @@ class EloquentRecurringTransactionRepository implements RecurringTransactionRepo | ||||
|  | ||||
|             return $recurringTransaction; | ||||
|         } | ||||
|         $recurringTransaction->date = new Carbon($data['date']); | ||||
|         $recurringTransaction->active = isset($data['active']) ? intval($data['active']) : 0; | ||||
|         $recurringTransaction->automatch = isset($data['automatch']) ? intval($data['automatch']) : 0; | ||||
|         $recurringTransaction->skip = isset($data['skip']) ? intval($data['skip']) : 0; | ||||
|         $recurringTransaction->date        = new Carbon($data['date']); | ||||
|         $recurringTransaction->active      = isset($data['active']) ? intval($data['active']) : 0; | ||||
|         $recurringTransaction->automatch   = isset($data['automatch']) ? intval($data['automatch']) : 0; | ||||
|         $recurringTransaction->skip        = isset($data['skip']) ? intval($data['skip']) : 0; | ||||
|         $recurringTransaction->repeat_freq = $data['repeat_freq']; | ||||
|  | ||||
|         if ($recurringTransaction->validate()) { | ||||
|   | ||||
| @@ -16,6 +16,12 @@ interface RecurringTransactionRepositoryInterface | ||||
|      */ | ||||
|     public function get(); | ||||
|  | ||||
|     /** | ||||
|      * @param $name | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function findByName($name); | ||||
|  | ||||
|     /** | ||||
|      * @param $data | ||||
|      * | ||||
|   | ||||
| @@ -18,55 +18,60 @@ class StorageServiceProvider extends ServiceProvider | ||||
|     public function register() | ||||
|     { | ||||
|         $this->app->bind( | ||||
|             'Firefly\Storage\User\UserRepositoryInterface', | ||||
|             'Firefly\Storage\User\EloquentUserRepository' | ||||
|                   'Firefly\Storage\User\UserRepositoryInterface', | ||||
|                       'Firefly\Storage\User\EloquentUserRepository' | ||||
|         ); | ||||
|         $this->app->bind( | ||||
|             'Firefly\Storage\Transaction\TransactionRepositoryInterface', | ||||
|             'Firefly\Storage\Transaction\EloquentTransactionRepository' | ||||
|                   'Firefly\Storage\Transaction\TransactionRepositoryInterface', | ||||
|                       'Firefly\Storage\Transaction\EloquentTransactionRepository' | ||||
|         ); | ||||
|         $this->app->bind( | ||||
|                   'Firefly\Storage\Import\ImportRepositoryInterface', | ||||
|                       'Firefly\Storage\Import\EloquentImportRepository' | ||||
|         ); | ||||
|  | ||||
|  | ||||
|         $this->app->bind( | ||||
|                   'Firefly\Storage\Piggybank\PiggybankRepositoryInterface', | ||||
|                       'Firefly\Storage\Piggybank\EloquentPiggybankRepository' | ||||
|         ); | ||||
|  | ||||
|         $this->app->bind( | ||||
|             'Firefly\Storage\Piggybank\PiggybankRepositoryInterface', | ||||
|             'Firefly\Storage\Piggybank\EloquentPiggybankRepository' | ||||
|                   'Firefly\Storage\RecurringTransaction\RecurringTransactionRepositoryInterface', | ||||
|                       'Firefly\Storage\RecurringTransaction\EloquentRecurringTransactionRepository' | ||||
|         ); | ||||
|  | ||||
|         $this->app->bind( | ||||
|             'Firefly\Storage\RecurringTransaction\RecurringTransactionRepositoryInterface', | ||||
|             'Firefly\Storage\RecurringTransaction\EloquentRecurringTransactionRepository' | ||||
|                   'Firefly\Storage\Reminder\ReminderRepositoryInterface', | ||||
|                       'Firefly\Storage\Reminder\EloquentReminderRepository' | ||||
|         ); | ||||
|  | ||||
|         $this->app->bind( | ||||
|             'Firefly\Storage\Reminder\ReminderRepositoryInterface', | ||||
|             'Firefly\Storage\Reminder\EloquentReminderRepository' | ||||
|                   'Firefly\Storage\Account\AccountRepositoryInterface', | ||||
|                       'Firefly\Storage\Account\EloquentAccountRepository' | ||||
|         ); | ||||
|         $this->app->bind( | ||||
|                   'Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface', | ||||
|                       'Firefly\Storage\TransactionJournal\EloquentTransactionJournalRepository' | ||||
|         ); | ||||
|  | ||||
|         $this->app->bind( | ||||
|             'Firefly\Storage\Account\AccountRepositoryInterface', | ||||
|             'Firefly\Storage\Account\EloquentAccountRepository' | ||||
|         ); | ||||
|         $this->app->bind( | ||||
|             'Firefly\Storage\TransactionJournal\TransactionJournalRepositoryInterface', | ||||
|             'Firefly\Storage\TransactionJournal\EloquentTransactionJournalRepository' | ||||
|                   'Firefly\Storage\Component\ComponentRepositoryInterface', | ||||
|                       'Firefly\Storage\Component\EloquentComponentRepository' | ||||
|         ); | ||||
|  | ||||
|         $this->app->bind( | ||||
|             'Firefly\Storage\Component\ComponentRepositoryInterface', | ||||
|             'Firefly\Storage\Component\EloquentComponentRepository' | ||||
|                   'Firefly\Storage\Limit\LimitRepositoryInterface', | ||||
|                       'Firefly\Storage\Limit\EloquentLimitRepository' | ||||
|         ); | ||||
|  | ||||
|         $this->app->bind( | ||||
|             'Firefly\Storage\Limit\LimitRepositoryInterface', | ||||
|             'Firefly\Storage\Limit\EloquentLimitRepository' | ||||
|         ); | ||||
|  | ||||
|         $this->app->bind( | ||||
|             'Firefly\Storage\Budget\BudgetRepositoryInterface', | ||||
|             'Firefly\Storage\Budget\EloquentBudgetRepository' | ||||
|                   'Firefly\Storage\Budget\BudgetRepositoryInterface', | ||||
|                       'Firefly\Storage\Budget\EloquentBudgetRepository' | ||||
|         ); | ||||
|         $this->app->bind( | ||||
|             'Firefly\Storage\Category\CategoryRepositoryInterface', | ||||
|             'Firefly\Storage\Category\EloquentCategoryRepository' | ||||
|                   'Firefly\Storage\Category\CategoryRepositoryInterface', | ||||
|                       'Firefly\Storage\Category\EloquentCategoryRepository' | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|   | ||||
							
								
								
									
										8
									
								
								app/models/Importentry.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								app/models/Importentry.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| <?php | ||||
|  | ||||
| class Importentry extends Eloquent { | ||||
|     public function importmap() | ||||
|     { | ||||
|         return $this->belongsTo('Importmap'); | ||||
|     } | ||||
| }  | ||||
							
								
								
									
										17
									
								
								app/models/Importmap.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								app/models/Importmap.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Class Importmap | ||||
|  */ | ||||
| class Importmap extends Eloquent | ||||
| { | ||||
|     /** | ||||
|      * User | ||||
|      * | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
|      */ | ||||
|     public function user() | ||||
|     { | ||||
|         return $this->belongsTo('User'); | ||||
|     } | ||||
| }  | ||||
| @@ -157,8 +157,6 @@ Route::group(['before' => 'auth'], function () { | ||||
|         Route::get('chart/budget/{budget}/session', ['uses' => 'ChartController@budgetSession', 'as' => 'chart.budget.session']); | ||||
|         Route::get('chart/budget/envelope/{limitrepetition}', ['uses' => 'ChartController@budgetLimit', 'as' => 'chart.budget.limit']); | ||||
|  | ||||
|  | ||||
|  | ||||
|         // home controller | ||||
|         Route::get('/', ['uses' => 'HomeController@index', 'as' => 'index']); | ||||
|         Route::get('/flush', ['uses' => 'HomeController@flush', 'as' => 'flush']); | ||||
| @@ -172,20 +170,19 @@ Route::group(['before' => 'auth'], function () { | ||||
|         Route::get('/budgets/limits/delete/{limit}',['uses' => 'LimitController@delete','as' => 'budgets.limits.delete']); | ||||
|         Route::get('/budgets/limits/edit/{limit}',['uses' => 'LimitController@edit','as' => 'budgets.limits.edit']); | ||||
|  | ||||
|         Route::get('/migrate',['uses' => 'MigrateController@index', 'as' => 'migrate.index']); | ||||
|  | ||||
|         // piggy bank controller | ||||
|         Route::get('/piggybanks',['uses' => 'PiggybankController@index','as' => 'piggybanks.index']); | ||||
|         Route::get('/piggybanks/create/piggybank', ['uses' => 'PiggybankController@createPiggybank','as' => 'piggybanks.create.piggybank']); | ||||
|         Route::get('/piggybanks/create/repeated', ['uses' => 'PiggybankController@createRepeated','as' => 'piggybanks.create.repeated']); | ||||
|  | ||||
|         Route::get('/piggybanks/addMoney/{piggybank}', ['uses' => 'PiggybankController@addMoney','as' => 'piggybanks.amount.add']); | ||||
|         Route::get('/piggybanks/removeMoney/{piggybank}', ['uses' => 'PiggybankController@removeMoney','as' => 'piggybanks.amount.remove']); | ||||
|  | ||||
|         Route::get('/piggybanks/show/{piggybank}', ['uses' => 'PiggybankController@show','as' => 'piggybanks.show']); | ||||
|         Route::get('/piggybanks/edit/{piggybank}', ['uses' => 'PiggybankController@edit','as' => 'piggybanks.edit']); | ||||
|         Route::get('/piggybanks/delete/{piggybank}', ['uses' => 'PiggybankController@delete','as' => 'piggybanks.delete']); | ||||
|         Route::post('/piggybanks/updateAmount/{piggybank}',['uses' => 'PiggybankController@updateAmount','as' => 'piggybanks.updateAmount']); | ||||
|  | ||||
|  | ||||
|         // preferences controller | ||||
|         Route::get('/preferences', ['uses' => 'PreferencesController@index', 'as' => 'preferences']); | ||||
|  | ||||
| @@ -247,6 +244,8 @@ Route::group(['before' => 'csrf|auth'], function () { | ||||
|         Route::post('/budgets/limits/destroy/{limit}',['uses' => 'LimitController@destroy','as' => 'budgets.limits.destroy']); | ||||
|         Route::post('/budgets/limits/update/{limit}',['uses' => 'LimitController@update','as' => 'budgets.limits.update']); | ||||
|  | ||||
|         Route::post('/migrate/upload',['uses' => 'MigrateController@upload', 'as' => 'migrate.upload']); | ||||
|  | ||||
|  | ||||
|         // piggy bank controller | ||||
|         Route::post('/piggybanks/store/piggybank',['uses' => 'PiggybankController@storePiggybank','as' => 'piggybanks.store.piggybank']); | ||||
|   | ||||
| @@ -24,7 +24,7 @@ | ||||
| </div> | ||||
| <div class="row"> | ||||
|     <div class="col-lg-6 col-md-6 col-sm-12"> | ||||
|         <h2><a href="#">Migrate from Firefly II</a></h2> | ||||
|         <h2><a href="{{route('migrate.index')}}">Migrate from Firefly II</a></h2> | ||||
|  | ||||
|         <p> | ||||
|             Use this option if you have a JSON file from your current Firefly II installation. | ||||
|   | ||||
| @@ -14,10 +14,10 @@ | ||||
|         <p> | ||||
|               | ||||
|         </p> | ||||
|         {{Form::open(['files' => true])}} | ||||
|         {{Form::open(['files' => true,'url' => route('migrate.upload')])}} | ||||
|             <div class="form-group"> | ||||
|                 <label for="exportFile">Export file</label> | ||||
|                 <input name="exportFile" type="file" id="exportFile"> | ||||
|                 <label for="file">Export file</label> | ||||
|                 <input name="file" type="file" id="exportFile"> | ||||
|                 <p class="help-block">Upload the export file here.</p> | ||||
|             </div> | ||||
|             <button type="submit" class="btn btn-info">Import</button> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user