{
	"info": {
		"_postman_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
		"name": "Vending Machines Management API",
		"description": "REST API для управления торговыми автоматами, компаниями и мониторинга состояния сети.\n\n## Базовый URL\n`http://127.0.0.1:8000`\n\n## Авторизация\nИспользуется JWT токен. Получите токен через `/login` и используйте его в заголовке `Authorization: Bearer <token>`\n\n## Переменные коллекции\n- `base_url` - базовый URL API\n- `access_token` - JWT токен доступа\n- `vending_machine_id` - ID торгового автомата\n- `company_id` - ID компании",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
	},
	"item": [
		{
			"name": "Авторизация",
			"item": [
				{
					"name": "Регистрация пользователя",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"// Проверка статуса ответа",
									"pm.test(\"Status code is 200\", function () {",
									"    pm.response.to.have.status(200);",
									"});",
									"",
									"// Проверка структуры ответа",
									"pm.test(\"Response has status field\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData).to.have.property('status');",
									"    pm.expect(jsonData.status).to.eql('ok');",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"email\": \"newuser@example.com\",\n    \"password\": \"securepassword123\"\n}"
						},
						"url": {
							"raw": "{{base_url}}/register",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"register"
							]
						},
						"description": "Регистрация нового пользователя в системе.\n\n**Тело запроса:**\n- `email` (string, required) - Email пользователя\n- `password` (string, required) - Пароль пользователя\n\n**Ответ:**\n```json\n{\n    \"status\": \"ok\"\n}\n```"
					},
					"response": []
				},
				{
					"name": "Авторизация (Login)",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"// Проверка успешного ответа",
									"pm.test(\"Status code is 200\", function () {",
									"    pm.response.to.have.status(200);",
									"});",
									"",
									"// Проверка наличия токена",
									"pm.test(\"Response contains access_token\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData).to.have.property('access_token');",
									"    ",
									"    // Сохраняем токен в переменную коллекции",
									"    pm.collectionVariables.set(\"access_token\", jsonData.access_token);",
									"});",
									"",
									"// Проверка формата токена",
									"pm.test(\"Token is not empty\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData.access_token).to.be.a('string');",
									"    pm.expect(jsonData.access_token.length).to.be.above(0);",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"email\": \"test@example.com\",\n    \"password\": \"123456\"\n}"
						},
						"url": {
							"raw": "{{base_url}}/login",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"login"
							]
						},
						"description": "Авторизация пользователя с получением JWT токена.\n\n**Тело запроса:**\n- `email` (string, required) - Email пользователя\n- `password` (string, required) - Пароль пользователя\n\n**Ответ:**\n```json\n{\n    \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\"\n}\n```\n\n**Примечание:** Токен автоматически сохраняется в переменную `access_token` для использования в других запросах."
					},
					"response": []
				}
			],
			"description": "Endpoints для управления авторизацией пользователей"
		},
		{
			"name": "Торговые автоматы",
			"item": [
				{
					"name": "Получить список торговых автоматов",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"// Проверка статуса",
									"pm.test(\"Status code is 200\", function () {",
									"    pm.response.to.have.status(200);",
									"});",
									"",
									"// Проверка что ответ - массив",
									"pm.test(\"Response is an array\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData).to.be.an('array');",
									"});",
									"",
									"// Проверка структуры объектов",
									"pm.test(\"Machines have required fields\", function () {",
									"    var jsonData = pm.response.json();",
									"    if (jsonData.length > 0) {",
									"        var machine = jsonData[0];",
									"        pm.expect(machine).to.have.property('id');",
									"        pm.expect(machine).to.have.property('model');",
									"        pm.expect(machine).to.have.property('location');",
									"        pm.expect(machine).to.have.property('equipment_status');",
									"        ",
									"        // Сохраняем ID первого автомата",
									"        pm.collectionVariables.set(\"vending_machine_id\", machine.id);",
									"    }",
									"});",
									"",
									"// Проверка типов данных",
									"pm.test(\"Machine fields have correct types\", function () {",
									"    var jsonData = pm.response.json();",
									"    if (jsonData.length > 0) {",
									"        var machine = jsonData[0];",
									"        pm.expect(machine.id).to.be.a('number');",
									"        pm.expect(machine.model).to.be.a('string');",
									"        pm.expect(machine.location).to.be.a('string');",
									"    }",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/machines",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"machines"
							]
						},
						"description": "Получение списка всех торговых автоматов в системе.\n\n**Ответ:**\n```json\n[\n    {\n        \"id\": 1,\n        \"serial_number\": 1001,\n        \"inventory_number\": 2001,\n        \"model\": \"VM-2000X\",\n        \"manufacturer\": \"VendoTech\",\n        \"country\": \"Japan\",\n        \"type\": \"Snacks\",\n        \"location\": \"ТЦ Мега, 1 этаж\",\n        \"resource_hours\": 15000,\n        \"hours_worked\": 5000,\n        \"equipment_status\": \"Работает\",\n        \"last_service_date\": \"2025-10-08\",\n        \"next_service_date\": \"2026-04-08\"\n    }\n]\n```"
					},
					"response": []
				},
				{
					"name": "Загрузить торговые автоматы из файла",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"// Проверка успешной загрузки",
									"pm.test(\"Status code is 200\", function () {",
									"    pm.response.to.have.status(200);",
									"});",
									"",
									"// Проверка структуры ответа",
									"pm.test(\"Response has required fields\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData).to.have.property('status');",
									"    pm.expect(jsonData).to.have.property('added_count');",
									"    pm.expect(jsonData).to.have.property('updated_count');",
									"    pm.expect(jsonData).to.have.property('errors');",
									"});",
									"",
									"// Проверка отсутствия ошибок",
									"pm.test(\"No errors in upload\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData.errors).to.be.an('array');",
									"    pm.expect(jsonData.errors.length).to.equal(0);",
									"});",
									"",
									"// Проверка что данные загружены",
									"pm.test(\"At least one machine added or updated\", function () {",
									"    var jsonData = pm.response.json();",
									"    var total = jsonData.added_count + jsonData.updated_count;",
									"    pm.expect(total).to.be.above(0);",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"file_content\": \"c2VyaWFsX251bWJlcixpbnZlbnRvcnlfbnVtYmVyLG1vZGVsLG1hbnVmYWN0dXJlcixjb3VudHJ5LHR5cGUsbG9jYXRpb24scmVzb3VyY2VfaG91cnMKMjAwMSwzMDAxLFZNLTIwMDBYLFZlbmRvVGVjaCxKYXBhbixTbmFja3Ms0KLQpiDQk9Cw0LvQtdGA0LXRjywxNTAwMAoyMDAyLDMwMDIsVk0tMzAwMFksQXV0b1ZlbmQsR2VybWFueSxEcmlua3Ms0J7RhNC40YEg0JHQpiDQkNC70YzRhNCwLDEyMDAw\",\n    \"filename\": \"test_machines.csv\"\n}"
						},
						"url": {
							"raw": "{{base_url}}/upload-machines",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"upload-machines"
							]
						},
						"description": "Загрузка торговых автоматов из CSV/XLSX файла в кодировке base64.\n\n**Тело запроса:**\n- `file_content` (string, required) - Содержимое файла в base64\n- `filename` (string, required) - Имя файла (должно заканчиваться на .csv или .xlsx)\n\n**Проверки:**\n1. Формат файла (только .xlsx, .csv)\n2. Обязательные поля (serial_number, inventory_number, model, manufacturer, country, type)\n3. Корректность значений\n4. Дубликаты в БД\n\n**Ответ:**\n```json\n{\n    \"status\": \"success\",\n    \"added_count\": 5,\n    \"updated_count\": 2,\n    \"errors\": []\n}\n```"
					},
					"response": []
				}
			],
			"description": "Управление торговыми автоматами"
		},
		{
			"name": "Мониторинг состояния сети",
			"item": [
				{
					"name": "Получить эффективность сети",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"// Проверка статуса",
									"pm.test(\"Status code is 200\", function () {",
									"    pm.response.to.have.status(200);",
									"});",
									"",
									"// Проверка структуры ответа",
									"pm.test(\"Response has required fields\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData).to.have.property('efficiency');",
									"    pm.expect(jsonData).to.have.property('total_machines');",
									"    pm.expect(jsonData).to.have.property('working_machines');",
									"    pm.expect(jsonData).to.have.property('broken_machines');",
									"    pm.expect(jsonData).to.have.property('maintenance_machines');",
									"});",
									"",
									"// Проверка диапазона эффективности",
									"pm.test(\"Efficiency is between 0 and 100\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData.efficiency).to.be.at.least(0);",
									"    pm.expect(jsonData.efficiency).to.be.at.most(100);",
									"});",
									"",
									"// Проверка корректности подсчета",
									"pm.test(\"Total equals sum of statuses\", function () {",
									"    var jsonData = pm.response.json();",
									"    var sum = jsonData.working_machines + jsonData.broken_machines + jsonData.maintenance_machines;",
									"    pm.expect(jsonData.total_machines).to.equal(sum);",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/network-status",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"network-status"
							]
						},
						"description": "Получение статистики по состоянию сети торговых автоматов.\n\n**Ответ:**\n```json\n{\n    \"efficiency\": 80.0,\n    \"total_machines\": 10,\n    \"working_machines\": 8,\n    \"broken_machines\": 1,\n    \"maintenance_machines\": 1\n}\n```\n\n**Расчет эффективности:**\n```\nefficiency = (working_machines / total_machines) * 100\n```"
					},
					"response": []
				},
				{
					"name": "Получить сводку",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"// Проверка статуса",
									"pm.test(\"Status code is 200\", function () {",
									"    pm.response.to.have.status(200);",
									"});",
									"",
									"// Проверка всех полей сводки",
									"pm.test(\"Summary has all required fields\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData).to.have.property('money_in_machines');",
									"    pm.expect(jsonData).to.have.property('collection_incoming');",
									"    pm.expect(jsonData).to.have.property('revenue_today');",
									"    pm.expect(jsonData).to.have.property('revenue_yesterday');",
									"    pm.expect(jsonData).to.have.property('maintenance_planned_hours');",
									"    pm.expect(jsonData).to.have.property('maintenance_unplanned_hours');",
									"    pm.expect(jsonData).to.have.property('support_requests_today');",
									"});",
									"",
									"// Проверка типов данных",
									"pm.test(\"All financial fields are numbers\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData.money_in_machines).to.be.a('number');",
									"    pm.expect(jsonData.collection_incoming).to.be.a('number');",
									"    pm.expect(jsonData.revenue_today).to.be.a('number');",
									"    pm.expect(jsonData.revenue_yesterday).to.be.a('number');",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/summary",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"summary"
							]
						},
						"description": "Получение сводной информации по продажам, инкассации и обслуживанию.\n\n**Ответ:**\n```json\n{\n    \"money_in_machines\": 200000,\n    \"collection_incoming\": 150000,\n    \"revenue_today\": 52000,\n    \"revenue_yesterday\": 51000,\n    \"maintenance_planned_hours\": 12,\n    \"maintenance_unplanned_hours\": 17,\n    \"support_requests_today\": 3\n}\n```"
					},
					"response": []
				},
				{
					"name": "Получить уведомления",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"// Проверка статуса",
									"pm.test(\"Status code is 200\", function () {",
									"    pm.response.to.have.status(200);",
									"});",
									"",
									"// Проверка структуры",
									"pm.test(\"Response has notifications array\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData).to.have.property('notifications');",
									"    pm.expect(jsonData.notifications).to.be.an('array');",
									"});",
									"",
									"// Проверка структуры уведомлений",
									"pm.test(\"Notifications have required fields\", function () {",
									"    var jsonData = pm.response.json();",
									"    if (jsonData.notifications.length > 0) {",
									"        var notif = jsonData.notifications[0];",
									"        pm.expect(notif).to.have.property('type');",
									"        pm.expect(notif).to.have.property('title');",
									"        pm.expect(notif).to.have.property('message');",
									"        pm.expect(notif).to.have.property('vending_machine_id');",
									"        pm.expect(notif).to.have.property('requires_confirmation');",
									"    }",
									"});",
									"",
									"// Проверка типов уведомлений",
									"pm.test(\"Notification types are valid\", function () {",
									"    var jsonData = pm.response.json();",
									"    var validTypes = ['critical', 'warning', 'info'];",
									"    jsonData.notifications.forEach(function(notif) {",
									"        pm.expect(validTypes).to.include(notif.type);",
									"    });",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/notifications",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"notifications"
							]
						},
						"description": "Получение списка уведомлений о состоянии торговых автоматов.\n\n**Типы уведомлений:**\n- `critical` - Критические ошибки (поломки, отсутствие товара)\n- `warning` - Предупреждения (низкий запас, приближающееся ТО)\n- `info` - Информационные сообщения (статистика продаж)\n\n**Ответ:**\n```json\n{\n    \"notifications\": [\n        {\n            \"type\": \"critical\",\n            \"title\": \"Критическая ошибка\",\n            \"message\": \"Автомат 'ТЦ Мега' не работает!\",\n            \"vending_machine_id\": 7,\n            \"timestamp\": \"2026-02-08T10:30:00\",\n            \"requires_confirmation\": true\n        }\n    ]\n}\n```"
					},
					"response": []
				},
				{
					"name": "Получить динамику продаж",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"// Проверка статуса",
									"pm.test(\"Status code is 200\", function () {",
									"    pm.response.to.have.status(200);",
									"});",
									"",
									"// Проверка структуры",
									"pm.test(\"Response has sales array\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData).to.have.property('sales');",
									"    pm.expect(jsonData.sales).to.be.an('array');",
									"});",
									"",
									"// Проверка данных продаж",
									"pm.test(\"Sales have date and value\", function () {",
									"    var jsonData = pm.response.json();",
									"    if (jsonData.sales.length > 0) {",
									"        var sale = jsonData.sales[0];",
									"        pm.expect(sale).to.have.property('date');",
									"        pm.expect(sale).to.have.property('value');",
									"        pm.expect(sale.value).to.be.a('number');",
									"    }",
									"});",
									"",
									"// Проверка максимум 10 дней",
									"pm.test(\"Sales data is for max 10 days\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData.sales.length).to.be.at.most(10);",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/sales-dynamics?by_amount=true",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"sales-dynamics"
							],
							"query": [
								{
									"key": "by_amount",
									"value": "true",
									"description": "true - по сумме, false - по количеству"
								}
							]
						},
						"description": "Получение динамики продаж за последние 10 дней.\n\n**Параметры запроса:**\n- `by_amount` (boolean) - true для суммы продаж, false для количества транзакций\n\n**Ответ:**\n```json\n{\n    \"sales\": [\n        {\n            \"date\": \"2026-02-01\",\n            \"value\": 45000\n        },\n        {\n            \"date\": \"2026-02-02\",\n            \"value\": 52000\n        }\n    ]\n}\n```"
					},
					"response": []
				}
			],
			"description": "Мониторинг состояния сети торговых автоматов"
		},
		{
			"name": "Календарь и график работ",
			"item": [
				{
					"name": "Получить события календаря",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"// Проверка статуса",
									"pm.test(\"Status code is 200\", function () {",
									"    pm.response.to.have.status(200);",
									"});",
									"",
									"// Проверка что ответ - массив",
									"pm.test(\"Response is an array\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData).to.be.an('array');",
									"});",
									"",
									"// Проверка структуры событий",
									"pm.test(\"Events have required fields\", function () {",
									"    var jsonData = pm.response.json();",
									"    if (jsonData.length > 0) {",
									"        var event = jsonData[0];",
									"        pm.expect(event).to.have.property('id');",
									"        pm.expect(event).to.have.property('vending_machine_id');",
									"        pm.expect(event).to.have.property('machine_model');",
									"        pm.expect(event).to.have.property('machine_location');",
									"        pm.expect(event).to.have.property('service_date');",
									"        pm.expect(event).to.have.property('service_type');",
									"    }",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/calendar-events",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"calendar-events"
							]
						},
						"description": "Получение событий календаря обслуживания.\n\n**Алгоритмы формирования:**\n1. **Плановое ТО** - по интервалу (Дата следующего ТО = Дата последней проверки + Интервал)\n2. **ТО по ресурсу** - при достижении 80-90% от resource_hours\n\n**Ответ:**\n```json\n[\n    {\n        \"id\": 1,\n        \"vending_machine_id\": 1,\n        \"machine_model\": \"VM-2000X\",\n        \"machine_location\": \"ТЦ Мега\",\n        \"franchisee\": \"ООО Франчайзи\",\n        \"service_date\": \"2026-04-08\",\n        \"service_type\": \"Плановое ТО\",\n        \"reason\": \"Интервал 6 мес.\"\n    }\n]\n```"
					},
					"response": []
				},
				{
					"name": "Получить список сотрудников",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"// Проверка статуса",
									"pm.test(\"Status code is 200\", function () {",
									"    pm.response.to.have.status(200);",
									"});",
									"",
									"// Проверка массива",
									"pm.test(\"Response is an array\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData).to.be.an('array');",
									"});",
									"",
									"// Проверка полей сотрудников",
									"pm.test(\"Employees have required fields\", function () {",
									"    var jsonData = pm.response.json();",
									"    if (jsonData.length > 0) {",
									"        var emp = jsonData[0];",
									"        pm.expect(emp).to.have.property('id');",
									"        pm.expect(emp).to.have.property('name');",
									"        pm.expect(emp).to.have.property('models_can_service');",
									"    }",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/employees",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"employees"
							]
						},
						"description": "Получение списка сотрудников для назначения на заявки.\n\n**Ответ:**\n```json\n[\n    {\n        \"id\": 1,\n        \"name\": \"Иванов Иван\",\n        \"email\": \"ivanov@service.com\",\n        \"phone\": \"+7-900-111-22-33\",\n        \"position\": \"Инженер\",\n        \"models_can_service\": \"VM-2000X,VM-3000Y,VM-4000Z\"\n    }\n]\n```"
					},
					"response": []
				},
				{
					"name": "Получить заявки на обслуживание",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"// Проверка статуса",
									"pm.test(\"Status code is 200\", function () {",
									"    pm.response.to.have.status(200);",
									"});",
									"",
									"// Проверка структуры заявок",
									"pm.test(\"Requests have required fields\", function () {",
									"    var jsonData = pm.response.json();",
									"    if (jsonData.length > 0) {",
									"        var req = jsonData[0];",
									"        pm.expect(req).to.have.property('id');",
									"        pm.expect(req).to.have.property('vending_machine_id');",
									"        pm.expect(req).to.have.property('status');",
									"        pm.expect(req).to.have.property('priority');",
									"        pm.expect(req).to.have.property('scheduled_date');",
									"    }",
									"});",
									"",
									"// Проверка статусов",
									"pm.test(\"Status values are valid\", function () {",
									"    var jsonData = pm.response.json();",
									"    var validStatuses = ['Новая', 'В работе', 'Завершена', 'Авария'];",
									"    jsonData.forEach(function(req) {",
									"        pm.expect(validStatuses).to.include(req.status);",
									"    });",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "GET",
						"header": [],
						"url": {
							"raw": "{{base_url}}/service-requests",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"service-requests"
							]
						},
						"description": "Получение списка заявок на обслуживание.\n\n**Статусы заявок:**\n- `Новая` - создана, не назначена\n- `В работе` - назначена на сотрудника\n- `Завершена` - обслуживание выполнено\n- `Авария` - критическая заявка\n\n**Ответ:**\n```json\n[\n    {\n        \"id\": 1,\n        \"vending_machine_id\": 1,\n        \"employee_id\": 1,\n        \"status\": \"Новая\",\n        \"priority\": \"Обычная\",\n        \"scheduled_date\": \"2026-02-08\",\n        \"scheduled_time\": \"10:00:00\",\n        \"service_duration_hours\": 1,\n        \"travel_time_hours\": 2,\n        \"description\": \"Плановое ТО\"\n    }\n]\n```"
					},
					"response": []
				},
				{
					"name": "Обновить заявку (Drag & Drop)",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"// Проверка успешного обновления",
									"pm.test(\"Status code is 200\", function () {",
									"    pm.response.to.have.status(200);",
									"});",
									"",
									"// Проверка ответа",
									"pm.test(\"Response confirms update\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData).to.have.property('status');",
									"    pm.expect(jsonData.status).to.eql('success');",
									"    pm.expect(jsonData).to.have.property('updated_id');",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "PUT",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"employee_id\": 2,\n    \"scheduled_time\": \"14:00:00\",\n    \"scheduled_date\": \"2026-02-09\"\n}"
						},
						"url": {
							"raw": "{{base_url}}/service-requests/{{vending_machine_id}}",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"service-requests",
								"{{vending_machine_id}}"
							]
						},
						"description": "Обновление заявки при перетаскивании (drag-and-drop) в интерфейсе графика работ.\n\n**Тело запроса (необязательные поля):**\n- `employee_id` (int) - ID сотрудника\n- `scheduled_time` (string) - Время начала работы\n- `scheduled_date` (string) - Дата выполнения\n\n**Ответ:**\n```json\n{\n    \"status\": \"success\",\n    \"updated_id\": 1\n}\n```"
					},
					"response": []
				},
				{
					"name": "Подтвердить график работ",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"// Проверка статуса",
									"pm.test(\"Status code is 200\", function () {",
									"    pm.response.to.have.status(200);",
									"});",
									"",
									"// Проверка результата",
									"pm.test(\"Schedule confirmed successfully\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData).to.have.property('status');",
									"    pm.expect(jsonData.status).to.eql('success');",
									"    pm.expect(jsonData).to.have.property('updated_count');",
									"    pm.expect(jsonData.updated_count).to.be.a('number');",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/confirm-schedule",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"confirm-schedule"
							]
						},
						"description": "Подтверждение графика работ с обновлением статусов.\n\n**Действия:**\n1. Обновляет статусы заявок с 'Новая' на 'В работе'\n2. Обновляет статусы оборудования на 'В ремонте/на обслуживании'\n3. Сохраняет изменения в историю статусов\n\n**Ответ:**\n```json\n{\n    \"status\": \"success\",\n    \"updated_count\": 5\n}\n```"
					},
					"response": []
				},
				{
					"name": "Автоматическое назначение заявок",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"// Проверка статуса",
									"pm.test(\"Status code is 200\", function () {",
									"    pm.response.to.have.status(200);",
									"});",
									"",
									"// Проверка результата",
									"pm.test(\"Auto-assignment completed\", function () {",
									"    var jsonData = pm.response.json();",
									"    pm.expect(jsonData).to.have.property('status');",
									"    pm.expect(jsonData).to.have.property('assigned_count');",
									"    pm.expect(jsonData).to.have.property('warnings');",
									"    pm.expect(jsonData.warnings).to.be.an('array');",
									"});"
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [],
						"url": {
							"raw": "{{base_url}}/auto-assign-requests?period=week",
							"host": [
								"{{base_url}}"
							],
							"path": [
								"auto-assign-requests"
							],
							"query": [
								{
									"key": "period",
									"value": "week",
									"description": "day или week"
								}
							]
						},
						"description": "Автоматическое назначение заявок на сотрудников с учетом:\n\n**Алгоритм:**\n1. Специфика работы (модели, которые может обслуживать)\n2. Загруженность (не более 10 часов в день)\n3. Равномерное распределение (не более 40 часов в неделю)\n4. Приоритет аварийных заявок\n\n**Параметры:**\n- `period` (string) - \"day\" для текущего дня, \"week\" для недели\n\n**Ответ:**\n```json\n{\n    \"status\": \"success\",\n    \"assigned_count\": 8,\n    \"warnings\": [\n        {\n            \"request_id\": 5,\n            \"message\": \"Нет сотрудников для обслуживания VM-5000A\"\n        }\n    ]\n}\n```"
					},
					"response": []
				}
			],
			"description": "Календарь обслуживания и график работ сотрудников"
		}
	],
	"event": [
		{
			"listen": "prerequest",
			"script": {
				"type": "text/javascript",
				"exec": [
					""
				]
			}
		},
		{
			"listen": "test",
			"script": {
				"type": "text/javascript",
				"exec": [
					""
				]
			}
		}
	],
	"variable": [
		{
			"key": "base_url",
			"value": "http://127.0.0.1:8000",
			"type": "string"
		},
		{
			"key": "access_token",
			"value": "",
			"type": "string"
		},
		{
			"key": "vending_machine_id",
			"value": "1",
			"type": "string"
		},
		{
			"key": "company_id",
			"value": "1",
			"type": "string"
		}
	]
}