diff --git a/app/DataMapper/CompanySettings.php b/app/DataMapper/CompanySettings.php index 669d5f306aea..440fb07eb2de 100644 --- a/app/DataMapper/CompanySettings.php +++ b/app/DataMapper/CompanySettings.php @@ -12,6 +12,7 @@ namespace App\DataMapper; use App\DataMapper\CompanySettings; +use App\DataMapper\EmailTemplateDefaults; use App\Models\Company; /** @@ -400,6 +401,9 @@ class CompanySettings extends BaseSettings $data->country_id = (string)config('ninja.i18n.country_id'); $data->translations = (object) []; + $data->email_subject_invoice = EmailTemplateDefaults::emailInvoiceSubject(); + $data->email_template_invoice = EmailTemplateDefaults:: emailInvoiceTemplate(); + return self::setCasts($data, self::$casts); } diff --git a/app/DataMapper/EmailTemplateDefaults.php b/app/DataMapper/EmailTemplateDefaults.php new file mode 100644 index 000000000000..2a1db3e6c084 --- /dev/null +++ b/app/DataMapper/EmailTemplateDefaults.php @@ -0,0 +1,32 @@ +line(self::transformText('invoice_subject')); + } + + public static function emailInvoiceTemplate() + { + return Parsedown::instance()->line(self::transformText('invoice_message')); + } + + private static function transformText($string) + { + return str_replace(":", "$", ctrans('texts.'.$string)); + } +} diff --git a/app/Filters/UserFilters.php b/app/Filters/UserFilters.php index 755e331f18a0..e8aede08ed6a 100644 --- a/app/Filters/UserFilters.php +++ b/app/Filters/UserFilters.php @@ -114,11 +114,11 @@ class UserFilters extends QueryFilters { //return $this->builder->user_companies()->whereCompanyId(auth()->user()->company()->id); //return $this->builder->whereCompanyId(auth()->user()->company()->id); - return $this->builder->whereHas('user_companies', function($q) - { - $q->where('company_id', '=', auth()->user()->company()->id); + return $this->builder->whereHas('company_users', function($q) + { + $q->where('company_id', '=', auth()->user()->company()->id); - }); + }); } } \ No newline at end of file diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index ca95b704c474..025436aff20c 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -173,7 +173,7 @@ class LoginController extends BaseController $user = $this->guard()->user(); - $user->setCompany($user->user_companies->first()->account->default_company); + $user->setCompany($user->company_user->account->default_company); $ct = CompanyUser::whereUserId($user->id); return $this->listResponse($ct); diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index a84e1dda4010..e1440e04b089 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -22,6 +22,7 @@ use App\Http\Requests\User\StoreUserRequest; use App\Http\Requests\User\UpdateUserRequest; use App\Jobs\Company\CreateCompanyToken; use App\Models\User; +use App\DataMapper\DefaultSettings; use App\Repositories\UserRepository; use App\Transformers\UserTransformer; use App\Utils\Traits\MakesHash; @@ -200,24 +201,14 @@ class UserController extends BaseController { $company = auth()->user()->company(); - //save user - $user = $this->user_repo->save($request->all(), UserFactory::create($company->id, auth()->user()->id)); + $user = $this->user_repo->save($request->all(), UserFactory::create()); - $user->companies()->attach($company->id, [ - 'account_id' => $company->account->id, - 'is_owner' => 0, - 'is_admin' => $request->input('is_admin'), - 'is_locked' => 0, - 'permissions' => $request->input('permissions'), - 'settings' => $request->input('settings'), - ]); + $user_agent = request()->input('token_name') ?: request()->server('HTTP_USER_AGENT'); - CreateCompanyToken::dispatchNow($company, $user, request()->server('HTTP_USER_AGENT')); + $ct = CreateCompanyToken::dispatchNow($company, $user, $user_agent); - $user->load('companies'); - - return $this->itemResponse($user); + return $this->itemResponse($user->fresh()); } diff --git a/app/Http/Middleware/TokenAuth.php b/app/Http/Middleware/TokenAuth.php index 27723f4437c1..abe1099cd415 100644 --- a/app/Http/Middleware/TokenAuth.php +++ b/app/Http/Middleware/TokenAuth.php @@ -52,7 +52,7 @@ class TokenAuth $user->setCompany($company_token->company); //user who once existed, but has been soft deleted - if($user->user_company()->is_locked){ + if($user->company_user->is_locked){ $error = [ 'message' => 'User access locked', diff --git a/app/Http/Requests/User/StoreUserRequest.php b/app/Http/Requests/User/StoreUserRequest.php index 515f32488f7b..5a3a3b5e638e 100644 --- a/app/Http/Requests/User/StoreUserRequest.php +++ b/app/Http/Requests/User/StoreUserRequest.php @@ -50,6 +50,8 @@ class StoreUserRequest extends Request if(isset($input['company_user'])) { + if(!isset($input['company_user']['is_admin'])) + $input['company_user']['is_admin'] = false; if(!isset($input['company_user']['permissions'])) $input['company_user']['permissions'] = ''; @@ -66,17 +68,11 @@ class StoreUserRequest extends Request } $this->replace($input); - +\Log::error($input); return $this->all(); } - public function messages() - { - return [ - 'company_user' => 'T', - ] - } } \ No newline at end of file diff --git a/app/Models/Company.php b/app/Models/Company.php index cb6b111fa875..3ce44e779893 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -46,6 +46,7 @@ class Company extends BaseModel protected $presenter = 'App\Models\Presenters\CompanyPresenter'; protected $fillable = [ + 'fill_products', 'industry_id', 'domain', 'size_id', diff --git a/app/Models/CompanyUser.php b/app/Models/CompanyUser.php index 4edc088b314e..d1856edc698e 100644 --- a/app/Models/CompanyUser.php +++ b/app/Models/CompanyUser.php @@ -15,7 +15,10 @@ use Illuminate\Database\Eloquent\Relations\Pivot; class CompanyUser extends Pivot { - protected $guarded = ['id']; + // protected $guarded = ['id']; + + protected $dateFormat = 'Y-m-d H:i:s.u'; + /** * The attributes that should be cast to native types. @@ -72,6 +75,7 @@ class CompanyUser extends Pivot { return $this->belongsTo(CompanyToken::class, 'user_id','user_id'); + /* return $this->hasOneThrough( CompanyToken::class, diff --git a/app/Models/User.php b/app/Models/User.php index 00ba47d07b27..52cc199a52a5 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -39,6 +39,7 @@ class User extends Authenticatable implements MustVerifyEmail use UserSessionAttributes; use UserSettings; use Filterable; + use \Staudenmeir\EloquentHasManyDeep\HasRelationships; protected $guard = 'user'; @@ -46,7 +47,7 @@ class User extends Authenticatable implements MustVerifyEmail protected $presenter = 'App\Models\Presenters\UserPresenter'; - protected $with = ['companies','user_companies']; + protected $with = ['companies']; protected $dateFormat = 'Y-m-d H:i:s.u'; @@ -169,52 +170,16 @@ class User extends Authenticatable implements MustVerifyEmail } - /** - * Returns the pivot tables for Company / User - * - * @return Collection - * - */ - public function user_companies() + public function company_users() { return $this->hasMany(CompanyUser::class); } - /** - * Alias of user_companies() - */ - public function company_users() - { - return $this->user_companies(); - } - - /** - * Returns the current company by - * querying directly on the pivot table relationship - * - * @return Collection - * @deprecated - */ - public function user_company() - { - - return $this->user_companies->where('company_id', $this->companyId())->first(); - - } - public function company_user() { - return $this->hasOneThrough(CompanyUser::class, CompanyToken::class, - 'user_id', // Foreign key on CompanyToken table... - 'company_id', // Foreign key on CompanyUser table... - 'id', // Local key on suppliers table... - 'company_id' // Local key on CompanyToken table... - ); - - // return $this->user_companies->where('company_id', $this->companyId()); + return $this->hasOneThrough(CompanyUser::class, CompanyToken::class, 'user_id', 'company_id','id','company_id')->where('company_user.user_id', $this->id); } - /** * Returns the currently set company id for the user * @@ -235,7 +200,7 @@ class User extends Authenticatable implements MustVerifyEmail public function permissions() { - $permissions = json_decode($this->user_company()->permissions); + $permissions = json_decode($this->company_user->permissions); if (! $permissions) return []; @@ -251,7 +216,7 @@ class User extends Authenticatable implements MustVerifyEmail public function settings() { - return json_decode($this->user_company()->settings); + return json_decode($this->company_user->settings); } @@ -263,7 +228,7 @@ class User extends Authenticatable implements MustVerifyEmail public function isAdmin() : bool { - return $this->user_company()->is_admin; + return $this->company_user->is_admin; } @@ -328,7 +293,7 @@ class User extends Authenticatable implements MustVerifyEmail { - return (stripos($this->user_company()->permissions, $permission) !== false); + return (stripos($this->company_user->permissions, $permission) !== false); // return $this->permissionsFlat()->contains($permission); diff --git a/app/Repositories/UserRepository.php b/app/Repositories/UserRepository.php index f4068d811e34..82a4db4a9d21 100644 --- a/app/Repositories/UserRepository.php +++ b/app/Repositories/UserRepository.php @@ -62,12 +62,15 @@ class UserRepository extends BaseRepository $cu = CompanyUser::whereUserId($user->id)->whereCompanyId($company->id)->first(); - if(!$cu) - $cu = CompanyUserFactory::create($user->id, $company->id, $account_id); - - $cu->fill($data['company_user']); - $cu->save(); + if(!$cu){ + //$cu = CompanyUserFactory::create($user->id, $company->id, $account_id); + $data['company_user']['account_id'] = $account_id; + + $user->companies()->attach($company->id, $data['company_user']); + + } + } return $user; diff --git a/app/Transformers/CompanyTransformer.php b/app/Transformers/CompanyTransformer.php index 8003e9abdb72..82b3a5b5a6fd 100644 --- a/app/Transformers/CompanyTransformer.php +++ b/app/Transformers/CompanyTransformer.php @@ -80,6 +80,8 @@ class CompanyTransformer extends EntityTransformer 'custom_surcharge_taxes2' => (bool)$company->custom_surcharge_taxes2, 'custom_surcharge_taxes3' => (bool)$company->custom_surcharge_taxes3, 'custom_surcharge_taxes4' => (bool)$company->custom_surcharge_taxes4, + 'show_product_cost' => (bool)$company->show_product_cost, + 'enable_invoice_quantity' => (bool)$company->enable_invoice_quantity, 'enable_product_cost' => (bool)$company->enable_product_cost, 'enable_product_quantity' => (bool)$company->enable_product_quantity, 'default_quantity' => (bool)$company->default_quantity, @@ -88,7 +90,11 @@ class CompanyTransformer extends EntityTransformer 'industry_id' => (string) $company->industry_id ?: '', 'first_month_of_year' => (string) $company->first_month_of_year ?: '', 'first_day_of_week' => (string) $company->first_day_of_week ?: '', + 'domain' => (string) $company->domain ?: '', + 'portal_mode' => (string) $company->portal_mode ?: '', + 'portal_domain' => (string) $company->portal_domain ?: '', 'settings' => $company->settings ?: '', + 'enabled_tax_rates' => (int)$company->enabled_tax_rates, 'updated_at' => (int)$company->updated_at, 'deleted_at' => (int)$company->deleted_at, ]; diff --git a/app/Transformers/CompanyUserTransformer.php b/app/Transformers/CompanyUserTransformer.php index eddd4af98cf7..7f34a1a0176f 100644 --- a/app/Transformers/CompanyUserTransformer.php +++ b/app/Transformers/CompanyUserTransformer.php @@ -46,13 +46,17 @@ class CompanyUserTransformer extends EntityTransformer public function transform(CompanyUser $company_user) { return [ + 'id' => $company_user->id, + 'account_id' => $company_user->account_id, + 'user_id' => $company_user->user_id, + 'company_id' => $company_user->company_id, 'permissions' => $company_user->permissions ?: '', 'settings' => $company_user->settings ?: '', 'is_owner' => (bool) $company_user->is_owner, 'is_admin' => (bool) $company_user->is_admin, 'is_locked' => (bool) $company_user->is_locked, - 'updated_at' => $company_user->updated_at, - 'deleted_at' => $company_user->deleted_at, + 'updated_at' => (int)$company_user->updated_at, + 'deleted_at' => (int)$company_user->deleted_at, ]; } diff --git a/app/Transformers/UserTransformer.php b/app/Transformers/UserTransformer.php index e17260ab3af4..e796bdbb47be 100644 --- a/app/Transformers/UserTransformer.php +++ b/app/Transformers/UserTransformer.php @@ -93,7 +93,7 @@ class UserTransformer extends EntityTransformer $transformer = new CompanyUserTransformer($this->serializer); - return $this->includeCollection($user->user_companies, $transformer, CompanyUser::class); + return $this->includeCollection($user->company_users, $transformer, CompanyUser::class); } diff --git a/app/Utils/Traits/Inviteable.php b/app/Utils/Traits/Inviteable.php index c512a9d049d2..73951a49a680 100644 --- a/app/Utils/Traits/Inviteable.php +++ b/app/Utils/Traits/Inviteable.php @@ -52,14 +52,14 @@ trait Inviteable switch ($this->company->portal_mode) { case 'subdomain': - return $domain .'client/'. $entity_type .'/'. $this->key; + return $domain .'/client/'. $entity_type .'/'. $this->key; break; case 'iframe': - return $domain .'client/'. $entity_type .'/'. $this->key; + return $domain .'/client/'. $entity_type .'/'. $this->key; //return $domain . $entity_type .'/'. $this->contact->client->client_hash .'/'. $this->key; break; case 'domain': - return $domain .'client/'. $entity_type .'/'. $this->key; + return $domain .'/client/'. $entity_type .'/'. $this->key; break; } diff --git a/composer.json b/composer.json index e01252b86638..1e529f4c0b20 100644 --- a/composer.json +++ b/composer.json @@ -41,6 +41,7 @@ "sentry/sentry-laravel": "^1.0", "simshaun/recurr": "^4.0", "spatie/browsershot": "^3.29", + "staudenmeir/eloquent-has-many-deep": "^1.11", "stripe/stripe-php": "^7.0", "superbalist/laravel-google-cloud-storage": "^2.2", "webpatser/laravel-countries": "dev-master#75992ad", diff --git a/database/seeds/RandomDataSeeder.php b/database/seeds/RandomDataSeeder.php index 6dec2e8e1ec8..0597cfc3be06 100644 --- a/database/seeds/RandomDataSeeder.php +++ b/database/seeds/RandomDataSeeder.php @@ -72,7 +72,7 @@ class RandomDataSeeder extends Seeder 'is_owner' => 1, 'is_admin' => 1, 'is_locked' => 0, - 'permissions' => json_encode([]), + 'permissions' => '', 'settings' => json_encode(DefaultSettings::userSettings()), ]); diff --git a/tests/Feature/LoginTest.php b/tests/Feature/LoginTest.php index 6f368fa8c7a3..52e0dc7fff76 100644 --- a/tests/Feature/LoginTest.php +++ b/tests/Feature/LoginTest.php @@ -171,9 +171,9 @@ class LoginTest extends TestCase $user->fresh(); $this->assertTrue($user->companies !== null); - $this->assertTrue($user->user_companies !== null); - $this->assertTrue($user->user_companies->first() !== null); - $this->assertTrue($user->user_companies->first()->account !== null); + $this->assertTrue($user->company_users !== null); + $this->assertTrue($user->company_users->first() !== null); + $this->assertTrue($user->company_user->account !== null); $data = [ 'email' => 'test@example.com', diff --git a/tests/Feature/UserTest.php b/tests/Feature/UserTest.php index 0c63cf3a8996..0d013815c5b3 100644 --- a/tests/Feature/UserTest.php +++ b/tests/Feature/UserTest.php @@ -37,45 +37,44 @@ class UserTest extends TestCase Model::reguard(); + $this->makeTestData(); } public function testUserList() { - $data = [ - 'first_name' => $this->faker->firstName, - 'last_name' => $this->faker->lastName, - 'name' => $this->faker->company, - 'email' => $this->faker->unique()->safeEmail, - 'password' => 'ALongAndBrilliantPassword123', - '_token' => csrf_token(), - 'privacy_policy' => 1, - 'terms_of_service' => 1 - ]; - $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), - ])->post('/api/v1/signup?include=account', $data); - - - $response->assertStatus(200); - - $acc = $response->json(); - - - $account = Account::find($this->decodePrimaryKey($acc['data'][0]['account']['id'])); - - $token = $account->default_company->tokens->first()->token; - - $response = $this->withHeaders([ - 'X-API-SECRET' => config('ninja.api_secret'), - 'X-API-TOKEN' => $token, + 'X-API-TOKEN' => $this->token, ])->get('/api/v1/users'); $response->assertStatus(200); } + public function testUserStore() + { + $data = [ + 'first_name' => 'hey', + 'last_name' => 'you', + 'email' => 'bob@good.ole.boys.com', + 'company_user' => [ + 'is_admin' => false, + 'is_owner' => false, + 'permissions' => 'create_client,create_invoice' + ], + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->post('/api/v1/users?include=company_user', $data); + + $response->assertStatus(200); + + $arr = $response->json(); + + } } \ No newline at end of file