Include Horizon (#3519)

* Fixes for white label

* Include Laravel Horizon

* Add Account ID to user table AND ensure a user cannot create an invoice across companies

* restart horison after an update

* Fixes for app setup

* Minor fixes

* Fixes for client routes

* Fixes for tests

* minor fixes
This commit is contained in:
David Bomba 2020-03-24 20:15:30 +11:00 committed by GitHub
parent 374a44aa55
commit cdc3ef12c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 105 additions and 48 deletions

View File

@ -54,12 +54,19 @@ class ArtisanUpgrade extends Command
\Log::error("I wasn't able to optimize.");
}
try {
Artisan::call('queue:restart');
} catch (Exception $e) {
\Log::error("I wasn't able to restart the queue");
}
// try {
// Artisan::call('queue:restart');
// } catch (Exception $e) {
// \Log::error("I wasn't able to restart the queue");
// }
try {
/* Restart Horizon */
Artisan::call('horizon:terminate');
Artisan::call('horizon');
} catch (Exception $e) {
\Log::error("I wasn't able to start horizon");
}
putenv('COMPOSER_HOME=' . __DIR__ . '/vendor/bin/composer');
$input = new ArrayInput(array('command' => 'install'));

View File

@ -96,7 +96,7 @@ class CreateTestData extends Command
if (!$user) {
$user = factory(\App\Models\User::class)->create([
// 'account_id' => $account->id,
'account_id' => $account->id,
'email' => 'small@example.com',
'confirmation_code' => $this->createDbHash(config('database.default'))
]);
@ -177,7 +177,7 @@ class CreateTestData extends Command
if (!$user) {
$user = factory(\App\Models\User::class)->create([
// 'account_id' => $account->id,
'account_id' => $account->id,
'email' => 'medium@example.com',
'confirmation_code' => $this->createDbHash(config('database.default'))
]);
@ -283,7 +283,7 @@ class CreateTestData extends Command
if (!$user) {
$user = factory(\App\Models\User::class)->create([
// 'account_id' => $account->id,
'account_id' => $account->id,
'email' => 'large@example.com',
'confirmation_code' => $this->createDbHash(config('database.default'))
]);

View File

@ -66,14 +66,15 @@ class ImportMigrations extends Command
public function getUser(): User
{
$account = $this->getAccount();
$company = $this->getCompany($account);
$user = factory(\App\Models\User::class)->create([
'account_id' => $account->id,
'email' => $this->faker->email,
'confirmation_code' => $this->createDbHash(config('database.default'))
]);
$account = $this->getAccount();
$company = $this->getCompany($account);
$company_token = CompanyToken::create([
'user_id' => $user->id,
'company_id' => $company->id,

View File

@ -72,14 +72,17 @@ class SendTestEmails extends Command
if (!$user) {
$account = factory(\App\Models\Account::class)->create();
$user = factory(\App\Models\User::class)->create([
'account_id' => $account->id,
'confirmation_code' => '123',
'email' => $faker->safeEmail,
'first_name' => 'John',
'last_name' => 'Doe',
]);
$account = factory(\App\Models\Account::class)->create();
$company = factory(\App\Models\Company::class)->create([

View File

@ -34,7 +34,7 @@ class CompanyFactory
//$company->custom_fields = (object) ['invoice1' => '1', 'invoice2' => '2', 'client1'=>'3'];
$company->custom_fields = (object) [];
$company->subdomain = '';
$company->enabled_modules = 4096;
$company->enabled_modules = 4095;
return $company;
}

View File

@ -15,10 +15,11 @@ use App\Models\User;
class UserFactory
{
public static function create() :User
public static function create(int $account_id) :User
{
$user = new User;
$user->account_id = $account_id;
$user->first_name = '';
$user->last_name = '';
$user->phone = '';

View File

@ -75,6 +75,8 @@ class InvoiceController extends Controller
*/
public function show(ShowInvoiceRequest $request, Invoice $invoice)
{
set_time_limit(0);
$data = [
'invoice' => $invoice,
];
@ -133,7 +135,7 @@ class InvoiceController extends Controller
'invoices' => $invoices,
'formatted_total' => $formatted_total,
'payment_methods' => $payment_methods,
'hashed_ids' => $invoices->pluck('hashed_ids'),
'hashed_ids' => $invoices->pluck('hashed_id'),
'total' => $total,
];

View File

@ -134,7 +134,7 @@ class LicenseController extends BaseController
}
$error = [
'message' => "Invalid license, or invalid environment ".config('ninja.environment')s,
'message' => "Invalid license, or invalid environment ".config('ninja.environment'),
'errors' => []
];

View File

@ -24,9 +24,14 @@ class SetupController extends Controller
{
public function index()
{
$system_health = SystemHealth::check();
if($system_health)
return redirect('/');
return view();
}
public function doSetup(StoreSetupRequest $request)
@ -76,6 +81,7 @@ class SetupController extends Controller
Artisan::call('optimize');
Artisan::call('migrate');
Artisan::call('db:seed');
Artisan::call('horizon');
if (Account::count() == 0) {
$account = CreateAccount::dispatchNow($request->all());

View File

@ -349,7 +349,7 @@ class UserController extends BaseController
* ),
* ),
* @OA\Response(
* response=200,
f * response=200,
* description="Returns the User object",
* @OA\Header(header="X-API-Version", ref="#/components/headers/X-API-Version"),
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),

View File

@ -36,9 +36,7 @@ class StoreInvoiceRequest extends Request
public function rules()
{
return [
'client_id' => 'required|exists:clients,id',
// 'invoice_type_id' => 'integer',
// 'documents' => 'mimes:png,ai,svg,jpeg,tiff,pdf,gif,psd,txt,doc,xls,ppt,xlsx,docx,pptx',
'client_id' => 'required|exists:clients,id,company_id,'.auth()->user()->company()->id,
];
}

View File

@ -56,6 +56,7 @@ class CreateUser
public function handle() : ?User
{
$user = new User();
$user->account_id = $this->account->id;
$user->password = bcrypt($this->request['password']);
$user->accepted_terms_version = config('ninja.terms_version');
$user->confirmation_code = $this->createDbHash(config('database.default'));

View File

@ -88,6 +88,11 @@ class Account extends BaseModel
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function users()
{
return $this->hasMany(User::class)->withTrashed();
}
public function default_company()
{
return $this->hasOne(Company::class, 'id', 'default_company_id');

View File

@ -27,6 +27,7 @@ use App\Events\Payment\PaymentWasRefunded;
use App\Events\Payment\PaymentWasVoided;
use App\Events\User\UserLoggedIn;
use App\Events\User\UserWasCreated;
use App\Events\User\UserWasDeleted;
use App\Listeners\Activity\CreatedClientActivity;
use App\Listeners\Activity\PaymentCreatedActivity;
use App\Listeners\Activity\PaymentDeletedActivity;
@ -47,6 +48,7 @@ use App\Listeners\Misc\InvitationViewedListener;
use App\Listeners\Payment\PaymentNotification;
use App\Listeners\SendVerificationNotification;
use App\Listeners\SetDBListener;
use App\Listeners\User\DeletedUserActivity;
use App\Listeners\User\UpdateUserLastLogin;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
@ -67,6 +69,9 @@ class EventServiceProvider extends ServiceProvider
UserWasCreated::class => [
SendVerificationNotification::class,
],
UserWasDeleted::class => [
DeletedUserActivity::class,
],
UserLoggedIn::class => [
UpdateUserLastLogin::class,
],

View File

@ -12,6 +12,7 @@
namespace App\Repositories;
use App\DataMapper\CompanySettings;
use App\Events\User\UserWasDeleted;
use App\Factory\CompanyUserFactory;
use App\Models\CompanyUser;
use App\Models\User;
@ -46,12 +47,16 @@ class UserRepository extends BaseRepository
*/
public function save(array $data, User $user)
{
$company = auth()->user()->company();
$account_id = $company->account->id;
$user->fill($data);
$user->account_id = $account_id;
$user->save();
if (isset($data['company_user'])) {
$company = auth()->user()->company();
$account_id = $company->account->id;
$cu = CompanyUser::whereUserId($user->id)->whereCompanyId($company->id)->withTrashed()->first();
@ -61,6 +66,7 @@ class UserRepository extends BaseRepository
$data['company_user']['notifications'] = CompanySettings::notificationDefaults();
$user->companies()->attach($company->id, $data['company_user']);
} else {
$cu->fill($data['company_user']);
$cu->restore();
$cu->tokens()->restore();
@ -71,7 +77,9 @@ class UserRepository extends BaseRepository
$query->whereCompanyId($company->id)
->whereUserId($user->id);
}])->first();
//return $user->with('company_user')->whereCompanyId($company->id)->first();
$user->restore();
}
return $user;
@ -80,6 +88,7 @@ class UserRepository extends BaseRepository
public function destroy(array $data, User $user)
{
if (array_key_exists('company_user', $data)) {
$this->forced_includes = 'company_users';
$company = auth()->user()->company();
@ -94,9 +103,15 @@ class UserRepository extends BaseRepository
$user->delete();
event(new UserWasDeleted($user, $company));
return $user->fresh();
}
/*
* Soft deletes the user and the company user
*/
public function delete($user)
{
$company = auth()->user()->company();
@ -114,6 +129,8 @@ class UserRepository extends BaseRepository
$user->save();
$user->delete();
event(new UserWasDeleted($user, $company));
return $user->fresh();
}
}

View File

@ -26,7 +26,10 @@ class SystemHealth
'gd',
'curl',
'zip',
'gmp'
'gmp',
'openssl',
'mbstring',
'xml'
];
private static $php_version = 7.3;

View File

@ -22,6 +22,8 @@ trait AppSetup
return true;
}
\Log::error(SystemHealth::check());
return SystemHealth::check()['system_health']; // Do the system tests pass?
}
}

View File

@ -196,10 +196,10 @@ trait MakesInvoiceValues
$data['$taxes'] = ['value' => Number::formatMoney($this->calc()->getItemTotalTaxes(), $this->client) ?: ' ', 'label' => ctrans('texts.taxes')];
$data['$invoice.taxes'] = &$data['$taxes'];
$data['$invoice1'] = ['value' => $this->custom_value1 ?: ' ', 'label' => $this->makeCustomField('invoice1')];
$data['$invoice2'] = ['value' => $this->custom_value2 ?: ' ', 'label' => $this->makeCustomField('invoice2')];
$data['$invoice3'] = ['value' => $this->custom_value3 ?: ' ', 'label' => $this->makeCustomField('invoice3')];
$data['$invoice4'] = ['value' => $this->custom_value4 ?: ' ', 'label' => $this->makeCustomField('invoice4')];
$data['$invoice.custom1'] = ['value' => $this->custom_value1 ?: ' ', 'label' => $this->makeCustomField('invoice1')];
$data['$invoice.custom2'] = ['value' => $this->custom_value2 ?: ' ', 'label' => $this->makeCustomField('invoice2')];
$data['$invoice.custom3'] = ['value' => $this->custom_value3 ?: ' ', 'label' => $this->makeCustomField('invoice3')];
$data['$invoice.custom4'] = ['value' => $this->custom_value4 ?: ' ', 'label' => $this->makeCustomField('invoice4')];
$data['$invoice.public_notes'] = ['value' => $this->public_notes ?: ' ', 'label' => ctrans('texts.public_notes')];
$data['$entity.public_notes'] = &$data['$invoice.public_notes'];

View File

@ -127,7 +127,7 @@ return [
|
*/
'memory_limit' => 256,
'memory_limit' => 512,
/*
|--------------------------------------------------------------------------
@ -146,7 +146,7 @@ return [
'connection' => 'redis',
'queue' => ['default'],
'balance' => 'simple',
'processes' => 10,
'processes' => 8,
'tries' => 1,
],
],

View File

@ -244,6 +244,7 @@ class CreateUsersTable extends Migration
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('account_id')->index();
$table->string('first_name')->nullable();
$table->string('last_name')->nullable();
$table->string('phone')->nullable();
@ -280,7 +281,7 @@ class CreateUsersTable extends Migration
$table->unique(['oauth_user_id', 'oauth_provider_id']);
// $table->foreign('user_id')->references('user_id')->on('company_users')->onDelete('cascade');
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade')->onUpdate('cascade');
});

View File

@ -82,7 +82,7 @@ class RandomDataSeeder extends Seeder
$user = factory(\App\Models\User::class)->create([
'email' => $faker->email,
// 'account_id' => $account->id,
'account_id' => $account->id,
'confirmation_code' => $this->createDbHash(config('database.default'))
]);

View File

@ -35,6 +35,7 @@ class UsersTableSeeder extends Seeder
$account->save();
$user = factory(\App\Models\User::class)->create([
'account_id' => $account->id,
'confirmation_code' => $this->createDbHash(config('database.default'))
]);

View File

@ -10,7 +10,7 @@
@section('body')
<form action="{{ route('client.payments.process') }}" method="post" id="payment-form">
@csrf
<input type="hidden" name="hashed_ids" value="{{ $hashed_ids }}" id="hashed_ids">
<input type="hidden" name="hashed_ids" value="{!! $hashed_ids !!}" id="hashed_ids">
<input type="hidden" name="company_gateway_id" id="company_gateway_id">
<input type="hidden" name="payment_method_id" id="payment_method_id">
</form>
@ -51,6 +51,7 @@
</div>
</div>
</div>
@foreach($invoices as $invoice)
<div class="bg-white shadow overflow-hidden sm:rounded-lg mb-4">
<div class="px-4 py-5 border-b border-gray-200 sm:px-6">

View File

@ -26,9 +26,9 @@ Route::group(['middleware' => ['auth:contact','locale'], 'prefix' => 'client', '
Route::get('recurring_invoices/{recurring_invoice}', 'ClientPortal\RecurringInvoiceController@show')->name('recurring_invoices.show');
Route::get('recurring_invoices/{recurring_invoice}/request_cancellation', 'ClientPortal\RecurringInvoiceController@requestCancellation')->name('recurring_invoices.request_cancellation');
Route::post('payments/process', 'ClientPortal\PaymentController@process')->name('payments.process');
Route::get('payments', 'ClientPortal\PaymentController@index')->name('payments.index')->middleware('portal_enabled');
Route::get('payments/{payment}', 'ClientPortal\PaymentController@show')->name('payments.show');
Route::post('payments/process', 'ClientPortal\PaymentController@process')->name('payments.process');
Route::post('payments/process/response', 'ClientPortal\PaymentController@response')->name('payments.response');
Route::get('payments/process/response', 'ClientPortal\PaymentController@response')->name('payments.response.get');

View File

@ -47,7 +47,7 @@ class ClientPortalTest extends DuskTestCase
$user = factory(\App\Models\User::class)->create([
'email' => $faker->email,
// 'account_id' => $account->id,
'account_id' => $account->id,
'confirmation_code' => $this->createDbHash(config('database.default'))
]);

View File

@ -215,7 +215,7 @@ class ClientTest extends TestCase
$account->save();
$user = factory(\App\Models\User::class)->create([
// 'account_id' => $account->id,
'account_id' => $account->id,
'confirmation_code' => $this->createDbHash(config('database.default'))
]);
@ -282,7 +282,7 @@ class ClientTest extends TestCase
$account->save();
$user = factory(\App\Models\User::class)->create([
// 'account_id' => $account->id,
'account_id' => $account->id,
'confirmation_code' => $this->createDbHash(config('database.default'))
]);

View File

@ -57,7 +57,7 @@ class InvitationTest extends TestCase
$account->save();
$user = factory(\App\Models\User::class)->create([
// 'account_id' => $account->id,
'account_id' => $account->id,
'confirmation_code' => $this->createDbHash(config('database.default'))
]);

View File

@ -133,7 +133,7 @@ class LoginTest extends TestCase
{
$account = factory(Account::class)->create();
$user = factory(User::class)->create([
// 'account_id' => $account->id,
'account_id' => $account->id,
'email' => 'test@example.com',
'password' => \Hash::make('123456')
]);

View File

@ -102,6 +102,7 @@ class CompanyLedgerTest extends TestCase
if (!$this->user) {
$this->user = factory(\App\Models\User::class)->create([
'account_id' => $this->account->id,
'password' => Hash::make('ALongAndBriliantPassword'),
'confirmation_code' => $this->createDbHash(config('database.default'))
]);

View File

@ -49,7 +49,7 @@ class DesignTest extends TestCase
{
$this->contact = $this->invoice->client->primary_contact()->first();
$design = Design::find(3);
$design = json_decode(Design::find(3));
$designer = new Designer($this->invoice, $design, $this->company->settings->pdf_variables, 'quote');
@ -57,7 +57,6 @@ class DesignTest extends TestCase
$this->assertNotNull($html);
$this->invoice = factory(\App\Models\Invoice::class)->create([
'user_id' => $this->user->id,
'client_id' => $this->client->id,
@ -79,7 +78,7 @@ class DesignTest extends TestCase
{
$this->contact = $this->quote->client->primary_contact()->first();
$design = Design::find(3);
$design = json_decode(Design::find(3));
$designer = new Designer($this->quote, $design, $this->company->settings->pdf_variables, 'quote');
@ -108,7 +107,7 @@ class DesignTest extends TestCase
public function testCreditDesignExists()
{
$design = Design::find(3);
$design = json_decode(Design::find(3));
$designer = new Designer($this->credit, $design, $this->company->settings->pdf_variables, 'credit');

View File

@ -58,6 +58,7 @@ class MultiDBUserTest extends TestCase
Company::on('db-ninja-02')->create($company2->toArray());
$user = [
'account_id' => $account->id,
'first_name' => 'user_db_1',
'last_name' => 'user_db_1-s',
'phone' => '55555',
@ -71,6 +72,7 @@ class MultiDBUserTest extends TestCase
$user2 = [
'account_id' => $account2->id,
'first_name' => 'user_db_2',
'last_name' => 'user_db_2-s',
'phone' => '55555',

View File

@ -63,14 +63,14 @@ class UniqueEmailTest extends TestCase
'first_name' => 'user_db_1',
'email' => 'user@example.com',
'password' => Hash::make('password'),
// 'account_id' => $account->id,
'account_id' => $account->id,
];
$user2 = [
'first_name' => 'user_db_2',
'email' => 'user@example.com',
'password' => Hash::make('password'),
// 'account_id' => $account2->id,
'account_id' => $account2->id,
];
User::on('db-ninja-01')->create($user);

View File

@ -119,6 +119,7 @@ trait MockAccountData
if (!$this->user) {
$this->user = factory(\App\Models\User::class)->create([
'account_id' => $this->account->id,
'password' => Hash::make('ALongAndBriliantPassword'),
'confirmation_code' => $this->createDbHash(config('database.default'))
]);

View File

@ -136,7 +136,7 @@ class FactoryCreationTest extends TestCase
*/
public function testUserCreate()
{
$new_user = UserFactory::create();
$new_user = UserFactory::create($this->account->id);
$new_user->email = $this->faker->email;
$new_user->save();

View File

@ -24,7 +24,7 @@ class PrimaryKeyTransformationTest extends TestCase
public function testTransformationArray()
{
$keys = [
'gl9avZgaG1', '7LDdwrmb1Y'
$this->encodePrimaryKey(310), $this->encodePrimaryKey(311)
];
$transformed_keys = $this->transformKeys($keys);
@ -36,7 +36,7 @@ class PrimaryKeyTransformationTest extends TestCase
public function testTransformation()
{
$keys = 'gl9avZgaG1';
$keys = $this->encodePrimaryKey(310);
$this->assertEquals(310, $this->transformKeys($keys));
}