Deploy 1: i18n + Notifications + Global Search + Tests
- SetLocale middleware (ro/ru/en, session-first, user-persisted)
- Lang switcher in topbar (Filament render hook USER_MENU_BEFORE)
- POST /locale/{lang} route persists to user.locale + session
- Database notifications enabled on tenant panel (30s polling)
- GlobalSearch (Cmd+K / Ctrl+K) on Client, Vehicle, WorkOrder, Lead, Part
- Tests: TenantIsolation (4), AuthFlow (2), WorkOrderCalc (3), MarkupRule (3)
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use App\Models\Central\Company;
|
||||
use App\Models\Central\Plan;
|
||||
use App\Models\Tenant\MarkupRule;
|
||||
use App\Models\Tenant\Part;
|
||||
use App\Tenancy\TenantManager;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class MarkupRuleTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_category_rule_applies_to_part(): void
|
||||
{
|
||||
$this->setupTenant();
|
||||
|
||||
$part = Part::create([
|
||||
'name' => 'Plăcuțe frână',
|
||||
'category' => 'Frâne',
|
||||
'buy_price' => 100,
|
||||
'sell_price' => 100,
|
||||
'stock' => 10,
|
||||
'is_active' => true,
|
||||
]);
|
||||
|
||||
MarkupRule::create([
|
||||
'type' => 'category',
|
||||
'key' => 'Frâne',
|
||||
'markup_pct' => 35,
|
||||
'priority' => 100,
|
||||
'is_active' => true,
|
||||
]);
|
||||
|
||||
MarkupRule::applyToPart($part);
|
||||
$part->refresh();
|
||||
|
||||
$this->assertEquals(135.00, (float) $part->sell_price);
|
||||
}
|
||||
|
||||
public function test_priority_picks_first_matching_rule(): void
|
||||
{
|
||||
$this->setupTenant();
|
||||
|
||||
$part = Part::create([
|
||||
'name' => 'Filtru',
|
||||
'category' => 'Filtre',
|
||||
'brand' => 'Bosch',
|
||||
'buy_price' => 50,
|
||||
'sell_price' => 50,
|
||||
'stock' => 5,
|
||||
'is_active' => true,
|
||||
]);
|
||||
|
||||
// Brand rule (priority 1 → applied first)
|
||||
MarkupRule::create(['type' => 'brand', 'key' => 'Bosch', 'markup_pct' => 50, 'priority' => 1, 'is_active' => true]);
|
||||
MarkupRule::create(['type' => 'category', 'key' => 'Filtre', 'markup_pct' => 20, 'priority' => 100, 'is_active' => true]);
|
||||
|
||||
MarkupRule::applyToPart($part);
|
||||
$part->refresh();
|
||||
|
||||
$this->assertEquals(75.00, (float) $part->sell_price);
|
||||
}
|
||||
|
||||
public function test_inactive_rule_is_skipped(): void
|
||||
{
|
||||
$this->setupTenant();
|
||||
|
||||
$part = Part::create([
|
||||
'name' => 'X', 'category' => 'Test',
|
||||
'buy_price' => 100, 'sell_price' => 100,
|
||||
'stock' => 1, 'is_active' => true,
|
||||
]);
|
||||
|
||||
MarkupRule::create([
|
||||
'type' => 'category', 'key' => 'Test',
|
||||
'markup_pct' => 99, 'priority' => 1, 'is_active' => false,
|
||||
]);
|
||||
|
||||
MarkupRule::applyToPart($part);
|
||||
$part->refresh();
|
||||
|
||||
// Inactive rule skipped → fallback default markup 30%.
|
||||
$this->assertEquals(130.00, (float) $part->sell_price);
|
||||
}
|
||||
|
||||
private function setupTenant(): void
|
||||
{
|
||||
$plan = Plan::create([
|
||||
'name' => 'Test', 'slug' => 'test', 'price' => 0, 'features' => [],
|
||||
]);
|
||||
$company = Company::create([
|
||||
'plan_id' => $plan->id,
|
||||
'slug' => 'unit-' . uniqid(),
|
||||
'name' => 'Unit Test',
|
||||
'status' => 'active',
|
||||
]);
|
||||
app(TenantManager::class)->setCurrent($company);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user