Fakultas Ilmu Komputer UI

Commit 330690cc authored by Bunga Amalia Kurniawati's avatar Bunga Amalia Kurniawati 🌺
Browse files

Merge branch 'bungamaku/15/fix-sonarqube' into 'dev'

Refactor and Fix Pilar-Be SonarQube issues

Closes #15

See merge request !15
parents 6e1eff1f cb2cad6e
Pipeline #78804 passed with stages
in 2 minutes and 25 seconds
...@@ -4,4 +4,8 @@ __pycache__/ ...@@ -4,4 +4,8 @@ __pycache__/
.env_var .env_var
static static
env env
.env .env
\ No newline at end of file .scannerwork
.vscode
coverage.xml
media
\ No newline at end of file
...@@ -303,7 +303,7 @@ def create_transaction_report(filter_params): # pylint: disable=too-many-locals ...@@ -303,7 +303,7 @@ def create_transaction_report(filter_params): # pylint: disable=too-many-locals
return buffer return buffer
def create_program_donation_report_CSH(filter_params): def create_program_donation_report_csh(filter_params):
buffer = io.BytesIO() buffer = io.BytesIO()
workbook = xlsxwriter.Workbook( workbook = xlsxwriter.Workbook(
buffer, buffer,
...@@ -373,7 +373,7 @@ def create_program_donation_report_CSH(filter_params): ...@@ -373,7 +373,7 @@ def create_program_donation_report_CSH(filter_params):
workbook.close() workbook.close()
return buffer return buffer
def create_program_donation_report_GDS(filter_params): def create_program_donation_report_gds(filter_params):
buffer = io.BytesIO() buffer = io.BytesIO()
workbook = xlsxwriter.Workbook( workbook = xlsxwriter.Workbook(
buffer, buffer,
......
...@@ -487,7 +487,6 @@ class ProgramProgressSerializer(serializers.ModelSerializer): ...@@ -487,7 +487,6 @@ class ProgramProgressSerializer(serializers.ModelSerializer):
def validate(self, attrs): def validate(self, attrs):
instance = self.instance instance = self.instance
date = attrs.get('date', getattr(instance, 'date', None))
errors = {} errors = {}
if errors: if errors:
raise serializers.ValidationError(errors) raise serializers.ValidationError(errors)
......
This diff is collapsed.
from .auth import *
from .bank import *
from .batch import *
from .cart import *
from .choices import *
from .config import *
from .donation import *
from .product import *
from .program import *
from .report import *
from .transaction import *
from .user import *
\ No newline at end of file
from api import models
from api import permissions as api_permissions
from api import serializers as api_serializers
from api import utils as api_utils
from django import shortcuts
from django.contrib import auth
from knox import views as knox_views
from rest_framework import generics
from rest_framework import permissions as rest_framework_permissions
from rest_framework import response, status
from rest_framework import views as rest_framework_views
from rest_framework.authtoken import serializers as authtoken_serializers
class AuthRegister(generics.CreateAPIView):
permission_classes = [api_permissions.IsAnonymousUser]
serializer_class = api_serializers.UserSerializer
class AuthCredLogin(knox_views.LoginView):
permission_classes = [rest_framework_permissions.AllowAny]
serializer_class = authtoken_serializers.AuthTokenSerializer
def get_serializer(self, *args, **kwargs):
return self.serializer_class(*args, **kwargs)
def post(self, request, format=None): # pylint: disable=redefined-builtin
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
auth.login(request, user)
return super().post(request, format)
class AuthPhoneNumberLogin(rest_framework_views.APIView):
permission_classes = [rest_framework_permissions.AllowAny]
serializer_class = api_serializers.PhoneNumberSerializer
def get_serializer(self, *args, **kwargs):
return self.serializer_class(*args, **kwargs)
def post(self, request, _format=None):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = shortcuts.get_object_or_404(
models.User,
phone_number=serializer.validated_data['phone_number']
)
user.otp = api_utils.generate_otp()
user.save()
api_utils.send_otp(str(user.phone_number), user.otp)
token = api_utils.generate_bearer_token(user)
return response.Response({'token': token}, status=status.HTTP_200_OK)
class AuthOTPLogin(knox_views.LoginView):
permission_classes = [rest_framework_permissions.AllowAny]
serializer_class = api_serializers.OTPSerializer
def get_serializer(self, *args, **kwargs):
return self.serializer_class(*args, **kwargs)
def post(self, request, format=None): # pylint: disable=redefined-builtin
http_authorization = self.request.META.get('HTTP_AUTHORIZATION')
username = api_utils.get_username_from_bearer_token(http_authorization)
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = shortcuts.get_object_or_404(models.User, username=username)
if user.otp != serializer.validated_data['otp']:
return response.Response(status=status.HTTP_400_BAD_REQUEST)
auth.login(request, user)
user.otp = ''
user.save()
return super().post(request, format)
class AuthResendOTP(rest_framework_views.APIView):
permission_classes = [rest_framework_permissions.AllowAny]
def post(self, request, _format=None):
http_authorization = self.request.META.get('HTTP_AUTHORIZATION')
username = api_utils.get_username_from_bearer_token(http_authorization)
user = shortcuts.get_object_or_404(models.User, username=username)
user.otp = api_utils.generate_otp()
user.save()
api_utils.send_otp(str(user.phone_number), user.otp)
return response.Response(status=status.HTTP_204_NO_CONTENT)
from api import models, paginations
from api import permissions as api_permissions
from api import serializers as api_serializers
from rest_framework import filters as rest_framework_filters
from rest_framework import generics
from rest_framework import permissions as rest_framework_permissions
class BankAccountTransferDestinationList(generics.ListCreateAPIView):
filter_backends = [rest_framework_filters.SearchFilter]
pagination_class = paginations.SmallResultsSetPagination
permission_classes = [
api_permissions.IsAdminUserOrReadOnly,
rest_framework_permissions.IsAuthenticated,
]
queryset = models.BankAccountTransferDestination.objects.all()
search_fields = ['bank_name', 'bank_account_number', 'bank_account_name']
serializer_class = api_serializers.BankAccountTransferDestinationSerializer
class BankAccountTransferDestinationDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [
api_permissions.IsAdminUserOrReadOnly,
rest_framework_permissions.IsAuthenticated,
]
queryset = models.BankAccountTransferDestination.objects.all()
serializer_class = api_serializers.BankAccountTransferDestinationSerializer
from api import filters as api_filters
from api import models, paginations
from api import permissions as api_permissions
from api import schemas
from api import serializers as api_serializers
from django.utils.translation import gettext_lazy as _
from django_filters import rest_framework
from rest_framework import exceptions as rest_framework_exceptions
from rest_framework import filters as rest_framework_filters
from rest_framework import generics
from rest_framework import permissions as rest_framework_permissions
from rest_framework import response, status
from rest_framework import views as rest_framework_views
class BatchList(generics.ListCreateAPIView):
filter_backends = [
rest_framework.DjangoFilterBackend,
rest_framework_filters.OrderingFilter,
rest_framework_filters.SearchFilter,
]
filterset_class = api_filters.BatchFilter
ordering_fields = ['created_at', 'updated_at']
pagination_class = paginations.SmallResultsSetPagination
permission_classes = [rest_framework_permissions.IsAuthenticated]
queryset = models.Batch.objects.all()
schema = schemas.BatchListSchema()
search_fields = ['batch_name']
serializer_class = api_serializers.BatchSerializer
def post(self, request, _format=None):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if serializer.validated_data['start_date'] < serializer.validated_data['end_date']:
batch = models.Batch.objects.create(
batch_name=serializer.validated_data['batch_name'],
start_date=serializer.validated_data['start_date'],
end_date=serializer.validated_data['end_date'],
shipping_cost=serializer.validated_data['shipping_cost'],
)
else:
raise rest_framework_exceptions.PermissionDenied(_(
'Start Date must be earlier than End Date.'
))
return response.Response(
{'id': batch.id},
status=status.HTTP_201_CREATED
)
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
if not self.request.user.is_staff:
return queryset.filter(user=self.request.user)
return queryset
class BatchDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [
api_permissions.IsAdminUserOrReadOnly,
rest_framework_permissions.IsAuthenticated,
]
queryset = models.Batch.objects.all()
serializer_class = api_serializers.BatchSerializer
class BatchCreate(rest_framework_views.APIView):
permission_classes = [rest_framework_permissions.IsAuthenticated]
serializer_class = api_serializers.BatchCreateSerializer
def get_serializer(self, *args, **kwargs):
return self.serializer_class(*args, **kwargs)
def post(self, request, _format=None):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if serializer.validated_data['start_date'] < serializer.validated_date['end_date']:
batch = models.Batch.objects.create(
batch_name=serializer.validated_data['batch_name'],
start_date=serializer.validated_data['start_date'],
end_date=serializer.validated_data['end_date'],
shipping_cost=serializer.validated_data['shipping_cost'],
)
else:
raise rest_framework_exceptions.PermissionDenied(_(
'Start Date must be earlier than End Date.'
))
return response.Response(
{'id': batch.id},
status=status.HTTP_201_CREATED
)
from api import models, paginations
from api import permissions as api_permissions
from api import serializers as api_serializers
from api import utils as api_utils
from django import shortcuts
from django.db import transaction as db_transaction
from django.db import utils as db_utils
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django_filters import rest_framework
from home_industry import utils as home_industry_utils
from rest_framework import exceptions as rest_framework_exceptions
from rest_framework import generics
from rest_framework import permissions as rest_framework_permissions
from rest_framework import response, status
from rest_framework import views as rest_framework_views
class CartUpdate(rest_framework_views.APIView):
permission_classes = [rest_framework_permissions.IsAuthenticated]
serializer_class = api_serializers.CartUpdateSerializer
def get_serializer(self, *args, **kwargs):
return self.serializer_class(*args, **kwargs)
def post(self, request, _format=None):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = request.user
product = shortcuts.get_object_or_404(
models.Product,
id=serializer.validated_data['product']
)
shopping_cart = models.ShoppingCart.objects.get(user=user)
cart_item, _created = models.CartItem.objects.get_or_create(
product=product,
shopping_cart=shopping_cart
)
if serializer.validated_data['quantity'] == 0:
cart_item.delete()
else:
cart_item.quantity = serializer.validated_data['quantity']
cart_item.save()
return response.Response(status=status.HTTP_204_NO_CONTENT)
class CartOverview(rest_framework_views.APIView):
permission_classes = [rest_framework_permissions.IsAuthenticated]
def get(self, request, _format=None):
user = request.user
shopping_cart = models.ShoppingCart.objects.get(user=user)
item_subtotal = sum(
cart_item.product.price * cart_item.quantity
for cart_item in shopping_cart.cart_items.all()
)
shipping_costs = api_utils.get_shipping_costs(user)
if shipping_costs is None:
return response.Response(
{'item_subtotal': str(item_subtotal)},
status=status.HTTP_200_OK
)
return response.Response(
{'item_subtotal': str(item_subtotal),
'shipping_costs': str(shipping_costs)},
status=status.HTTP_200_OK
)
class CartCheckout(rest_framework_views.APIView):
permission_classes = [rest_framework_permissions.IsAuthenticated]
serializer_class = api_serializers.CartCheckoutSerializer
def get_serializer(self, *args, **kwargs):
return self.serializer_class(*args, **kwargs)
def post(self, request, _format=None):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = request.user
shipment_config = home_industry_utils.get_shipment_config()
if user.sub_district.lower() != shipment_config.sub_district.lower():
raise rest_framework_exceptions.ParseError(_( # pylint: disable=no-member
'Cannot process shipment to other sub-districts other than {sub_district}.'
).format(sub_district=shipment_config.sub_district))
shopping_cart = models.ShoppingCart.objects.get(user=user)
cart_items = shopping_cart.cart_items.all()
if not cart_items.exists():
raise rest_framework_exceptions.ParseError(_(
'Unable to checkout because there are no items purchased.'
))
api_utils.validate_product_stock(cart_items)
transaction_status = (
'001' if serializer.validated_data['payment_method'] == 'TRF' else '002'
)
transaction = models.Transaction.objects.create(
user=user,
payment_method=serializer.validated_data['payment_method'],
donation=serializer.validated_data['donation'],
transaction_status=transaction_status,
batch=(
None if serializer.validated_data['payment_method'] == 'TRF'
else models.Batch.objects.filter(
start_date__lte=timezone.now().date(),
end_date__gte=timezone.now().date()).first()
)
)
is_success = True
for cart_item in cart_items:
product = cart_item.product
if product.stock is not None:
try:
with db_transaction.atomic():
product.stock -= cart_item.quantity
product.total_profit += cart_item.quantity*product.profit
product.save()
except db_utils.IntegrityError:
is_success = False
models.TransactionItem.objects.create(
transaction=transaction,
product=product,
quantity=cart_item.quantity
)
cart_item.delete()
if not is_success:
transaction.transaction_status = '007'
transaction.save()
raise rest_framework_exceptions.APIException(_('Checkout failed.'))
return response.Response({'transaction': transaction.id}, status=status.HTTP_200_OK)
class CartUploadPOP(rest_framework_views.APIView):
permission_classes = [rest_framework_permissions.IsAuthenticated]
serializer_class = api_serializers.CartUploadPOPSerializer
def get_serializer(self, *args, **kwargs):
return self.serializer_class(*args, **kwargs)
def post(self, request, _format=None):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = request.user
bank_account_transfer_destination = shortcuts.get_object_or_404(
models.BankAccountTransferDestination,
id=serializer.validated_data['bank_account_transfer_destination']
)
transaction = shortcuts.get_object_or_404(
models.Transaction,
id=serializer.validated_data['transaction'],
user=user
)
if transaction.payment_method != 'TRF':
raise rest_framework_exceptions.PermissionDenied(_(
'The payment method for this transaction is not a transfer.'
))
if transaction.transaction_status not in ('001', '002'):
raise rest_framework_exceptions.PermissionDenied(_(
'Cannot upload proof of payment at this stage.'
))
transaction.proof_of_payment = serializer.validated_data['proof_of_payment']
transaction.user_bank_name = serializer.validated_data['user_bank_name']
transaction.user_bank_account_name = serializer.validated_data['user_bank_account_name']
transaction.bank_account_transfer_destination = bank_account_transfer_destination
transaction.update_bank_account_transfer_destination = True
transaction.transaction_status = '002'
transaction.batch = models.Batch.objects.filter(
start_date__lte=timezone.now().date(),
end_date__gte=timezone.now().date()).first()
transaction.save()
return response.Response(status=status.HTTP_204_NO_CONTENT)
class CartCompleteTransaction(rest_framework_views.APIView):
permission_classes = [rest_framework_permissions.IsAuthenticated]
serializer_class = api_serializers.CartCompleteOrCancelTransactionSerializer
def get_serializer(self, *args, **kwargs):
return self.serializer_class(*args, **kwargs)
def post(self, request, _format=None):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
transaction = shortcuts.get_object_or_404(
models.Transaction,
id=serializer.validated_data['transaction'],
user=request.user
)
if transaction.transaction_status != '004':
raise rest_framework_exceptions.PermissionDenied(_(
'Transaction cannot be completed unless the status is "Being shipped".'
))
transaction.transaction_status = '005'
transaction.save()
return response.Response(status=status.HTTP_204_NO_CONTENT)
class CartCancelTransaction(rest_framework_views.APIView):
permission_classes = [rest_framework_permissions.IsAuthenticated]
serializer_class = api_serializers.CartCompleteOrCancelTransactionSerializer
def get_serializer(self, *args, **kwargs):
return self.serializer_class(*args, **kwargs)
def post(self, request, _format=None):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = request.user
transaction = shortcuts.get_object_or_404(
models.Transaction,
id=serializer.validated_data['transaction'],
user=user
)
if transaction.transaction_status not in ('001', '002'):
raise rest_framework_exceptions.PermissionDenied(_(
'Transaction cannot be canceled at this stage.'
))
transaction_items = transaction.transaction_items.all()
api_utils.return_transaction_items_to_product_stock(transaction_items)
transaction.transaction_status = '006'
transaction.save()
return response.Response(status=status.HTTP_204_NO_CONTENT)
class ShoppingCartList(generics.ListAPIView):
filter_backends = [rest_framework.DjangoFilterBackend]
filterset_fields = ['user']
pagination_class = paginations.SmallResultsSetPagination
permission_classes = [rest_framework_permissions.IsAdminUser]
queryset = models.ShoppingCart.objects.all()
serializer_class = api_serializers.ShoppingCartSerializer
class ShoppingCartDetail(generics.RetrieveAPIView):
permission_classes = [
api_permissions.IsAdminUserOrOwner,
rest_framework_permissions.IsAuthenticated,
]
queryset = models.ShoppingCart.objects.all()
serializer_class = api_serializers.ShoppingCartSerializer
def get_object(self):
if self.kwargs.get('pk') == 'self':
self.kwargs['pk'] = models.ShoppingCart.objects.get(
user=self.request.user).id
return super().get_object()
from api import constants
from api import utils as api_utils
from rest_framework import permissions as rest_framework_permissions
from rest_framework import response, status
from rest_framework import views as rest_framework_views
class ChoicesAPIView(rest_framework_views.APIView):
choices = None
permission_classes = [rest_framework_permissions.IsAuthenticated]
def get(self, request, _format=None):
assert self.choices is not None, (
'{} should include a `choices` attribute.'.format(
self.__class__.__name__)
)
return response.Response(api_utils.map_choices(self.choices), status=status.HTTP_200_OK)
class PaymentMethodChoices(ChoicesAPIView):
choices = constants.PAYMENT_METHOD_CHOICES
class TransactionStatusChoices(ChoicesAPIView):
choices = constants.TRANSACTION_STATUS_CHOICES
class DonationStatusChoices(ChoicesAPIView):
choices = constants.DONATION_STATUS_CHOICES
from api import models
from api import permissions as api_permissions
from api import serializers as api_serializers
from django import shortcuts
from rest_framework import generics
from rest_framework import permissions as rest_framework_permissions
class AppConfigDetail(generics.RetrieveUpdateAPIView):
permission_classes = [rest_framework_permissions.IsAdminUser]
queryset = models.AppConfig.objects.all()
serializer_class = api_serializers.AppConfigSerializer
def get_object(self):
obj = shortcuts.get_object_or_404(models.AppConfig)
return obj
class HelpContactConfigDetail(generics.RetrieveUpdateAPIView):
permission_classes = [api_permissions.IsAdminUserOrReadOnly]
queryset = models.HelpContactConfig.objects.all()
serializer_class = api_serializers.HelpContactConfigSerializer
def get_object(self):
obj = shortcuts.get_object_or_404(models.HelpContactConfig)
return obj
class ShipmentConfigDetail(generics.RetrieveUpdateAPIView):
permission_classes = [api_permissions.IsAdminUserOrReadOnly]
queryset = models.ShipmentConfig.objects.all()
serializer_class = api_serializers.ShipmentConfigSerializer
def get_object(self):
obj = shortcuts.get_object_or_404(models.ShipmentConfig)
return obj
from api import models
from api import serializers as api_serializers
from django import shortcuts
from django.utils.translation import gettext_lazy as _
from rest_framework import exceptions as rest_framework_exceptions
from rest_framework import permissions as rest_framework_permissions
from rest_framework import response, status