103 خطوط
4.9 KiB
PHP
103 خطوط
4.9 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\Lead;
|
|
use App\Models\Team;
|
|
use App\Models\User;
|
|
use Database\Seeders\RolePermissionSeeder;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Tests\TestCase;
|
|
|
|
class WorkflowInteractionTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->seed(RolePermissionSeeder::class);
|
|
}
|
|
|
|
public function test_follow_up_assignment_is_visible_notified_and_only_creator_can_edit(): void
|
|
{
|
|
[$supervisor, $agent] = $this->team();
|
|
$lead = $this->lead($agent);
|
|
|
|
$created = $this->actingAs($supervisor)->postJson('/api/follow-ups', [
|
|
'lead_id' => $lead->id,
|
|
'user_id' => $agent->id,
|
|
'scheduled_at' => now()->addDay()->setTime(10, 0)->toISOString(),
|
|
'notes' => 'تماس درباره پیشنهاد',
|
|
])->assertCreated()->assertJsonPath('data.created_by', $supervisor->id);
|
|
$followUpId = $created->json('data.id');
|
|
|
|
$this->assertDatabaseHas('internal_notifications', ['user_id' => $agent->id, 'type' => 'follow_up']);
|
|
$this->actingAs($agent)->getJson('/api/follow-ups')->assertOk()->assertJsonFragment(['id' => $followUpId]);
|
|
$this->actingAs($agent)->patchJson("/api/follow-ups/{$followUpId}", ['notes' => 'ویرایش غیرمجاز'])->assertForbidden();
|
|
$this->actingAs($supervisor)->patchJson("/api/follow-ups/{$followUpId}", ['notes' => 'ویرایش سازنده'])->assertOk();
|
|
$this->actingAs($agent)->patchJson("/api/follow-ups/{$followUpId}/mark-done")->assertOk()->assertJsonPath('data.status', 'completed');
|
|
}
|
|
|
|
public function test_invoice_has_paid_balance_and_separate_approval_then_issue(): void
|
|
{
|
|
[$supervisor, $agent] = $this->team();
|
|
$lead = $this->lead($agent, ['final_result' => 'موفق', 'deal_value' => 1_000_000, 'sold_product' => 'اشتراک']);
|
|
|
|
$invoiceId = $this->actingAs($agent)->postJson("/api/leads/{$lead->id}/invoice", [
|
|
'paid_amount' => 250_000,
|
|
])->assertCreated()->assertJsonPath('payment_status', 'partial')->assertJsonPath('balance_due', 750000)->json('id');
|
|
|
|
$this->actingAs($supervisor)->postJson("/api/invoices/{$invoiceId}/reject", ['reason' => 'اصلاح مبلغ پرداختی'])
|
|
->assertOk()->assertJsonPath('status', 'rejected');
|
|
$this->actingAs($agent)->putJson("/api/invoices/{$invoiceId}", ['paid_amount' => 300_000])
|
|
->assertOk()->assertJsonPath('status', 'pending_approval')->assertJsonPath('balance_due', 700000);
|
|
$this->actingAs($supervisor)->postJson("/api/invoices/{$invoiceId}/approve")
|
|
->assertOk()->assertJsonPath('status', 'approved');
|
|
$this->actingAs($supervisor)->postJson("/api/invoices/{$invoiceId}/issue")
|
|
->assertOk()->assertJsonPath('status', 'issued');
|
|
}
|
|
|
|
public function test_agent_can_refer_own_lead_to_team_agent_and_recipient_is_notified(): void
|
|
{
|
|
[$supervisor, $agent, $secondAgent] = $this->team(true);
|
|
$lead = $this->lead($agent);
|
|
|
|
$this->actingAs($agent)->postJson("/api/leads/{$lead->id}/refer", ['user_id' => $secondAgent->id])
|
|
->assertOk()->assertJsonPath('assigned_to', $secondAgent->id);
|
|
$this->assertDatabaseHas('internal_notifications', ['user_id' => $secondAgent->id, 'type' => 'assignment']);
|
|
$managerLead = $this->lead($agent);
|
|
$this->actingAs($agent)->postJson("/api/leads/{$managerLead->id}/refer", ['user_id' => $supervisor->id])
|
|
->assertOk()->assertJsonPath('assigned_to', $supervisor->id);
|
|
$this->assertDatabaseHas('internal_notifications', ['user_id' => $supervisor->id, 'type' => 'assignment']);
|
|
}
|
|
|
|
private function team(bool $withSecondAgent = false): array
|
|
{
|
|
$supervisor = User::factory()->create(['is_active' => true]);
|
|
$supervisor->assignRole('supervisor');
|
|
$agent = User::factory()->create(['is_active' => true]);
|
|
$agent->assignRole('agent');
|
|
$team = Team::create(['name' => fake()->unique()->company(), 'supervisor_id' => $supervisor->id, 'is_active' => true]);
|
|
$supervisor->teams()->attach($team);
|
|
$agent->teams()->attach($team);
|
|
if (! $withSecondAgent) {
|
|
return [$supervisor, $agent];
|
|
}
|
|
$second = User::factory()->create(['is_active' => true]);
|
|
$second->assignRole('agent');
|
|
$second->teams()->attach($team);
|
|
|
|
return [$supervisor, $agent, $second];
|
|
}
|
|
|
|
private function lead(User $agent, array $overrides = []): Lead
|
|
{
|
|
return Lead::create(array_merge([
|
|
'company' => 'شرکت نمونه', 'first_name' => 'علی', 'last_name' => 'آزمایشی',
|
|
'phone' => fake()->unique()->numerify('0912#######'), 'assigned_to' => $agent->id, 'is_unassigned' => false,
|
|
'team_id' => $agent->teams()->value('teams.id'),
|
|
], $overrides));
|
|
}
|
|
}
|