mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2026-03-03 02:57:01 +00:00
Purge user functionality
This commit is contained in:
@@ -12,31 +12,32 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Utils\Ninja;
|
||||
use App\Models\CompanyUser;
|
||||
use App\Factory\UserFactory;
|
||||
use App\Filters\UserFilters;
|
||||
use Illuminate\Http\Response;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Events\User\UserWasCreated;
|
||||
use App\Events\User\UserWasDeleted;
|
||||
use App\Events\User\UserWasUpdated;
|
||||
use App\Factory\UserFactory;
|
||||
use App\Filters\UserFilters;
|
||||
use App\Http\Controllers\Traits\VerifiesUserEmail;
|
||||
use App\Http\Requests\User\BulkUserRequest;
|
||||
use App\Http\Requests\User\CreateUserRequest;
|
||||
use App\Http\Requests\User\DestroyUserRequest;
|
||||
use App\Http\Requests\User\DetachCompanyUserRequest;
|
||||
use App\Http\Requests\User\DisconnectUserMailerRequest;
|
||||
use App\Http\Requests\User\EditUserRequest;
|
||||
use App\Http\Requests\User\ReconfirmUserRequest;
|
||||
use App\Http\Requests\User\ShowUserRequest;
|
||||
use App\Http\Requests\User\StoreUserRequest;
|
||||
use App\Http\Requests\User\UpdateUserRequest;
|
||||
use App\Jobs\Company\CreateCompanyToken;
|
||||
use App\Jobs\User\UserEmailChanged;
|
||||
use App\Models\CompanyUser;
|
||||
use App\Models\User;
|
||||
use App\Repositories\UserRepository;
|
||||
use App\Transformers\UserTransformer;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use Illuminate\Http\Response;
|
||||
use App\Jobs\Company\CreateCompanyToken;
|
||||
use App\Http\Requests\User\BulkUserRequest;
|
||||
use App\Http\Requests\User\EditUserRequest;
|
||||
use App\Http\Requests\User\ShowUserRequest;
|
||||
use App\Http\Requests\User\PurgeUserRequest;
|
||||
use App\Http\Requests\User\StoreUserRequest;
|
||||
use App\Http\Requests\User\CreateUserRequest;
|
||||
use App\Http\Requests\User\UpdateUserRequest;
|
||||
use App\Http\Requests\User\DestroyUserRequest;
|
||||
use App\Http\Requests\User\ReconfirmUserRequest;
|
||||
use App\Http\Controllers\Traits\VerifiesUserEmail;
|
||||
use App\Http\Requests\User\DetachCompanyUserRequest;
|
||||
use App\Http\Requests\User\DisconnectUserMailerRequest;
|
||||
|
||||
/**
|
||||
* Class UserController.
|
||||
@@ -350,4 +351,12 @@ class UserController extends BaseController
|
||||
|
||||
}
|
||||
|
||||
public function purge(PurgeUserRequest $request, User $user)
|
||||
{
|
||||
$this->user_repo->purge($user, auth()->user());
|
||||
|
||||
return response()->noContent();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
28
app/Http/Requests/User/PurgeUserRequest.php
Normal file
28
app/Http/Requests/User/PurgeUserRequest.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Http\Requests\User;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
|
||||
class PurgeUserRequest extends Request
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth()->user()->isOwner() && auth()->user()->id !== $this->user->id;
|
||||
}
|
||||
}
|
||||
@@ -351,6 +351,196 @@ class User extends Authenticatable implements MustVerifyEmail
|
||||
return $this->hasMany(Client::class);
|
||||
}
|
||||
|
||||
public function activities(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Activity::class);
|
||||
}
|
||||
|
||||
public function bank_integrations(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(BankIntegration::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function bank_transaction_rules(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(BankTransactionRule::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function bank_transactions(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(BankTransaction::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function client_contacts(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(ClientContact::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function company_gateways(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(CompanyGateway::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function company_ledgers(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(CompanyLedger::class);
|
||||
}
|
||||
|
||||
public function company_tokens(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(CompanyToken::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function credit_invitations(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(CreditInvitation::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function credits(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Credit::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function designs(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Design::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function expense_categories(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(ExpenseCategory::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function expenses(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Expense::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function group_settings(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(GroupSetting::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function invoice_invitations(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(InvoiceInvitation::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function invoices(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Invoice::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function locations(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Location::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function payment_terms(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(PaymentTerm::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function payments(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Payment::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function products(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Product::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function projects(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Project::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function purchase_order_invitations(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(PurchaseOrderInvitation::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function purchase_orders(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(PurchaseOrder::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function quote_invitations(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(QuoteInvitation::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function quotes(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Quote::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function recurring_expenses(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(RecurringExpense::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function recurring_invoice_invitations(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(RecurringInvoiceInvitation::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function recurring_invoices(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(RecurringInvoice::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function recurring_quotes(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(RecurringQuote::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function recurring_quote_invitations(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(RecurringQuoteInvitation::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function schedules(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Scheduler::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function system_logs(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(SystemLog::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function tasks(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Task::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function task_statuses(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(TaskStatus::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function tax_rates(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(TaxRate::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function vendor_contacts(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(VendorContact::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function vendors(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Vendor::class)->withTrashed();
|
||||
}
|
||||
|
||||
public function webhooks(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Webhook::class)->withTrashed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comma separated list of user permissions.
|
||||
*
|
||||
|
||||
@@ -12,17 +12,33 @@
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Events\User\UserWasArchived;
|
||||
use App\Events\User\UserWasDeleted;
|
||||
use App\Events\User\UserWasRestored;
|
||||
use App\Jobs\Company\CreateCompanyToken;
|
||||
use App\Models\CompanyUser;
|
||||
use App\Models\Task;
|
||||
use App\Models\User;
|
||||
use App\Utils\Ninja;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Models\Quote;
|
||||
use App\Models\Client;
|
||||
use App\Models\Credit;
|
||||
use App\Models\Vendor;
|
||||
use App\Models\Expense;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
use App\Models\Product;
|
||||
use App\Models\Project;
|
||||
use App\Models\CompanyUser;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\PurchaseOrder;
|
||||
use App\Models\RecurringQuote;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
use App\Models\RecurringExpense;
|
||||
use App\Models\RecurringInvoice;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\DataMapper\CompanySettings;
|
||||
use App\Events\User\UserWasDeleted;
|
||||
use App\Events\User\UserWasArchived;
|
||||
use App\Events\User\UserWasRestored;
|
||||
use App\Repositories\BaseRepository;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use App\Jobs\Company\CreateCompanyToken;
|
||||
|
||||
/**
|
||||
* UserRepository.
|
||||
@@ -242,4 +258,51 @@ class UserRepository extends BaseRepository
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function purge(User $user, User $new_owner_user): void
|
||||
{
|
||||
|
||||
\DB::transaction(function () use ($user, $new_owner_user) {
|
||||
|
||||
// Relations to transfer user_id to new owner
|
||||
$allRelations = [
|
||||
'activities', 'bank_integrations', 'bank_transaction_rules',
|
||||
'bank_transactions', 'client_contacts', 'company_gateways',
|
||||
'company_ledgers', 'company_tokens', 'credit_invitations',
|
||||
'designs', 'expense_categories', 'group_settings',
|
||||
'invoice_invitations', 'locations', 'payment_terms',
|
||||
'quote_invitations', 'purchase_order_invitations',
|
||||
'recurring_invoice_invitations', 'recurring_quote_invitations',
|
||||
'schedules', 'system_logs', 'task_statuses', 'tax_rates',
|
||||
'vendor_contacts', 'webhooks',
|
||||
// Models that also have assigned_user_id
|
||||
'clients', 'invoices', 'credits', 'quotes', 'payments',
|
||||
'expenses', 'tasks', 'projects', 'vendors', 'products',
|
||||
'purchase_orders', 'recurring_invoices', 'recurring_expenses',
|
||||
'recurring_quotes',
|
||||
];
|
||||
|
||||
foreach ($allRelations as $relation) {
|
||||
$user->{$relation}()->update(['user_id' => $new_owner_user->id]);
|
||||
}
|
||||
|
||||
// Models with both user_id and assigned_user_id
|
||||
$modelsWithAssignedUser = [
|
||||
Client::class, Invoice::class, Credit::class, Quote::class,
|
||||
Payment::class, Expense::class, Task::class, Project::class,
|
||||
Vendor::class, Product::class, PurchaseOrder::class,
|
||||
RecurringInvoice::class, RecurringExpense::class, RecurringQuote::class,
|
||||
];
|
||||
|
||||
foreach ($modelsWithAssignedUser as $model) {
|
||||
// Null out assigned_user_id
|
||||
$model::withTrashed()
|
||||
->where('assigned_user_id', $user->id)
|
||||
->update(['assigned_user_id' => null]);
|
||||
}
|
||||
|
||||
$user->forceDelete();
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,6 +436,7 @@ Route::group(['middleware' => ['throttle:api', 'token_auth', 'valid_json','local
|
||||
Route::post('/users/{user}/disconnect_mailer', [UserController::class, 'disconnectOauthMailer']);
|
||||
Route::post('/users/{user}/disconnect_oauth', [UserController::class, 'disconnectOauth']);
|
||||
Route::post('/user/{user}/reconfirm', [UserController::class, 'reconfirm']);
|
||||
Route::post('/user/{user}/purge', [UserController::class, 'purge'])->middleware('password_protected');
|
||||
|
||||
Route::resource('webhooks', WebhookController::class);
|
||||
Route::post('webhooks/bulk', [WebhookController::class, 'bulk'])->name('webhooks.bulk');
|
||||
|
||||
@@ -755,4 +755,260 @@ class UserTest extends TestCase
|
||||
$this->assertFalse($arr['data']['company_user']['is_owner']);
|
||||
$this->assertEquals($arr['data']['company_user']['permissions'], 'create_invoice,create_invoice');
|
||||
}
|
||||
|
||||
public function testPurgeUserTransfersEntities()
|
||||
{
|
||||
// Create account and owner user
|
||||
$account = Account::factory()->create([
|
||||
'hosted_client_count' => 1000,
|
||||
'hosted_company_count' => 1000,
|
||||
]);
|
||||
|
||||
$account->num_users = 3;
|
||||
$account->save();
|
||||
|
||||
$owner_user = User::factory()->create([
|
||||
'account_id' => $account->id,
|
||||
'email' => \Illuminate\Support\Str::random(32)."@example.com",
|
||||
]);
|
||||
|
||||
$settings = CompanySettings::defaults();
|
||||
|
||||
$company = Company::factory()->create([
|
||||
'account_id' => $account->id,
|
||||
'settings' => $settings,
|
||||
]);
|
||||
|
||||
$owner_user->companies()->attach($company->id, [
|
||||
'account_id' => $account->id,
|
||||
'is_owner' => 1,
|
||||
'is_admin' => 1,
|
||||
'is_locked' => 0,
|
||||
'permissions' => '',
|
||||
'notifications' => CompanySettings::notificationAdminDefaults(),
|
||||
'settings' => null,
|
||||
]);
|
||||
|
||||
// Create secondary user to be purged
|
||||
$secondary_user = User::factory()->create([
|
||||
'account_id' => $account->id,
|
||||
'email' => \Illuminate\Support\Str::random(32)."@example.com",
|
||||
]);
|
||||
|
||||
$secondary_user->companies()->attach($company->id, [
|
||||
'account_id' => $account->id,
|
||||
'is_owner' => 0,
|
||||
'is_admin' => 1,
|
||||
'is_locked' => 0,
|
||||
'permissions' => '',
|
||||
'notifications' => CompanySettings::notificationAdminDefaults(),
|
||||
'settings' => null,
|
||||
]);
|
||||
|
||||
// Create a client owned by secondary user
|
||||
$client = \App\Models\Client::factory()->create([
|
||||
'user_id' => $secondary_user->id,
|
||||
'company_id' => $company->id,
|
||||
'assigned_user_id' => $secondary_user->id,
|
||||
]);
|
||||
|
||||
// Create client contact
|
||||
$client_contact = \App\Models\ClientContact::factory()->create([
|
||||
'user_id' => $secondary_user->id,
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'is_primary' => true,
|
||||
]);
|
||||
|
||||
// Create invoice owned by secondary user
|
||||
$invoice = \App\Models\Invoice::factory()->create([
|
||||
'user_id' => $secondary_user->id,
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'assigned_user_id' => $secondary_user->id,
|
||||
'status_id' => \App\Models\Invoice::STATUS_DRAFT,
|
||||
]);
|
||||
$invoice = $invoice->service()->createInvitations()->markSent()->save();
|
||||
|
||||
// Create credit owned by secondary user
|
||||
$credit = \App\Models\Credit::factory()->create([
|
||||
'user_id' => $secondary_user->id,
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'assigned_user_id' => $secondary_user->id,
|
||||
'status_id' => \App\Models\Credit::STATUS_DRAFT,
|
||||
]);
|
||||
|
||||
$credit = $credit->service()->createInvitations()->markSent()->save();
|
||||
|
||||
// Create quote owned by secondary user
|
||||
$quote = \App\Models\Quote::factory()->create([
|
||||
'user_id' => $secondary_user->id,
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'assigned_user_id' => $secondary_user->id,
|
||||
'status_id' => \App\Models\Quote::STATUS_DRAFT,
|
||||
]);
|
||||
$quote = $quote->service()->createInvitations()->markSent()->save();
|
||||
|
||||
// Create recurring invoice owned by secondary user
|
||||
$recurring_invoice = \App\Models\RecurringInvoice::factory()->create([
|
||||
'user_id' => $secondary_user->id,
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'assigned_user_id' => $secondary_user->id,
|
||||
'status_id' => \App\Models\RecurringInvoice::STATUS_DRAFT,
|
||||
]);
|
||||
|
||||
$recurring_invoice = $recurring_invoice->service()->createInvitations()->start()->save();
|
||||
// Create expense owned by secondary user
|
||||
$expense = \App\Models\Expense::factory()->create([
|
||||
'user_id' => $secondary_user->id,
|
||||
'company_id' => $company->id,
|
||||
'assigned_user_id' => $secondary_user->id,
|
||||
]);
|
||||
|
||||
// Create task owned by secondary user
|
||||
$task = \App\Models\Task::factory()->create([
|
||||
'user_id' => $secondary_user->id,
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'assigned_user_id' => $secondary_user->id,
|
||||
]);
|
||||
|
||||
// Create vendor owned by secondary user
|
||||
$vendor = \App\Models\Vendor::factory()->create([
|
||||
'user_id' => $secondary_user->id,
|
||||
'company_id' => $company->id,
|
||||
'assigned_user_id' => $secondary_user->id,
|
||||
]);
|
||||
|
||||
// Create vendor contact
|
||||
$vendor_contact = \App\Models\VendorContact::factory()->create([
|
||||
'user_id' => $secondary_user->id,
|
||||
'company_id' => $company->id,
|
||||
'vendor_id' => $vendor->id,
|
||||
'is_primary' => true,
|
||||
]);
|
||||
|
||||
// Create product owned by secondary user
|
||||
$product = \App\Models\Product::factory()->create([
|
||||
'user_id' => $secondary_user->id,
|
||||
'company_id' => $company->id,
|
||||
'assigned_user_id' => $secondary_user->id,
|
||||
]);
|
||||
|
||||
// Create project owned by secondary user
|
||||
$project = \App\Models\Project::factory()->create([
|
||||
'user_id' => $secondary_user->id,
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'assigned_user_id' => $secondary_user->id,
|
||||
]);
|
||||
|
||||
// Create an entity owned by owner but assigned to secondary user
|
||||
$invoice_assigned_only = \App\Models\Invoice::factory()->create([
|
||||
'user_id' => $owner_user->id,
|
||||
'company_id' => $company->id,
|
||||
'client_id' => $client->id,
|
||||
'assigned_user_id' => $secondary_user->id,
|
||||
]);
|
||||
|
||||
|
||||
$invoice = $invoice->load('invitations');
|
||||
|
||||
$this->assertCount(1, $invoice->invitations);
|
||||
$this->assertCount(1, $recurring_invoice->invitations);
|
||||
// Store IDs for later assertions
|
||||
$secondary_user_id = $secondary_user->id;
|
||||
$client_id = $client->id;
|
||||
$client_contact_id = $client_contact->id;
|
||||
$invoice_id = $invoice->id;
|
||||
$invoice_invitation_id = $invoice->invitations()->first()->id;
|
||||
$credit_id = $credit->id;
|
||||
$credit_invitation_id = $credit->invitations()->first()->id;
|
||||
$quote_id = $quote->id;
|
||||
$quote_invitation_id = $quote->invitations()->first()->id;
|
||||
$recurring_invoice_id = $recurring_invoice->id;
|
||||
$expense_id = $expense->id;
|
||||
$task_id = $task->id;
|
||||
$vendor_id = $vendor->id;
|
||||
$vendor_contact_id = $vendor_contact->id;
|
||||
$product_id = $product->id;
|
||||
$project_id = $project->id;
|
||||
$invoice_assigned_only_id = $invoice_assigned_only->id;
|
||||
|
||||
// Perform the purge
|
||||
$user_repo = new UserRepository();
|
||||
$user_repo->purge($secondary_user, $owner_user);
|
||||
|
||||
// Assert secondary user is deleted
|
||||
$this->assertNull(User::find($secondary_user_id));
|
||||
|
||||
// Assert all entities are now owned by owner user
|
||||
$client = \App\Models\Client::find($client_id);
|
||||
$this->assertEquals($owner_user->id, $client->user_id);
|
||||
$this->assertNull($client->assigned_user_id);
|
||||
|
||||
// Assert client contact user_id updated
|
||||
$client_contact = \App\Models\ClientContact::find($client_contact_id);
|
||||
$this->assertEquals($owner_user->id, $client_contact->user_id);
|
||||
|
||||
$invoice = \App\Models\Invoice::find($invoice_id);
|
||||
$this->assertEquals($owner_user->id, $invoice->user_id);
|
||||
$this->assertNull($invoice->assigned_user_id);
|
||||
|
||||
// Assert invoice invitation user_id updated
|
||||
$invoice_invitation = \App\Models\InvoiceInvitation::find($invoice_invitation_id);
|
||||
$this->assertEquals($owner_user->id, $invoice_invitation->user_id);
|
||||
|
||||
$credit = \App\Models\Credit::find($credit_id);
|
||||
$this->assertEquals($owner_user->id, $credit->user_id);
|
||||
$this->assertNull($credit->assigned_user_id);
|
||||
|
||||
// Assert credit invitation user_id updated
|
||||
$credit_invitation = \App\Models\CreditInvitation::find($credit_invitation_id);
|
||||
$this->assertEquals($owner_user->id, $credit_invitation->user_id);
|
||||
|
||||
$quote = \App\Models\Quote::find($quote_id);
|
||||
$this->assertEquals($owner_user->id, $quote->user_id);
|
||||
$this->assertNull($quote->assigned_user_id);
|
||||
|
||||
// Assert quote invitation user_id updated
|
||||
$quote_invitation = \App\Models\QuoteInvitation::find($quote_invitation_id);
|
||||
$this->assertEquals($owner_user->id, $quote_invitation->user_id);
|
||||
|
||||
$recurring_invoice = \App\Models\RecurringInvoice::find($recurring_invoice_id);
|
||||
$this->assertEquals($owner_user->id, $recurring_invoice->user_id);
|
||||
$this->assertNull($recurring_invoice->assigned_user_id);
|
||||
|
||||
$expense = \App\Models\Expense::find($expense_id);
|
||||
$this->assertEquals($owner_user->id, $expense->user_id);
|
||||
$this->assertNull($expense->assigned_user_id);
|
||||
|
||||
$task = \App\Models\Task::find($task_id);
|
||||
$this->assertEquals($owner_user->id, $task->user_id);
|
||||
$this->assertNull($task->assigned_user_id);
|
||||
|
||||
$vendor = \App\Models\Vendor::find($vendor_id);
|
||||
$this->assertEquals($owner_user->id, $vendor->user_id);
|
||||
$this->assertNull($vendor->assigned_user_id);
|
||||
|
||||
// Assert vendor contact user_id updated
|
||||
$vendor_contact = \App\Models\VendorContact::find($vendor_contact_id);
|
||||
$this->assertEquals($owner_user->id, $vendor_contact->user_id);
|
||||
|
||||
$product = \App\Models\Product::find($product_id);
|
||||
$this->assertEquals($owner_user->id, $product->user_id);
|
||||
$this->assertNull($product->assigned_user_id);
|
||||
|
||||
$project = \App\Models\Project::find($project_id);
|
||||
$this->assertEquals($owner_user->id, $project->user_id);
|
||||
$this->assertNull($project->assigned_user_id);
|
||||
|
||||
// Assert entity owned by owner but assigned to secondary now has null assigned_user_id
|
||||
$invoice_assigned_only = \App\Models\Invoice::find($invoice_assigned_only_id);
|
||||
$this->assertEquals($owner_user->id, $invoice_assigned_only->user_id);
|
||||
$this->assertNull($invoice_assigned_only->assigned_user_id);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user