Skip to content

Commit

Permalink
Merge pull request #127 from fleetbase/dev-v0.5.10
Browse files Browse the repository at this point in the history
v0.5.10 - fixed driver creation flow to stop role breaking, added contact sync …
  • Loading branch information
roncodes authored Oct 10, 2024
2 parents 8a40f52 + 30604f9 commit 59b309d
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 65 deletions.
2 changes: 1 addition & 1 deletion addon/components/modals/reset-customer-credentials.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Modal::Default @modalIsOpened={{@modalIsOpened}} @options={{@options}} @confirm={{@onConfirm}} @decline={{@onDecline}}>
<div class="px-5 text-white dark:text-black">
<div class="px-4 text-gray-900 dark:text-gray-50">
<div class="mb-1 text-base font-semibold">
You are about to reset the password for
{{this.customer.name}}
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fleetbase/fleetops-api",
"version": "0.5.9",
"version": "0.5.10",
"description": "Fleet & Transport Management Extension for Fleetbase",
"keywords": [
"fleetbase-extension",
Expand Down
2 changes: 1 addition & 1 deletion extension.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Fleet-Ops",
"version": "0.5.9",
"version": "0.5.10",
"description": "Fleet & Transport Management Extension for Fleetbase",
"repository": "https://github.com/fleetbase/fleetops",
"license": "AGPL-3.0-or-later",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fleetbase/fleetops-engine",
"version": "0.5.9",
"version": "0.5.10",
"description": "Fleet & Transport Management Extension for Fleetbase",
"fleetbase": {
"route": "fleet-ops"
Expand Down
59 changes: 12 additions & 47 deletions server/src/Http/Controllers/Internal/v1/DriverController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
use Fleetbase\Models\Invite;
use Fleetbase\Models\User;
use Fleetbase\Models\VerificationCode;
use Fleetbase\Notifications\UserInvited;
use Fleetbase\Support\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
Expand Down Expand Up @@ -81,7 +80,7 @@ public function createRecord(Request $request)

if ($existingUser) {
// if exists in organization create driver profile for user
$isOrganizationMember = $existingUser->companies()->where('company_uuid', session('company'))->exists();
$isOrganizationMember = $existingUser->companies()->where('companies.uuid', session('company'))->exists();

// Check if driver profile also already exists
$existingDriverProfile = Driver::where(['company_uuid' => session('company'), 'user_uuid' => $existingUser->uuid])->first();
Expand All @@ -106,36 +105,14 @@ public function createRecord(Request $request)
$input['location'] = new Point(0, 0);
}

// If user is a regular user set type and role
// also if is not admin and is not Administrator role
if ($existingUser->isNotAdmin() && !$existingUser->hasRole('Administrator')) {
$existingUser->assignSingleRole('Driver');
}

// create the profile
$driverProfile = Driver::create($input);

// Assign user to company
if ($company) {
// If not already a member of the company assign them to the company and send the user an invite
if (!$isOrganizationMember && $company) {
$existingUser->assignCompany($company);
}

if (!$isOrganizationMember) {
// send invitation to user
$invitation = Invite::create([
'company_uuid' => session('company'),
'created_by_uuid' => session('user'),
'subject_uuid' => session('company'),
'subject_type' => Utils::getMutationType('company'),
'protocol' => 'email',
'recipients' => [$existingUser->email],
'reason' => 'join_company',
]);

// notify user
$existingUser->notify(new UserInvited($invitation));
}

return ['driver' => new $this->resource($driverProfile)];
}
}
Expand All @@ -152,10 +129,12 @@ function (&$request, &$input) {

// Get current session company
$company = Auth::getCompany();
if (!$company) {
throw new \Exception('Unable to create driver.');
}

if ($input->has('user_uuid')) {
$user = User::where('uuid', $input->get('user_uuid'))->first();
// handle `photo_uuid`
if ($user && $input->has('photo_uuid')) {
$user->update(['avatar_uuid' => $input->get('photo_uuid')]);
}
Expand Down Expand Up @@ -188,39 +167,25 @@ function (&$request, &$input) {
$user->setType('driver');
}

// if exists in organization create driver profile for user
$isOrganizationMember = $user->companies()->where('companies.uuid', session('company'))->exists();

// Prepare input
$input = $input
->except(['name', 'password', 'email', 'phone', 'meta', 'avatar_uuid', 'photo_uuid', 'status'])
->filter()
->toArray();

// Assign user to company
if ($company) {
// Assign user to company and send invite
if (!$isOrganizationMember && $company) {
$user->assignCompany($company);
} else {
$user->deleteQuietly();
throw new \Exception('Unable to assign driver to company.');
}

// Set user type as driver and set role to driver
if ($user->isNotAdmin()) {
if ($user->type === 'driver') {
$user->assignSingleRole('Driver');
}

// send invitation to user
$invitation = Invite::create([
'company_uuid' => session('company'),
'created_by_uuid' => session('user'),
'subject_uuid' => session('company'),
'subject_type' => Utils::getMutationType('company'),
'protocol' => 'email',
'recipients' => [$user->email],
'reason' => 'join_company',
]);

// notify user
$user->notify(new UserInvited($invitation));

$input['user_uuid'] = $user->uuid;
$input['slug'] = $user->slug;

Expand Down
6 changes: 0 additions & 6 deletions server/src/Http/Filter/ContactFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ public function queryForInternal()
$this->builder->where(
function ($query) {
$query->where('company_uuid', $this->session->get('company'));
$query->orWhereHas(
'anyUser',
function ($query) {
$query->where('company_uuid', $this->session->get('company'));
}
);
}
);
}
Expand Down
7 changes: 1 addition & 6 deletions server/src/Http/Filter/DriverFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,7 @@ public function queryForInternal()
$this->builder->where(
function ($query) {
$query->where('company_uuid', $this->session->get('company'));
$query->orWhereHas(
'user',
function ($query) {
$query->where('company_uuid', $this->session->get('company'));
}
);
$query->whereHas('user');
}
);
}
Expand Down
60 changes: 58 additions & 2 deletions server/src/Models/Contact.php
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,12 @@ public static function createFromImport(array $row, bool $saveInstance = false):
public static function createUserFromContact(Contact $contact, bool $sendInvite = true): User
{
// Check if user already exist with email or phone number
$userAlreadyExists = User::where('type', $contact->type)->where(function ($query) use ($contact) {
$userAlreadyExists = User::where(function ($query) use ($contact) {
$query->where('email', $contact->email);
$query->orWhere('phone', $contact->phone);
})->first();
if ($userAlreadyExists) {
throw new UserAlreadyExistsException('User already exists, try to assign the user to this contact.');
throw new UserAlreadyExistsException('User already exists, try to assigning the user to this contact.');
}

// Load company
Expand Down Expand Up @@ -325,9 +325,39 @@ public static function createUserFromContact(Contact $contact, bool $sendInvite
$user->notify(new UserInvited($invitation));
}

$contact->setRelation('user', $user);

return $user;
}

public function syncWithUser(): bool
{
$updates = [];

if ($this->isDirty('name')) {
$updates['name'] = $this->name;
}

if ($this->isDirty('email')) {
$updates['email'] = $this->email;
}

if ($this->isDirty('phone')) {
$updates['phone'] = $this->phone;
}

if ($this->isDirty('timezone')) {
$updates['timezone'] = $this->timezone;
}

$user = $this->getUser();
if ($user) {
return $user->update($updates);
}

return false;
}

/**
* Creates a new user from the current contact instance and optionally sends an invitation.
*
Expand Down Expand Up @@ -355,4 +385,30 @@ public function deleteUser(): ?bool

return false;
}

public function getUser(): ?User
{
$this->loadMissing('user');
if ($this->user) {
return $this->user;
}

if (Str::isUuid($this->user_uuid)) {
return User::where('uuid', $this->user_uuid)->first();
}

return null;
}

public function hasUser(): bool
{
$user = $this->getUser();

return Str::isUuid($this->user_uuid) && $user instanceof User;
}

public function doesntHaveUser(): bool
{
return !$this->hasUser();
}
}
37 changes: 37 additions & 0 deletions server/src/Observers/ContactObserver.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Fleetbase\FleetOps\Observers;

use Fleetbase\FleetOps\Models\Contact;
use Fleetbase\Models\User;

class ContactObserver
{
Expand All @@ -17,6 +18,32 @@ public function created(Contact $contact)
$contact->createUser();
}

/**
* Handle the Contact "creating" event.
*
* @return void
*/
public function updating(Contact $contact)
{
// Get the contacts assosciated user
if ($contact->doesntHaveUser()) {
$contact->createUser();
}

// Validate email is available to user
if ($contact->isDirty('email') && $this->isEmailUnavailable($contact)) {
throw new \Exception('Email attempting to update for ' . $contact->type . ' is not available.');
}

// Validate phone is available to user
if ($contact->isDirty('phone') && $this->isPhoneUnavailable($contact)) {
throw new \Exception('Phone attempting to update for ' . $contact->type . ' is not available.');
}

// Sync updates from contact to user
$contact->syncWithUser();
}

/**
* Handle the Contact "deleted" event.
*
Expand All @@ -27,4 +54,14 @@ public function deleted(Contact $contact)
// Delete the assosciated user account
$contact->deleteUser();
}

private function isEmailUnavailable(Contact $contact)
{
return User::where('email', $contact->email)->whereNot('uuid', $contact->user_uuid)->exists() || Contact::where('email', $contact->email)->whereNot('uuid', $contact->uuid)->exists();
}

private function isPhoneUnavailable(Contact $contact)
{
return User::where('phone', $contact->phone)->whereNot('uuid', $contact->user_uuid)->exists() || Contact::where('phone', $contact->phone)->whereNot('uuid', $contact->uuid)->exists();
}
}

0 comments on commit 59b309d

Please sign in to comment.