fix(реклама): вернуть GET /api/sales/ad-audience/firms для модуля «Прогрев СМС»
Разъезд «Рекламы на кандидатов» на площадки (yandex|vk|mts) снёс общий маршрут /ad-audience/firms — фирмо-пикер SalesSmsView.vue его звал и получал 404. Восстановлен как платформо-независимый allFirms(): та же выборка firms(), но без where(channel, true). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,8 @@ use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
* POST /api/sales/warming/{platform}/firms/{id}/toggle — включить/выключить фирму на площадке
|
||||
* POST /api/sales/warming/{platform}/firms/{id}/assign — начальник назначает менеджера, рождается карточка воронки
|
||||
* GET /api/sales/warming/mts/file — выгрузка номеров для ручной загрузки в МТС
|
||||
* GET /api/sales/ad-audience/firms — ВСЕ фирмы прогрева, без фильтра площадки
|
||||
* (для модуля «Прогрев СМС», см. allFirms())
|
||||
*
|
||||
* Все методы — ТОЛЬКО начальник (role=head), гейт зеркалит SalesManagersController.
|
||||
* Менеджер → 403. Неизвестная площадка (не yandex/vk/mts) → 404.
|
||||
@@ -236,6 +238,35 @@ class SalesAdAudienceController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/sales/ad-audience/firms — ВСЕ фирмы прогрева без фильтра площадки.
|
||||
*
|
||||
* Платформенный список — firms({platform}); этот метод отдаёт полный состав
|
||||
* (используется модулем «Прогрев СМС», у которого своя логика отбора).
|
||||
*/
|
||||
public function allFirms(Request $request): JsonResponse
|
||||
{
|
||||
if (($resp = $this->denyIfNotHead($request)) !== null) {
|
||||
return $resp;
|
||||
}
|
||||
|
||||
$firms = SalesAdAudienceFirm::query()
|
||||
->with('phones')
|
||||
->orderByRaw('ready_at IS NULL')
|
||||
->orderByDesc('warmup_started_at')
|
||||
->limit(500)
|
||||
->get();
|
||||
|
||||
$prospects = SalesProspect::query()
|
||||
->whereIn('id', $firms->pluck('prospect_id')->filter()->all())
|
||||
->get()
|
||||
->keyBy('id');
|
||||
|
||||
return response()->json([
|
||||
'firms' => $firms->map(fn (SalesAdAudienceFirm $firm): array => $this->firmRow($firm, $prospects))->all(),
|
||||
]);
|
||||
}
|
||||
|
||||
// ── private ──────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
|
||||
@@ -316,6 +316,10 @@ Route::middleware(['admin-db', 'auth:sales', 'sales-portal'])->prefix('api/sales
|
||||
// Регистрируем ДО /warming/{platform}/firms — иначе .../firms не перепутается,
|
||||
// но mts/file имеет другое число сегментов, поэтому порядок не критичен.
|
||||
Route::get('/warming/mts/file', [SalesAdAudienceController::class, 'mtsFile']);
|
||||
// Регрессия: старая /ad-audience/firms была снесена разъездом на площадки, но модуль
|
||||
// «Прогрев СМС» (SalesSmsView) зовёт именно её для фирмо-пикера — восстановлена как
|
||||
// платформо-независимый список ВСЕХ фирм прогрева (allFirms(), НЕ путать с firms()).
|
||||
Route::get('/ad-audience/firms', [SalesAdAudienceController::class, 'allFirms']);
|
||||
// Task 9 (план «Прогрев СМС»): список рассылок, предпросмотр цены, запуск (только head).
|
||||
Route::get('/sms/campaigns', [SalesSmsController::class, 'index']);
|
||||
Route::post('/sms/campaigns', [SalesSmsController::class, 'store']);
|
||||
|
||||
@@ -97,3 +97,28 @@ it('переключатель добавляет и убирает фирму
|
||||
test()->postJson("/api/sales/warming/vk/firms/{$firm->id}/toggle", ['on' => false])->assertOk();
|
||||
expect($firm->fresh()->ch_vk)->toBeFalse();
|
||||
});
|
||||
|
||||
it('отдаёт ВСЕ фирмы прогрева, без фильтра площадки (для модуля СМС)', function () {
|
||||
actingHead();
|
||||
|
||||
SalesAdAudienceFirm::create(['firm_name' => 'Только Яндекс', 'ch_yandex' => true]);
|
||||
SalesAdAudienceFirm::create(['firm_name' => 'Только ВК', 'ch_vk' => true]);
|
||||
SalesAdAudienceFirm::create(['firm_name' => 'Нигде', 'ch_yandex' => false, 'ch_vk' => false, 'ch_mts' => false]);
|
||||
|
||||
test()->getJson('/api/sales/ad-audience/firms')
|
||||
->assertOk()
|
||||
->assertJsonCount(3, 'firms');
|
||||
});
|
||||
|
||||
it('список всех фирм закрыт для менеджера', function () {
|
||||
$m = SalesUser::create([
|
||||
'name' => 'Менеджер '.uniqid(),
|
||||
'email' => 'warmingmgr'.uniqid().'@sales.local',
|
||||
'password' => bcrypt('secret'),
|
||||
'role' => 'manager',
|
||||
'is_active' => true,
|
||||
]);
|
||||
test()->actingAs($m, 'sales');
|
||||
|
||||
test()->getJson('/api/sales/ad-audience/firms')->assertForbidden();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user