diff --git a/app/Http/Controllers/Api/V1/SettingsController.php b/app/Http/Controllers/Api/V1/SettingsController.php index f0fe2ca..829cc3a 100644 --- a/app/Http/Controllers/Api/V1/SettingsController.php +++ b/app/Http/Controllers/Api/V1/SettingsController.php @@ -276,4 +276,156 @@ public function updateShiftConfig(Request $request): JsonResponse ]); } + /** + * Get bot configuration + * + * GET /api/v1/settings/bot-config + * Query params: dealership_id (optional) + */ + public function getBotConfig(Request $request): JsonResponse + { + $dealershipId = $request->query('dealership_id'); + + return response()->json([ + 'success' => true, + 'data' => [ + // Telegram bot settings + 'telegram_bot_id' => $this->settingsService->get('telegram_bot_id', $dealershipId), + 'telegram_bot_username' => $this->settingsService->get('telegram_bot_username', $dealershipId), + 'telegram_webhook_url' => $this->settingsService->get('telegram_webhook_url', $dealershipId), + 'notification_enabled' => $this->settingsService->get('notification_enabled', $dealershipId, true), + + // Shift settings + 'shift_1_start_time' => $this->settingsService->getShiftStartTime($dealershipId, 1), + 'shift_1_end_time' => $this->settingsService->getShiftEndTime($dealershipId, 1), + 'shift_2_start_time' => $this->settingsService->getShiftStartTime($dealershipId, 2), + 'shift_2_end_time' => $this->settingsService->getShiftEndTime($dealershipId, 2), + 'late_tolerance_minutes' => $this->settingsService->getLateTolerance($dealershipId), + ], + ]); + } + + /** + * Update bot configuration + * + * POST /api/v1/settings/bot-config + * Body: {telegram_bot_id?, telegram_bot_username?, telegram_webhook_url?, notification_enabled?, dealership_id?} + */ + public function updateBotConfig(Request $request): JsonResponse + { + $validator = Validator::make($request->all(), [ + 'telegram_bot_id' => 'nullable|string|max:255', + 'telegram_bot_username' => 'nullable|string|max:255', + 'telegram_webhook_url' => 'nullable|url|max:500', + 'notification_enabled' => 'nullable|boolean', + 'shift_start_time' => 'sometimes|required|date_format:H:i', + 'shift_end_time' => 'sometimes|required|date_format:H:i', + 'late_tolerance_minutes' => 'sometimes|required|integer|min:0|max:120', + 'dealership_id' => 'nullable|exists:auto_dealerships,id', + ]); + + if ($validator->fails()) { + return response()->json([ + 'success' => false, + 'errors' => $validator->errors(), + ], 422); + } + + $data = $validator->validated(); + $dealershipId = $data['dealership_id'] ?? null; + + $updated = []; + + try { + if (isset($data['telegram_bot_id'])) { + $this->settingsService->set( + 'telegram_bot_id', + $data['telegram_bot_id'], + $dealershipId, + 'string', + 'Telegram Bot ID' + ); + $updated['telegram_bot_id'] = $data['telegram_bot_id']; + } + + if (isset($data['telegram_bot_username'])) { + $this->settingsService->set( + 'telegram_bot_username', + $data['telegram_bot_username'], + $dealershipId, + 'string', + 'Telegram Bot Username' + ); + $updated['telegram_bot_username'] = $data['telegram_bot_username']; + } + + if (isset($data['telegram_webhook_url'])) { + $this->settingsService->set( + 'telegram_webhook_url', + $data['telegram_webhook_url'], + $dealershipId, + 'string', + 'Telegram Webhook URL' + ); + $updated['telegram_webhook_url'] = $data['telegram_webhook_url']; + } + + if (isset($data['notification_enabled'])) { + $this->settingsService->set( + 'notification_enabled', + $data['notification_enabled'], + $dealershipId, + 'boolean', + 'Enable/disable notifications' + ); + $updated['notification_enabled'] = $data['notification_enabled']; + } + + // Handle shift settings when sent to bot-config endpoint + if (isset($data['shift_start_time'])) { + $this->settingsService->set( + 'shift_1_start_time', + $data['shift_start_time'], + $dealershipId, + 'time', + 'Shift start time' + ); + $updated['shift_start_time'] = $data['shift_start_time']; + } + + if (isset($data['shift_end_time'])) { + $this->settingsService->set( + 'shift_1_end_time', + $data['shift_end_time'], + $dealershipId, + 'time', + 'Shift end time' + ); + $updated['shift_end_time'] = $data['shift_end_time']; + } + + if (isset($data['late_tolerance_minutes'])) { + $this->settingsService->set( + 'late_tolerance_minutes', + $data['late_tolerance_minutes'], + $dealershipId, + 'integer', + 'Late tolerance in minutes' + ); + $updated['late_tolerance_minutes'] = $data['late_tolerance_minutes']; + } + } catch (\InvalidArgumentException $e) { + return response()->json([ + 'success' => false, + 'message' => 'Invalid setting value', + 'errors' => ['setting' => $e->getMessage()], + ], 422); + } + + return response()->json([ + 'success' => true, + 'message' => 'Bot configuration updated successfully', + 'data' => $updated, + ]); + } } diff --git a/routes/api.php b/routes/api.php index 4f52ef7..0a399a5 100644 --- a/routes/api.php +++ b/routes/api.php @@ -108,10 +108,13 @@ // Settings (read-only for observers) Route::get('/settings', [SettingsController::class, 'index']); Route::get('/settings/shift-config', [SettingsController::class, 'getShiftConfig']); + Route::get('/settings/bot-config', [SettingsController::class, 'getBotConfig']); Route::get('/settings/{key}', [SettingsController::class, 'show']); // Only managers and owners can modify settings - Route::put('/settings/shift-config', [SettingsController::class, 'updateShiftConfig']) + Route::post('/settings/shift-config', [SettingsController::class, 'updateShiftConfig']) + ->middleware('role:manager,owner'); + Route::post('/settings/bot-config', [SettingsController::class, 'updateBotConfig']) ->middleware('role:manager,owner'); Route::post('/settings', [SettingsController::class, 'store']) ->middleware('role:manager,owner'); diff --git a/swagger.yaml b/swagger.yaml index 785e19d..f2b4ae4 100644 --- a/swagger.yaml +++ b/swagger.yaml @@ -3099,7 +3099,7 @@ paths: schema: $ref: '#/components/schemas/Error' - put: + post: tags: - Settings summary: Обновить конфигурацию смен @@ -3187,6 +3187,180 @@ paths: errors: type: object + /settings/bot-config: + get: + tags: + - Settings + summary: Получить конфигурацию бота + description: Получение настроек Telegram бота и смен + operationId: getBotConfig + security: + - bearerAuth: [] + parameters: + - name: dealership_id + in: query + description: ID автосалона (если не указан, возвращается глобальная конфигурация) + schema: + type: integer + example: 1 + responses: + '200': + description: Конфигурация бота + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: object + properties: + telegram_bot_id: + type: string + nullable: true + example: "123456789:ABCdefGHIjklMNOpqrsTUVwxyz" + telegram_bot_username: + type: string + nullable: true + example: "taskmate_bot" + telegram_webhook_url: + type: string + format: uri + nullable: true + example: "https://example.com/api/webhook" + notification_enabled: + type: boolean + example: true + shift_1_start_time: + type: string + format: time + example: "09:00" + description: Время начала первой смены + shift_1_end_time: + type: string + format: time + example: "18:00" + description: Время окончания первой смены + shift_2_start_time: + type: string + format: time + example: "18:00" + description: Время начала второй смены + shift_2_end_time: + type: string + format: time + example: "02:00" + description: Время окончания второй смены + late_tolerance_minutes: + type: integer + example: 15 + description: Допустимое время опоздания в минутах + '401': + description: Неавторизован + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + + post: + tags: + - Settings + summary: Обновить конфигурацию бота + description: Обновление настроек Telegram бота и смен + operationId: updateBotConfig + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + telegram_bot_id: + type: string + nullable: true + description: Telegram Bot ID + example: "123456789:ABCdefGHIjklMNOpqrsTUVwxyz" + telegram_bot_username: + type: string + nullable: true + description: Telegram Bot Username + example: "taskmate_bot" + telegram_webhook_url: + type: string + format: uri + nullable: true + description: Telegram Webhook URL + example: "https://example.com/api/webhook" + notification_enabled: + type: boolean + nullable: true + description: Включить/выключить уведомления + example: true + shift_start_time: + type: string + format: time + nullable: true + description: Время начала смены (формат HH:MM) + example: "09:00" + shift_end_time: + type: string + format: time + nullable: true + description: Время окончания смены (формат HH:MM) + example: "18:00" + late_tolerance_minutes: + type: integer + nullable: true + description: Допустимое время опоздания в минутах + example: 15 + dealership_id: + type: integer + nullable: true + example: 1 + responses: + '200': + description: Конфигурация бота успешно обновлена + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + message: + type: string + example: Bot configuration updated successfully + data: + type: object + additionalProperties: + oneOf: + - type: string + - type: boolean + - type: integer + '401': + description: Неавторизован + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '422': + description: Ошибка валидации + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: false + errors: + type: object + /webhook: post: tags: