import time import logging import requests from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status, viewsets from .models import Nomenclature, Sticker, StickerMovement from .serializers import NomenclatureSerializer, StickerSerializer, StickerMovementSerializer # Авторизационные данные USERNAME = "superuser" PASSWORD = "Superuser1105" TOKEN_URL = "http://192.168.254.2:8280/api/login" # URL для получения токена PRODUCT_LIST_URL = "http://192.168.254.2:8280/api/ProductType/list" # Глобальный кэш для хранения токена token_cache = {"token": None, "timestamp": 0} TOKEN_LIFETIME = 1440 * 60 # 24 часа в секундах def get_new_token(): """Получение нового токена с кешированием.""" global token_cache current_time = time.time() # Если токен есть и он еще не истек, возвращаем его if token_cache["token"] and (current_time - token_cache["timestamp"] < TOKEN_LIFETIME): return token_cache["token"] payload = {"UserName": USERNAME, "Password": PASSWORD} try: response = requests.post(TOKEN_URL, json=payload, timeout=5) response_data = response.json() if response.status_code == 200 and response_data.get("IsSuccess"): token_cache["token"] = response_data["Value"]["Token"] token_cache["timestamp"] = current_time return token_cache["token"] logging.error(f"Ошибка получения токена: {response_data}") return None except requests.RequestException as e: logging.error(f"Ошибка сети при получении токена: {str(e)}") return None class ExternalNomenclatureView(APIView): """Получение списка номенклатур с внешнего API.""" def post(self, request): product_line_id = request.data.get("product_line_id", "40ba525b-1686-4900-a2a9-443436812b1d") token = get_new_token() if not token: return Response({"error": "Ошибка авторизации"}, status=status.HTTP_401_UNAUTHORIZED) headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} payload = { "Filter": { "Filters": [ { "Logic": "and", "Operator": "linq", "Field": "ProductType_ProductLines.Where(i=>i.ProductLineId=='{0}').Any()", "Value": product_line_id, } ], "Logic": "and", }, "Includes": ["ProductType_ProductLines"], } try: response = requests.post(PRODUCT_LIST_URL, json=payload, headers=headers, timeout=10) response.raise_for_status() return Response(response.json(), status=status.HTTP_200_OK) except requests.RequestException as e: logging.error(f"Ошибка запроса {PRODUCT_LIST_URL}: {str(e)}") return Response({"error": "Ошибка запроса к API"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) # Основные API ViewSet'ы class NomenclatureViewSet(viewsets.ModelViewSet): queryset = Nomenclature.objects.all() serializer_class = NomenclatureSerializer class StickerViewSet(viewsets.ModelViewSet): queryset = Sticker.objects.all().select_related('nomenclature') serializer_class = StickerSerializer def create(self, request, *args, **kwargs): data = request.data gtin = data.get("nomenclature_gtin") # Берем GTIN из запроса if not gtin: return Response({"error": "GTIN обязателен"}, status=status.HTTP_400_BAD_REQUEST) # Проверяем, есть ли номенклатура с таким GTIN nomenclature, created = Nomenclature.objects.get_or_create( gtin=gtin, defaults={"name": data.get("nomenclature_name", "Неизвестный продукт")} ) # Обновляем данные запроса, чтобы стикер использовал ID найденной/созданной номенклатуры data["nomenclature"] = nomenclature.id serializer = self.get_serializer(data=data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def destroy(self, request, *args, **kwargs): instance = self.get_object() self.perform_destroy(instance) return Response({"message": "Стикер успешно удалён"}, status=status.HTTP_204_NO_CONTENT) class StickerMovementViewSet(viewsets.ModelViewSet): queryset = StickerMovement.objects.all() serializer_class = StickerMovementSerializer