mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Migration improvements: (#3428)
- Refactored exceptions - Changed failed.blade.php - Removed report() method from exceptions - Added new force flag for MigrationController.php
This commit is contained in:
parent
20c818cf97
commit
280271718b
@ -7,13 +7,5 @@ use Throwable;
|
||||
|
||||
class MigrationValidatorFailed extends Exception
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
public function report()
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
// ..
|
||||
}
|
||||
|
@ -7,13 +7,5 @@ use Throwable;
|
||||
|
||||
class NonExistingMigrationFile extends Exception
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
public function report()
|
||||
{
|
||||
return 'Migration file doesn\'t exist or it is corrupted.';
|
||||
}
|
||||
// ..
|
||||
}
|
||||
|
@ -7,22 +7,5 @@ use Throwable;
|
||||
|
||||
class ProcessingMigrationArchiveFailed extends Exception
|
||||
{
|
||||
/**
|
||||
* @var Throwable
|
||||
*/
|
||||
private $previous;
|
||||
|
||||
public function __construct($message = "", $code = 0, Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->message = $message;
|
||||
$this->code = $code;
|
||||
$this->previous = $previous;
|
||||
}
|
||||
|
||||
public function report()
|
||||
{
|
||||
return 'Unable to open migration archive.';
|
||||
}
|
||||
|
||||
// ..
|
||||
}
|
||||
|
@ -7,18 +7,5 @@ use Throwable;
|
||||
|
||||
class ResourceDependencyMissing extends Exception
|
||||
{
|
||||
private $resource;
|
||||
private $dependency;
|
||||
|
||||
public function __construct($resource, $dependency)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->resource = $resource;
|
||||
$this->dependency = $dependency;
|
||||
}
|
||||
|
||||
public function report()
|
||||
{
|
||||
return "Resource '{$this->resource}' depends on '{$this->dependency}'.";
|
||||
}
|
||||
// ..
|
||||
}
|
||||
|
@ -7,19 +7,5 @@ use Throwable;
|
||||
|
||||
class ResourceNotAvailableForMigration extends Exception
|
||||
{
|
||||
private $resource;
|
||||
|
||||
public function __construct($resource)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->resource = $resource;
|
||||
}
|
||||
|
||||
public function report()
|
||||
{
|
||||
// TODO: Handle this nicely, throw response, etc.
|
||||
return "Resource {$this->resource} is not available for the migration.";
|
||||
}
|
||||
|
||||
// ..
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ use App\Exceptions\MigrationValidatorFailed;
|
||||
use App\Exceptions\NonExistingMigrationFile;
|
||||
use App\Exceptions\ProcessingMigrationArchiveFailed;
|
||||
use App\Exceptions\ResourceNotAvailableForMigration;
|
||||
use App\Factory\CompanyFactory;
|
||||
use App\Http\Requests\Account\CreateAccountRequest;
|
||||
use App\Http\Requests\Migration\UploadMigrationFileRequest;
|
||||
use App\Jobs\Account\CreateAccount;
|
||||
@ -192,7 +193,7 @@ class MigrationController extends BaseController
|
||||
*/
|
||||
public function startMigration(Request $request, Company $company)
|
||||
{
|
||||
if ($request->has('force'))
|
||||
if ($request->has('force') && !empty($request->force))
|
||||
$this->purgeCompany($company);
|
||||
|
||||
$migration_file = $request->file('migration')
|
||||
@ -201,12 +202,11 @@ class MigrationController extends BaseController
|
||||
if (app()->environment() == 'testing') return;
|
||||
|
||||
$user = auth()->user();
|
||||
$company = $company;
|
||||
|
||||
StartMigration::dispatch($migration_file, $user, $company);
|
||||
|
||||
return response()->json([
|
||||
'_id' => Str::uuid(),
|
||||
'_id' => Str::uuid(),
|
||||
'method' => config('queue.default'),
|
||||
'started_at' => now(),
|
||||
], 200);
|
||||
|
@ -131,14 +131,19 @@ class Import implements ShouldQueue
|
||||
foreach ($this->data as $key => $resource) {
|
||||
|
||||
if (!in_array($key, $this->available_imports)) {
|
||||
throw new ResourceNotAvailableForMigration($key);
|
||||
throw new ResourceNotAvailableForMigration("Resource {$key} is not available for migration.");
|
||||
}
|
||||
\Log::error($key);
|
||||
|
||||
\Log::error($key);
|
||||
|
||||
$method = sprintf("process%s", Str::ucfirst(Str::camel($key)));
|
||||
|
||||
$this->{$method}($resource);
|
||||
|
||||
info("$key done!!");
|
||||
}
|
||||
|
||||
info('Completed🚀🚀🚀🚀🚀 at ' . now());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -155,7 +160,7 @@ class Import implements ShouldQueue
|
||||
|
||||
if ($validator->fails()) {
|
||||
// \Log::error($validator->errors());
|
||||
throw new MigrationValidatorFailed($validator->errors());
|
||||
throw new MigrationValidatorFailed(json_encode($validator->errors()));
|
||||
}
|
||||
|
||||
if (isset($data['account_id']))
|
||||
@ -185,7 +190,7 @@ class Import implements ShouldQueue
|
||||
$validator = Validator::make($data, $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
throw new MigrationValidatorFailed($validator->errors());
|
||||
throw new MigrationValidatorFailed(json_encode($validator->errors()));
|
||||
}
|
||||
|
||||
foreach ($data as $resource) {
|
||||
@ -231,7 +236,7 @@ class Import implements ShouldQueue
|
||||
$validator = Validator::make($data, $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
throw new MigrationValidatorFailed($validator->errors());
|
||||
throw new MigrationValidatorFailed(json_encode($validator->errors()));
|
||||
}
|
||||
|
||||
$user_repository = new UserRepository();
|
||||
@ -324,7 +329,7 @@ class Import implements ShouldQueue
|
||||
$validator = Validator::make($data, $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
throw new MigrationValidatorFailed($validator->errors());
|
||||
throw new MigrationValidatorFailed(json_encode($validator->errors()));
|
||||
}
|
||||
|
||||
$product_repository = new ProductRepository();
|
||||
@ -358,7 +363,7 @@ class Import implements ShouldQueue
|
||||
$validator = Validator::make($data, $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
throw new MigrationValidatorFailed($validator->errors());
|
||||
throw new MigrationValidatorFailed(json_encode($validator->errors()));
|
||||
}
|
||||
|
||||
$invoice_repository = new InvoiceRepository();
|
||||
@ -368,7 +373,7 @@ class Import implements ShouldQueue
|
||||
$modified = $resource;
|
||||
|
||||
if (array_key_exists('client_id', $resource) && !array_key_exists('clients', $this->ids)) {
|
||||
throw new ResourceDependencyMissing(array_key_first($data), 'clients');
|
||||
throw new ResourceDependencyMissing('Processing invoices failed, because of missing dependency - clients.');
|
||||
}
|
||||
|
||||
$modified['client_id'] = $this->transformId('clients', $resource['client_id']);
|
||||
@ -405,7 +410,7 @@ class Import implements ShouldQueue
|
||||
$validator = Validator::make($data, $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
throw new MigrationValidatorFailed($validator->errors());
|
||||
throw new MigrationValidatorFailed(json_encode($validator->errors()));
|
||||
}
|
||||
|
||||
$credit_repository = new CreditRepository();
|
||||
@ -415,7 +420,7 @@ class Import implements ShouldQueue
|
||||
$modified = $resource;
|
||||
|
||||
if (array_key_exists('client_id', $resource) && !array_key_exists('clients', $this->ids)) {
|
||||
throw new ResourceDependencyMissing(array_key_first($data), 'clients');
|
||||
throw new ResourceDependencyMissing('Processing credits failed, because of missing dependency - clients.');
|
||||
}
|
||||
|
||||
$modified['client_id'] = $this->transformId('clients', $resource['client_id']);
|
||||
@ -451,7 +456,7 @@ class Import implements ShouldQueue
|
||||
$validator = Validator::make($data, $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
throw new MigrationValidatorFailed($validator->errors());
|
||||
throw new MigrationValidatorFailed(json_encode($validator->errors()));
|
||||
}
|
||||
|
||||
$quote_repository = new QuoteRepository();
|
||||
@ -461,7 +466,7 @@ class Import implements ShouldQueue
|
||||
$modified = $resource;
|
||||
|
||||
if (array_key_exists('client_id', $resource) && !array_key_exists('clients', $this->ids)) {
|
||||
throw new ResourceDependencyMissing(array_key_first($data), 'clients');
|
||||
throw new ResourceDependencyMissing('Processing quotes failed, because of missing dependency - clients.');
|
||||
}
|
||||
|
||||
$modified['client_id'] = $this->transformId('clients', $resource['client_id']);
|
||||
@ -502,7 +507,7 @@ class Import implements ShouldQueue
|
||||
$validator = Validator::make($data, $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
throw new MigrationValidatorFailed($validator->errors());
|
||||
throw new MigrationValidatorFailed(json_encode($validator->errors()));
|
||||
}
|
||||
|
||||
$payment_repository = new PaymentRepository(new CreditRepository());
|
||||
@ -512,7 +517,7 @@ class Import implements ShouldQueue
|
||||
$modified = $resource;
|
||||
|
||||
if (array_key_exists('client_id', $resource) && !array_key_exists('clients', $this->ids)) {
|
||||
throw new ResourceDependencyMissing(array_key_first($data), 'clients');
|
||||
throw new ResourceDependencyMissing('Processing payments failed, because of missing dependency - clients.');
|
||||
}
|
||||
|
||||
$modified['client_id'] = $this->transformId('clients', $resource['client_id']);
|
||||
@ -557,11 +562,11 @@ class Import implements ShouldQueue
|
||||
$modified = $resource;
|
||||
|
||||
if (array_key_exists('invoice_id', $resource) && $resource['invoice_id'] && !array_key_exists('invoices', $this->ids)) {
|
||||
throw new ResourceDependencyMissing(array_key_first($data), 'invoices');
|
||||
throw new ResourceDependencyMissing('Processing documents failed, because of missing dependency - invoices.');
|
||||
}
|
||||
|
||||
if (array_key_exists('expense_id', $resource) && $resource['expense_id'] && !array_key_exists('expenses', $this->ids)) {
|
||||
throw new ResourceDependencyMissing(array_key_first($data), 'expenses');
|
||||
throw new ResourceDependencyMissing('Processing documents failed, because of missing dependency - expenses.');
|
||||
}
|
||||
|
||||
/** Remove because of polymorphic joins. */
|
||||
@ -611,7 +616,7 @@ class Import implements ShouldQueue
|
||||
$validator = Validator::make($data, $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
throw new MigrationValidatorFailed($validator->errors());
|
||||
throw new MigrationValidatorFailed(json_encode($validator->errors()));
|
||||
}
|
||||
|
||||
foreach ($data as $resource) {
|
||||
|
@ -63,7 +63,7 @@ class StartMigration implements ShouldQueue
|
||||
auth()->login($this->user, false);
|
||||
|
||||
auth()->user()->setCompany($this->company);
|
||||
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
$archive = $zip->open($this->filepath);
|
||||
|
||||
@ -71,7 +71,7 @@ class StartMigration implements ShouldQueue
|
||||
|
||||
try {
|
||||
if (!$archive)
|
||||
throw new ProcessingMigrationArchiveFailed();
|
||||
throw new ProcessingMigrationArchiveFailed('Processing migration archive failed. Migration file is possibly corrupted.');
|
||||
|
||||
$zip->extractTo(storage_path("migrations/{$filename}"));
|
||||
$zip->close();
|
||||
@ -81,10 +81,9 @@ class StartMigration implements ShouldQueue
|
||||
|
||||
$this->start($filename);
|
||||
} catch (NonExistingMigrationFile | ProcessingMigrationArchiveFailed | ResourceNotAvailableForMigration | MigrationValidatorFailed | ResourceDependencyMissing $e) {
|
||||
Mail::to($this->user)
|
||||
->send(new MigrationFailed($e, $e->getMessage()));
|
||||
|
||||
if(app()->environment() !== 'production') info($e->getMessage());
|
||||
Mail::to($this->user)->send(new MigrationFailed($e, $e->getMessage()));
|
||||
|
||||
if (app()->environment() !== 'production') info($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,7 +97,7 @@ class StartMigration implements ShouldQueue
|
||||
$file = storage_path("migrations/$filename/migration.json");
|
||||
|
||||
if (!file_exists($file))
|
||||
throw new NonExistingMigrationFile();
|
||||
throw new NonExistingMigrationFile('Migration file does not exist, or it is corrupted.');
|
||||
|
||||
$handle = fopen($file, "r");
|
||||
$file = fread($handle, filesize($file));
|
||||
|
@ -11,18 +11,17 @@ class MigrationFailed extends Mailable
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
public $exception;
|
||||
public $message;
|
||||
public $content;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @param $message
|
||||
* @param $content
|
||||
* @param $exception
|
||||
*/
|
||||
public function __construct($exception, $message = null)
|
||||
public function __construct($exception, $content = null)
|
||||
{
|
||||
$this->exception = $exception;
|
||||
$this->message = 'Oops, looks like something went wrong with your migration. Please try again, later.';
|
||||
}
|
||||
|
||||
/**
|
||||
|
36
database/migrations/2020_03_05_123315_create_jobs_table.php
Normal file
36
database/migrations/2020_03_05_123315_create_jobs_table.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateJobsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('jobs', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->string('queue')->index();
|
||||
$table->longText('payload');
|
||||
$table->unsignedTinyInteger('attempts');
|
||||
$table->unsignedInteger('reserved_at')->nullable();
|
||||
$table->unsignedInteger('available_at');
|
||||
$table->unsignedInteger('created_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('jobs');
|
||||
}
|
||||
}
|
@ -2,6 +2,6 @@ Whoops!
|
||||
Looks like your migration failed.
|
||||
|
||||
<pre>
|
||||
{!! $exception->report() !!}
|
||||
{!! $message !!}
|
||||
{!! $exception->getMessage() !!}
|
||||
{!! $content !!}
|
||||
</pre>
|
||||
|
@ -504,4 +504,21 @@ class ImportTest extends TestCase
|
||||
|
||||
$this->assertTrue(true, 'Documents importing not completed yet. Missing expenses.');
|
||||
}
|
||||
|
||||
public function testExceptionMailSending()
|
||||
{
|
||||
Mail::fake();
|
||||
|
||||
$data['panda_bears'] = [
|
||||
'name' => 'Awesome Panda Bear',
|
||||
];
|
||||
|
||||
try {
|
||||
Import::dispatchNow($data, $this->company, $this->user);
|
||||
}
|
||||
catch (ResourceNotAvailableForMigration $e) {
|
||||
Mail::to($this->user)->send(new MigrationFailed($e, $e->getMessage()));
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user