backend/inventory/views.py

123 lines
5.0 KiB
Python
Raw Normal View History

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