rancher check unique - pos free products check unique - 500 error handling
This commit is contained in:
@@ -26,7 +26,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
|
|||||||
SECRET_KEY = 'django-insecure-@0apn-lk85pfw=z00x2ib$w9#rwz8%2v4i_n^^9jz-m9b+y55*'
|
SECRET_KEY = 'django-insecure-@0apn-lk85pfw=z00x2ib$w9#rwz8%2v4i_n^^9jz-m9b+y55*'
|
||||||
|
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = True
|
DEBUG = False
|
||||||
|
|
||||||
sentry_sdk.init(
|
sentry_sdk.init(
|
||||||
dsn="https://e8d8ff4f1bf729370af00b7775be441c@o4509597964697600.ingest.us.sentry.io/4509597966073856",
|
dsn="https://e8d8ff4f1bf729370af00b7775be441c@o4509597964697600.ingest.us.sentry.io/4509597966073856",
|
||||||
@@ -98,6 +98,7 @@ INSTALLED_APPS = [
|
|||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
"corsheaders.middleware.CorsMiddleware",
|
"corsheaders.middleware.CorsMiddleware",
|
||||||
'django.middleware.security.SecurityMiddleware',
|
'django.middleware.security.SecurityMiddleware',
|
||||||
|
'apps.core.middlewares.Json500Middleware',
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
'django.middleware.common.CommonMiddleware',
|
'django.middleware.common.CommonMiddleware',
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
@@ -110,7 +111,7 @@ MIDDLEWARE = [
|
|||||||
'apps.pos_device.middlewares.PosDeviceValidationMiddleware'
|
'apps.pos_device.middlewares.PosDeviceValidationMiddleware'
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'Rasaddam_Backend.urls'
|
ROOT_URLCONF = 'Rasaddam_Backend.urls' # noqa
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
@@ -196,7 +197,7 @@ REST_FRAMEWORK = {
|
|||||||
'django_filters.rest_framework.DjangoFilterBackend',
|
'django_filters.rest_framework.DjangoFilterBackend',
|
||||||
'rest_framework.filters.SearchFilter',
|
'rest_framework.filters.SearchFilter',
|
||||||
],
|
],
|
||||||
# 'EXCEPTION_HANDLER': 'apps.core.error_handler.custom_exception_handler',
|
'EXCEPTION_HANDLER': 'apps.core.error_handler.custom_exception_handler',
|
||||||
"DEFAULT_PAGINATION_CLASS": 'apps.core.pagination.CustomPageNumberPagination',
|
"DEFAULT_PAGINATION_CLASS": 'apps.core.pagination.CustomPageNumberPagination',
|
||||||
"PAGE_SIZE": 20,
|
"PAGE_SIZE": 20,
|
||||||
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema'
|
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema'
|
||||||
@@ -261,7 +262,7 @@ CHANNEL_LAYERS = {
|
|||||||
"default": {
|
"default": {
|
||||||
"BACKEND": "channels_redis.core.RedisChannelLayer",
|
"BACKEND": "channels_redis.core.RedisChannelLayer",
|
||||||
"CONFIG": {
|
"CONFIG": {
|
||||||
"hosts": [("redis://:ydnW4hwzuDRYcTX3FWCHgQ1f@apo.liara.cloud:33740/0")],
|
"hosts": [("redis://:ydnW4hwzuDRYcTX3FWCHgQ1f@apo.liara.cloud:33740/0")], # noqa
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -286,8 +287,8 @@ ELASTICSEARCH_DSL = {
|
|||||||
# liara elastic password uYkiQ860vLW8DIbWpNjqtz2B # noqa
|
# liara elastic password uYkiQ860vLW8DIbWpNjqtz2B # noqa
|
||||||
# local system password =z66+LCIebq4NQRR_+=R # noqa
|
# local system password =z66+LCIebq4NQRR_+=R # noqa
|
||||||
"default": {
|
"default": {
|
||||||
"hosts": "http://monte-rosa.liara.cloud:31157",
|
"hosts": "http://monte-rosa.liara.cloud:31157", # noqa
|
||||||
"http_auth": ("elastic", "uYkiQ860vLW8DIbWpNjqtz2B"),
|
"http_auth": ("elastic", "uYkiQ860vLW8DIbWpNjqtz2B"), # noqa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,7 +451,6 @@ JAZZMIN_SETTINGS = {
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
|
|
||||||
# Custom icons for side menu apps/models See https://fontawesome.com/icons?d=gallery&m=free&v=5.0.0,5.0.1,5.0.10,5.0.11,5.0.12,5.0.13,5.0.2,5.0.3,5.0.4,5.0.5,5.0.6,5.0.7,5.0.8,5.0.9,5.1.0,5.1.1,5.2.0,5.3.0,5.3.1,5.4.0,5.4.1,5.4.2,5.13.0,5.12.0,5.11.2,5.11.1,5.10.0,5.9.0,5.8.2,5.8.1,5.7.2,5.7.1,5.7.0,5.6.3,5.5.0,5.4.2
|
|
||||||
# for the full list of 5.13.0 free icon classes
|
# for the full list of 5.13.0 free icon classes
|
||||||
"icons": {
|
"icons": {
|
||||||
"auth": "fas fa-users-cog",
|
"auth": "fas fa-users-cog",
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
from rest_framework.views import exception_handler
|
from rest_framework.views import exception_handler
|
||||||
|
from django.conf import settings
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
|
||||||
def custom_exception_handler(exc, context):
|
def custom_exception_handler(exc, context):
|
||||||
@@ -11,6 +13,13 @@ def custom_exception_handler(exc, context):
|
|||||||
response.data['message'] = response.data.get('detail', str(exc))
|
response.data['message'] = response.data.get('detail', str(exc))
|
||||||
del response.data['detail']
|
del response.data['detail']
|
||||||
else:
|
else:
|
||||||
response = JsonResponse({'message': str(exc), 'status_code': 500})
|
if settings.DEBUG:
|
||||||
|
raise
|
||||||
|
response = JsonResponse({
|
||||||
|
"message": str(exc),
|
||||||
|
"status_code": 500,
|
||||||
|
"error_type": exc.__class__.__name__,
|
||||||
|
"traceback": traceback.format_exc().splitlines(),
|
||||||
|
}, status=500)
|
||||||
response.status_code = 500
|
response.status_code = 500
|
||||||
return response
|
return response
|
||||||
|
|||||||
@@ -1,60 +1,29 @@
|
|||||||
from rest_framework.exceptions import APIException
|
from rest_framework.exceptions import APIException
|
||||||
|
from django.http import JsonResponse
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
import traceback
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
def terminal_width():
|
class Json500Middleware:
|
||||||
"""
|
""" return all 500 status errors in json response """
|
||||||
Function to compute the terminal width.
|
|
||||||
WARNING: This is not my code, but I've been using it forever and
|
|
||||||
I don't remember where it came from.
|
|
||||||
"""
|
|
||||||
width = 0
|
|
||||||
try:
|
|
||||||
import struct, fcntl, termios
|
|
||||||
s = struct.pack('HHHH', 0, 0, 0, 0)
|
|
||||||
x = fcntl.ioctl(1, termios.TIOCGWINSZ, s)
|
|
||||||
width = struct.unpack('HHHH', x)[1]
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
if width <= 0:
|
|
||||||
try:
|
|
||||||
width = int(os.environ['COLUMNS'])
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
if width <= 0:
|
|
||||||
width = 80
|
|
||||||
return width
|
|
||||||
|
|
||||||
|
|
||||||
class SqlPrintingMiddleware(object):
|
|
||||||
"""
|
|
||||||
Middleware which prints out a list of all SQL queries done
|
|
||||||
for each view that is processed. This is only useful for debugging.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, get_response):
|
def __init__(self, get_response):
|
||||||
self.get_response = get_response
|
self.get_response = get_response
|
||||||
|
|
||||||
def __call__(self, request):
|
def __call__(self, request, *args, **kwargs):
|
||||||
return self.process_response(request=request, response=self.get_response(request))
|
try:
|
||||||
|
return self.get_response(request)
|
||||||
|
except Exception as exc:
|
||||||
|
|
||||||
def process_response(self, request, response): # noqa
|
if settings.DEBUG:
|
||||||
indentation = 2
|
raise
|
||||||
if len(connection.queries) > 0 and settings.DEBUG:
|
|
||||||
width = terminal_width()
|
return JsonResponse({
|
||||||
total_time = 0.0
|
"message": str(exc),
|
||||||
for query in connection.queries:
|
"status_code": 500,
|
||||||
nice_sql = query['sql'].replace('"', '').replace(',', ', ')
|
"error_type": exc.__class__.__name__,
|
||||||
sql = "\033[1;31m[%s]\033[0m %s" % (query['time'], nice_sql)
|
"traceback": traceback.format_exc().splitlines(),
|
||||||
total_time = total_time + float(query['time'])
|
}, status=500)
|
||||||
while len(sql) > width - indentation:
|
|
||||||
print("%s%s" % (" " * indentation, sql[:width - indentation]))
|
|
||||||
sql = sql[width - indentation:]
|
|
||||||
print("%s%s\n" % (" " * indentation, sql))
|
|
||||||
replace_tuple = (" " * indentation, str(total_time))
|
|
||||||
print("%s\033[1;32m[TOTAL TIME: %s seconds]\033[0m" % replace_tuple)
|
|
||||||
print(response)
|
|
||||||
return response
|
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
from apps.herd.web.api.v1.serializers import HerdSerializer, RancherSerializer
|
from apps.herd.pos.api.v1.serializers import HerdSerializer, RancherSerializer
|
||||||
from apps.livestock.web.api.v1.serializers import LiveStockSerializer
|
from apps.livestock.web.api.v1.serializers import LiveStockSerializer
|
||||||
from apps.herd.services.services import (
|
|
||||||
get_rancher_statistics,
|
|
||||||
rancher_quota_weight
|
|
||||||
)
|
|
||||||
from apps.warehouse.models import InventoryEntry
|
|
||||||
from apps.core.mixins.search_mixin import DynamicSearchMixin
|
from apps.core.mixins.search_mixin import DynamicSearchMixin
|
||||||
from rest_framework.exceptions import APIException
|
from rest_framework.exceptions import APIException
|
||||||
from rest_framework.permissions import AllowAny
|
from rest_framework.permissions import AllowAny
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ class RancherSerializer(serializers.ModelSerializer):
|
|||||||
if self.Meta.model.objects.filter(national_code=attrs['national_code']).exists():
|
if self.Meta.model.objects.filter(national_code=attrs['national_code']).exists():
|
||||||
raise UniqueRancherApiException()
|
raise UniqueRancherApiException()
|
||||||
|
|
||||||
|
return attrs
|
||||||
|
|
||||||
def to_representation(self, instance):
|
def to_representation(self, instance):
|
||||||
""" customize output of serializer """
|
""" customize output of serializer """
|
||||||
|
|
||||||
|
|||||||
@@ -35,3 +35,13 @@ class QuotaLimitByOrganizationException(APIException):
|
|||||||
status_code = status.HTTP_400_BAD_REQUEST
|
status_code = status.HTTP_400_BAD_REQUEST
|
||||||
default_detail = "سازمان انتخاب شده در بین سامان های انتخاب شده برای توزیع سهمیه وجود ندارد" # noqa
|
default_detail = "سازمان انتخاب شده در بین سامان های انتخاب شده برای توزیع سهمیه وجود ندارد" # noqa
|
||||||
default_code = 'error'
|
default_code = 'error'
|
||||||
|
|
||||||
|
|
||||||
|
class FreePOSProductUniqueCheck(APIException):
|
||||||
|
"""
|
||||||
|
raise exception for free pos products to be unique
|
||||||
|
"""
|
||||||
|
|
||||||
|
status_code = status.HTTP_403_FORBIDDEN
|
||||||
|
default_detail = "محصول مورد نظر برای این دستگاه از قبل ثبت شده است" # noqa
|
||||||
|
default_code = 'error'
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from apps.product import models as product_models
|
from apps.product import models as product_models
|
||||||
from apps.pos_device.models import POSFreeProducts
|
from apps.pos_device.models import POSFreeProducts
|
||||||
from apps.authorization.api.v1 import serializers as authorize_serializers
|
from apps.authentication.api.v1.serializers.serializer import OrganizationTypeSerializer
|
||||||
from apps.authentication.api.v1.serializers.serializer import OrganizationSerializer, OrganizationTypeSerializer
|
from apps.product.exceptions import FreePOSProductUniqueCheck
|
||||||
|
|
||||||
|
|
||||||
class POSFreeProductSerializer(serializers.ModelSerializer):
|
class POSFreeProductSerializer(serializers.ModelSerializer):
|
||||||
@@ -10,6 +10,18 @@ class POSFreeProductSerializer(serializers.ModelSerializer):
|
|||||||
model = POSFreeProducts
|
model = POSFreeProducts
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
def validate(self, attrs):
|
||||||
|
"""
|
||||||
|
@check free product for pos to be unique
|
||||||
|
"""
|
||||||
|
organization = attrs['organization']
|
||||||
|
product = attrs['product']
|
||||||
|
|
||||||
|
if self.Meta.model.objects.filter(organization=organization, product=product).exists():
|
||||||
|
raise FreePOSProductUniqueCheck()
|
||||||
|
|
||||||
|
return attrs
|
||||||
|
|
||||||
def to_representation(self, instance):
|
def to_representation(self, instance):
|
||||||
representation = super().to_representation(instance)
|
representation = super().to_representation(instance)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user