128 lines
5.0 KiB
Python
128 lines
5.0 KiB
Python
|
|
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
|
|||
|
|
|