Merge pull request #822 from joshuadwire/enterprise-plan

Improve enterprise plan migration
This commit is contained in:
Hillel Coren 2016-04-20 19:42:46 +03:00
commit 6711678fbe

View File

@ -13,36 +13,45 @@ class EnterprisePlan extends Migration
* @return void * @return void
*/ */
public function up() { public function up() {
$timeout = ini_get('max_execution_time');
if ($timeout == 0) {
$timeout = 600;
}
$timeout = max($timeout - 10, $timeout * .9);
$startTime = time();
Schema::create('companies', function($table) if (!Schema::hasTable('companies')) {
{ Schema::create('companies', function($table)
$table->increments('id'); {
$table->increments('id');
$table->enum('plan', array('pro', 'enterprise', 'white_label'))->nullable();
$table->enum('plan_term', array('month', 'year'))->nullable(); $table->enum('plan', array('pro', 'enterprise', 'white_label'))->nullable();
$table->date('plan_started')->nullable(); $table->enum('plan_term', array('month', 'year'))->nullable();
$table->date('plan_paid')->nullable(); $table->date('plan_started')->nullable();
$table->date('plan_expires')->nullable(); $table->date('plan_paid')->nullable();
$table->date('plan_expires')->nullable();
$table->unsignedInteger('payment_id')->nullable();
$table->foreign('payment_id')->references('id')->on('payments'); $table->unsignedInteger('payment_id')->nullable();
$table->foreign('payment_id')->references('id')->on('payments');
$table->date('trial_started')->nullable();
$table->enum('trial_plan', array('pro', 'enterprise'))->nullable(); $table->date('trial_started')->nullable();
$table->enum('trial_plan', array('pro', 'enterprise'))->nullable();
$table->enum('pending_plan', array('pro', 'enterprise', 'free'))->nullable();
$table->enum('pending_term', array('month', 'year'))->nullable(); $table->enum('pending_plan', array('pro', 'enterprise', 'free'))->nullable();
$table->enum('pending_term', array('month', 'year'))->nullable();
$table->timestamps();
$table->softDeletes(); $table->timestamps();
}); $table->softDeletes();
});
Schema::table('accounts', function($table) }
{
$table->unsignedInteger('company_id')->nullable();
$table->foreign('company_id')->references('id')->on('companies');
});
if (!Schema::hasColumn('accounts', 'company_id')) {
Schema::table('accounts', function($table)
{
$table->unsignedInteger('company_id')->nullable();
$table->foreign('company_id')->references('id')->on('companies');
});
}
$single_account_ids = \DB::table('users') $single_account_ids = \DB::table('users')
->leftJoin('user_accounts', function ($join) { ->leftJoin('user_accounts', function ($join) {
@ -52,34 +61,54 @@ class EnterprisePlan extends Migration
$join->orOn('user_accounts.user_id4', '=', 'users.id'); $join->orOn('user_accounts.user_id4', '=', 'users.id');
$join->orOn('user_accounts.user_id5', '=', 'users.id'); $join->orOn('user_accounts.user_id5', '=', 'users.id');
}) })
->leftJoin('accounts', 'accounts.id', '=', 'users.account_id')
->whereNull('user_accounts.id') ->whereNull('user_accounts.id')
->whereNull('accounts.company_id')
->where(function ($query) { ->where(function ($query) {
$query->whereNull('users.public_id'); $query->whereNull('users.public_id');
$query->orWhere('users.public_id', '=', 0); $query->orWhere('users.public_id', '=', 0);
}) })
->lists('users.account_id'); ->lists('users.account_id');
if (count($single_account_ids)) {
foreach (Account::find($single_account_ids) as $account) {
$this->upAccounts($account);
$this->checkTimeout($timeout, $startTime);
}
}
$group_accounts = \DB::select( $group_accounts = \DB::select(
'SELECT u1.account_id as account1, u2.account_id as account2, u3.account_id as account3, u4.account_id as account4, u5.account_id as account5 FROM `user_accounts` 'SELECT u1.account_id as account1, u2.account_id as account2, u3.account_id as account3, u4.account_id as account4, u5.account_id as account5 FROM `user_accounts`
LEFT JOIN users u1 ON (u1.public_id IS NULL OR u1.public_id = 0) AND user_accounts.user_id1 = u1.id LEFT JOIN users u1 ON (u1.public_id IS NULL OR u1.public_id = 0) AND user_accounts.user_id1 = u1.id
LEFT JOIN users u2 ON (u2.public_id IS NULL OR u2.public_id = 0) AND user_accounts.user_id2 = u2.id LEFT JOIN users u2 ON (u2.public_id IS NULL OR u2.public_id = 0) AND user_accounts.user_id2 = u2.id
LEFT JOIN users u3 ON (u3.public_id IS NULL OR u3.public_id = 0) AND user_accounts.user_id3 = u3.id LEFT JOIN users u3 ON (u3.public_id IS NULL OR u3.public_id = 0) AND user_accounts.user_id3 = u3.id
LEFT JOIN users u4 ON (u4.public_id IS NULL OR u4.public_id = 0) AND user_accounts.user_id4 = u4.id LEFT JOIN users u4 ON (u4.public_id IS NULL OR u4.public_id = 0) AND user_accounts.user_id4 = u4.id
LEFT JOIN users u5 ON (u5.public_id IS NULL OR u5.public_id = 0) AND user_accounts.user_id5 = u5.id'); LEFT JOIN users u5 ON (u5.public_id IS NULL OR u5.public_id = 0) AND user_accounts.user_id5 = u5.id
LEFT JOIN accounts a1 ON a1.id = u1.account_id
foreach (Account::find($single_account_ids) as $account) { LEFT JOIN accounts a2 ON a2.id = u2.account_id
$this->upAccounts($account); LEFT JOIN accounts a3 ON a3.id = u3.account_id
LEFT JOIN accounts a4 ON a4.id = u4.account_id
LEFT JOIN accounts a5 ON a5.id = u5.account_id
WHERE (a1.id IS NOT NULL AND a1.company_id IS NULL)
OR (a2.id IS NOT NULL AND a2.company_id IS NULL)
OR (a3.id IS NOT NULL AND a3.company_id IS NULL)
OR (a4.id IS NOT NULL AND a4.company_id IS NULL)
OR (a5.id IS NOT NULL AND a5.company_id IS NULL)');
if (count($group_accounts)) {
foreach ($group_accounts as $group_account) {
$this->upAccounts(null, Account::find(get_object_vars($group_account)));
$this->checkTimeout($timeout, $startTime);
}
} }
foreach ($group_accounts as $group_account) { if (Schema::hasColumn('accounts', 'pro_plan_paid')) {
$this->upAccounts(null, Account::find(get_object_vars($group_account))); Schema::table('accounts', function($table)
{
$table->dropColumn('pro_plan_paid');
$table->dropColumn('pro_plan_trial');
});
} }
Schema::table('accounts', function($table)
{
$table->dropColumn('pro_plan_paid');
$table->dropColumn('pro_plan_trial');
});
} }
private function upAccounts($primaryAccount, $otherAccounts = array()) { private function upAccounts($primaryAccount, $otherAccounts = array()) {
@ -87,6 +116,10 @@ LEFT JOIN users u5 ON (u5.public_id IS NULL OR u5.public_id = 0) AND user_accoun
$primaryAccount = $otherAccounts->first(); $primaryAccount = $otherAccounts->first();
} }
if (empty($primaryAccount)) {
return;
}
$company = Company::create(); $company = Company::create();
if ($primaryAccount->pro_plan_paid && $primaryAccount->pro_plan_paid != '0000-00-00') { if ($primaryAccount->pro_plan_paid && $primaryAccount->pro_plan_paid != '0000-00-00') {
$company->plan = 'pro'; $company->plan = 'pro';
@ -124,6 +157,12 @@ LEFT JOIN users u5 ON (u5.public_id IS NULL OR u5.public_id = 0) AND user_accoun
} }
} }
protected function checkTimeout($timeout, $startTime) {
if (time() - $startTime >= $timeout) {
exit('Migration reached time limit; please run again to continue');
}
}
/** /**
* Reverse the migrations. * Reverse the migrations.
* *
@ -131,25 +170,51 @@ LEFT JOIN users u5 ON (u5.public_id IS NULL OR u5.public_id = 0) AND user_accoun
*/ */
public function down() public function down()
{ {
Schema::table('accounts', function($table) $timeout = ini_get('max_execution_time');
{ if ($timeout == 0) {
$table->date('pro_plan_paid')->nullable(); $timeout = 600;
$table->date('pro_plan_trial')->nullable(); }
}); $timeout = max($timeout - 10, $timeout * .9);
$startTime = time();
foreach (Company::all() as $company) { if (!Schema::hasColumn('accounts', 'pro_plan_paid')) {
foreach ($company->accounts as $account) { Schema::table('accounts', function($table)
$account->pro_plan_paid = $company->plan_paid; {
$account->pro_plan_trial = $company->trial_started; $table->date('pro_plan_paid')->nullable();
$account->save(); $table->date('pro_plan_trial')->nullable();
});
}
$company_ids = \DB::table('companies')
->leftJoin('accounts', 'accounts.company_id', '=', 'companies.id')
->whereNull('accounts.pro_plan_paid')
->whereNull('accounts.pro_plan_trial')
->where(function ($query) {
$query->whereNotNull('companies.plan_paid');
$query->orWhereNotNull('companies.trial_started');
})
->lists('companies.id');
$company_ids = array_unique($company_ids);
if (count($company_ids)) {
foreach (Company::find($company_ids) as $company) {
foreach ($company->accounts as $account) {
$account->pro_plan_paid = $company->plan_paid;
$account->pro_plan_trial = $company->trial_started;
$account->save();
}
$this->checkTimeout($timeout, $startTime);
} }
} }
Schema::table('accounts', function($table) if (Schema::hasColumn('accounts', 'company_id')) {
{ Schema::table('accounts', function($table)
$table->dropForeign('accounts_company_id_foreign'); {
$table->dropColumn('company_id'); $table->dropForeign('accounts_company_id_foreign');
}); $table->dropColumn('company_id');
});
}
Schema::dropIfExists('companies'); Schema::dropIfExists('companies');
} }