Commit cd808d42 authored by John Red Medrano's avatar John Red Medrano

pull changes from demo

parents 0f456296 d1c80aa6
...@@ -38,17 +38,17 @@ class ChangeRequestFormApproversSerializer( ...@@ -38,17 +38,17 @@ class ChangeRequestFormApproversSerializer(
if instance.form_code.status == 'Draft': if instance.form_code.status == 'Draft':
if instance.tmp_approver: if instance.tmp_approver:
if instance.tmp_approver.user or instance.tmp_approver.delegation.name.lower() == 'requestor': if instance.tmp_approver.user:
ret['editable_user'] = False ret['editable_user'] = False
else: else:
ret['editable_user'] = True ret['editable_user'] = True
if instance.tmp_approver.company or instance.tmp_approver.delegation.name.lower() == 'requestor': if instance.tmp_approver.company:
ret['editable_comp'] = False ret['editable_comp'] = False
else: else:
ret['editable_comp'] = True ret['editable_comp'] = True
if instance.tmp_approver.department or instance.tmp_approver.delegation.name.lower() == 'requestor': if instance.tmp_approver.department:
ret['editable_dept'] = False ret['editable_dept'] = False
else: else:
ret['editable_dept'] = True ret['editable_dept'] = True
...@@ -58,12 +58,12 @@ class ChangeRequestFormApproversSerializer( ...@@ -58,12 +58,12 @@ class ChangeRequestFormApproversSerializer(
else: else:
ret['editable_deleg'] = True ret['editable_deleg'] = True
# comment if instance.tmp_approver.delegation:
# if instance.tmp_approver.delegation.name.lower() == 'requestor': if instance.tmp_approver.delegation.name.lower() == 'requestor':
# ret['editable_user'] = False ret['editable_user'] = False
# ret['editable_comp'] = False ret['editable_comp'] = False
# ret['editable_dept'] = False ret['editable_dept'] = False
# ret['editable_deleg'] = False ret['editable_deleg'] = False
else: else:
ret['editable_user'] = True ret['editable_user'] = True
...@@ -83,13 +83,13 @@ class ChangeRequestFormApproversSerializer( ...@@ -83,13 +83,13 @@ class ChangeRequestFormApproversSerializer(
if instance.form_code.status == 'Draft': if instance.form_code.status == 'Draft':
if instance.tmp_approver: if instance.tmp_approver:
if instance.tmp_approver.user or instance.tmp_approver.delegation.name.lower() == 'requestor': if instance.tmp_approver.user:
ret['editable_user'] = False ret['editable_user'] = False
else: else:
ret['user'] = None ret['user'] = None
ret['editable_user'] = True ret['editable_user'] = True
if instance.tmp_approver.company or instance.tmp_approver.delegation.name.lower() == 'requestor': if instance.tmp_approver.company:
ret['company'] = { ret['company'] = {
"id": instance.tmp_approver.company.id, "id": instance.tmp_approver.company.id,
"code": instance.tmp_approver.company.code, "code": instance.tmp_approver.company.code,
...@@ -101,7 +101,7 @@ class ChangeRequestFormApproversSerializer( ...@@ -101,7 +101,7 @@ class ChangeRequestFormApproversSerializer(
ret['company'] = None ret['company'] = None
ret['editable_comp'] = True ret['editable_comp'] = True
if instance.tmp_approver.department or instance.tmp_approver.delegation.name.lower() == 'requestor': if instance.tmp_approver.department:
ret['department'] = { ret['department'] = {
"id": instance.tmp_approver.department.id, "id": instance.tmp_approver.department.id,
"code": instance.tmp_approver.department.code, "code": instance.tmp_approver.department.code,
...@@ -123,12 +123,13 @@ class ChangeRequestFormApproversSerializer( ...@@ -123,12 +123,13 @@ class ChangeRequestFormApproversSerializer(
else: else:
ret['delegation'] = None ret['delegation'] = None
ret['editable_deleg'] = True ret['editable_deleg'] = True
# if instance.tmp_approver.delegation.name.lower() == 'requestor': if instance.tmp_approver.delegation:
# ret['editable_user'] = False if instance.tmp_approver.delegation.name.lower() == 'requestor':
# ret['editable_comp'] = False ret['editable_user'] = False
# ret['editable_dept'] = False ret['editable_comp'] = False
# ret['editable_deleg'] = False ret['editable_dept'] = False
ret['editable_deleg'] = False
else: else:
ret['editable_user'] = True ret['editable_user'] = True
......
...@@ -17,18 +17,18 @@ class ChangeRequestFormAttachmentsSerializer( ...@@ -17,18 +17,18 @@ class ChangeRequestFormAttachmentsSerializer(
"contact_no": instance.uploaded_by.contact_no "contact_no": instance.uploaded_by.contact_no
} }
ret['uploaded_by'] = user_object ret['uploaded_by'] = user_object
ret['file_upload'] = self.context['request'].build_absolute_uri( ret['file_upload'] = self.context['request'].build_absolute_uri(
instance.file_upload.url.url) instance.file_upload.url.url)
ret['file_upload_id'] = instance.file_upload.id ret['file_upload_id'] = instance.file_upload.id
return ret return ret
class Meta: class Meta:
model = models.ChangeRequestFormAttachments model = models.ChangeRequestFormAttachments
fields = '__all__' fields = '__all__'
read_only_fields = ['created', 'code'] read_only_fields = ['created', 'code']
class ChangeRequestFormAttachmentsFileUploadSerializer( class ChangeRequestFormAttachmentsFileUploadSerializer(
serializers.ModelSerializer serializers.ModelSerializer
): ):
......
...@@ -98,7 +98,7 @@ class ChangeRequestFormHeaderSerializer( ...@@ -98,7 +98,7 @@ class ChangeRequestFormHeaderSerializer(
ret['template_object'] = "None" ret['template_object'] = "None"
return ret return ret
# 'company_desc', 'department_desc', 'requested_desc',
class Meta: class Meta:
model = models.ChangeRequestFormHeader model = models.ChangeRequestFormHeader
# fields = '__all__' # fields = '__all__'
......
...@@ -22,7 +22,8 @@ from django.db import transaction, IntegrityError, connection ...@@ -22,7 +22,8 @@ from django.db import transaction, IntegrityError, connection
from app.applicationlayer.utils import (QuerySetHelper, from app.applicationlayer.utils import (QuerySetHelper,
status_message_response, status_message_response,
send_broadcast_message) send_broadcast_message)
from app.businesslayer.changerequest import change_request from app.businesslayer.changerequest import (change_request,
change_request_template)
from app.applicationlayer.cms.utils_cr import (number_generator, from app.applicationlayer.cms.utils_cr import (number_generator,
send_mail_requestor, send_mail_requestor,
...@@ -35,7 +36,8 @@ from app.applicationlayer.cms.utils_cr import (number_generator, ...@@ -35,7 +36,8 @@ from app.applicationlayer.cms.utils_cr import (number_generator,
entity_log_bulk, entity_log_bulk,
reminder_trigger_save, reminder_trigger_save,
overdue_trigger_save, overdue_trigger_save,
reset_autoemail_tables) reset_autoemail_tables,
delete_master_attachment_file)
from app.entities import enums from app.entities import enums
from app.applicationlayer.utils import model_to_dict from app.applicationlayer.utils import model_to_dict
...@@ -72,6 +74,9 @@ from django.conf import settings ...@@ -72,6 +74,9 @@ from django.conf import settings
from io import BytesIO from io import BytesIO
from django.http import HttpResponse from django.http import HttpResponse
from xhtml2pdf import pisa from xhtml2pdf import pisa
from app.helper.decorators import *
from app.applicationlayer.utils import error_message
config = configparser.ConfigParser() config = configparser.ConfigParser()
...@@ -552,13 +557,14 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -552,13 +557,14 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
# full_file_name = os.path.join(my_folder, file_name) # full_file_name = os.path.join(my_folder, file_name)
# if os.path.isfile(full_file_name): # if os.path.isfile(full_file_name):
# shutil.copy(full_file_name, dest) # shutil.copy(full_file_name, dest)
for file_name in attch: for file_name in attch:
a = os.path.join(settings.MEDIA_ROOT, file_name['file_upload__url']) a = os.path.join(settings.MEDIA_ROOT, file_name['file_upload__url'])
# full_file_name = os.path.join(my_folder, file_name['file_upload__url']) # full_file_name = os.path.join(my_folder, file_name['file_upload__url'])
# print(full_file_name) # print(full_file_name)
if os.path.isfile(a): if os.path.isfile(a):
print(a)
# print(type(a))
b = open(a, 'r') b = open(a, 'r')
shutil.copy(b, my_folder) shutil.copy(b, my_folder)
else: else:
...@@ -739,6 +745,7 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -739,6 +745,7 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
return Response(message, status=status.HTTP_200_OK) return Response(message, status=status.HTTP_200_OK)
@FormValidation
@transaction.atomic @transaction.atomic
@action( @action(
methods=['PATCH'], detail=True, methods=['PATCH'], detail=True,
...@@ -851,7 +858,8 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -851,7 +858,8 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
) )
return Response(message, status=status.HTTP_200_OK) return Response(message, status=status.HTTP_200_OK)
@FormValidation
@transaction.atomic @transaction.atomic
@action( @action(
methods=['PATCH'], detail=True, methods=['PATCH'], detail=True,
...@@ -864,6 +872,13 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -864,6 +872,13 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
form_code = kwargs['form_code'] form_code = kwargs['form_code']
form_data = request.data form_data = request.data
# Restrict a requestor to submit a CR without atleast 1 approver
counter = change_request_template.validation_existing_approver(
form_data['frm_approvers'])
if counter == 0:
return error_message('400', 'Please select at least 1 approver before submitting this request.',
'failed', status.HTTP_400_BAD_REQUEST)
# generate batchno history # generate batchno history
batchno = get_max_batchno("batch") batchno = get_max_batchno("batch")
...@@ -1180,16 +1195,17 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -1180,16 +1195,17 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
class ChangeRequestFormPost(APIView): class ChangeRequestFormPost(APIView):
@FormValidation
@transaction.atomic() @transaction.atomic()
def post(self, request): def post(self, request):
form_header = request.data form_header = request.data
try: try:
data_list_approver = [] data_list_approver = []
data_list_stake = [] data_list_stake = []
data_list_attach = [] data_list_attach = []
data_list_detail = [] data_list_detail = []
form_header_data = { form_header_data = {
'requested_to_template_name': form_header['requested_to_template_name'], 'requested_to_template_name': form_header['requested_to_template_name'],
'requested_to_template_id': form_header['requested_to_template_id'], 'requested_to_template_id': form_header['requested_to_template_id'],
...@@ -1198,9 +1214,6 @@ class ChangeRequestFormPost(APIView): ...@@ -1198,9 +1214,6 @@ class ChangeRequestFormPost(APIView):
'requested_to_priority': form_header['requested_to_priority'], 'requested_to_priority': form_header['requested_to_priority'],
'description': form_header['description'], 'description': form_header['description'],
'status': form_header['status'], 'status': form_header['status'],
'company_desc': form_header['company_desc'],
'department_desc': form_header['department_desc'],
'requested_desc': form_header['requested_desc'],
'requested_by_department': form_header['requested_by_department'], 'requested_by_department': form_header['requested_by_department'],
'requested_by_user': form_header['requested_by_user'], 'requested_by_user': form_header['requested_by_user'],
'requested_to_company': form_header['requested_to_company'], 'requested_to_company': form_header['requested_to_company'],
...@@ -1209,7 +1222,11 @@ class ChangeRequestFormPost(APIView): ...@@ -1209,7 +1222,11 @@ class ChangeRequestFormPost(APIView):
'template_no': form_header['template_no'] 'template_no': form_header['template_no']
} }
# sp1 = transaction.savepoint() # nothing will save to db # 'company_desc': None,
# 'department_desc': None,
# 'requested_desc': None,
sp1 = transaction.savepoint() # nothing will save to db
serializer = ChangeRequestFormHeaderSerializer( serializer = ChangeRequestFormHeaderSerializer(
data=form_header_data) data=form_header_data)
...@@ -1228,15 +1245,13 @@ class ChangeRequestFormPost(APIView): ...@@ -1228,15 +1245,13 @@ class ChangeRequestFormPost(APIView):
serializer.save() serializer.save()
frm_id = serializer.data['form_code'] frm_id = serializer.data['form_code']
# create form approvers # create form approvers
frm_approvers = form_header['frm_approvers'] frm_approvers = form_header['frm_approvers']
counter = 0
for frm_approver in frm_approvers: for frm_approver in frm_approvers:
frm_approver['form_code'] = frm_id frm_approver['form_code'] = frm_id
counter = counter + 1
data_list_approver.append(frm_approver) data_list_approver.append(frm_approver)
serializerApprover = ChangeRequestFormApproversSerializer( serializerApprover = ChangeRequestFormApproversSerializer(
data=data_list_approver, many=True) data=data_list_approver, many=True)
...@@ -1367,7 +1382,8 @@ class ChangeRequestFormPost(APIView): ...@@ -1367,7 +1382,8 @@ class ChangeRequestFormPost(APIView):
return Response(message, status=status.HTTP_201_CREATED) return Response(message, status=status.HTTP_201_CREATED)
except ValidationError as e: except ValidationError as e:
# transaction.savepoint_rollback(sp1) transaction.savepoint_rollback(sp1)
message = { message = {
'code': 400, 'code': 400,
'status': 'failed', 'status': 'failed',
...@@ -1376,7 +1392,8 @@ class ChangeRequestFormPost(APIView): ...@@ -1376,7 +1392,8 @@ class ChangeRequestFormPost(APIView):
return Response(message, status=status.HTTP_400_BAD_REQUEST) return Response(message, status=status.HTTP_400_BAD_REQUEST)
except Exception as e: except Exception as e:
# transaction.savepoint_rollback(sp1) transaction.savepoint_rollback(sp1)
message = { message = {
'code': 500, 'code': 500,
'status': 'failed', 'status': 'failed',
......
...@@ -118,7 +118,6 @@ class ChangeRequestFormHeaderSerializer( ...@@ -118,7 +118,6 @@ class ChangeRequestFormHeaderSerializer(
fields = ('form_code', 'requested_to_template_name', 'requested_to_objective', fields = ('form_code', 'requested_to_template_name', 'requested_to_objective',
'requested_to_target_date', 'requested_to_priority', 'requested_to_target_date', 'requested_to_priority',
'description', 'created', 'cancel_date', 'status', 'description', 'created', 'cancel_date', 'status',
'company_desc', 'department_desc', 'requested_desc',
'requested_to_template_id', 'requested_to_company', 'requested_to_template_id', 'requested_to_company',
'requested_to_department', 'requested_to_user', 'requested_to_department', 'requested_to_user',
'requested_by_user', 'requested_by_department', 'requested_by_user', 'requested_by_department',
...@@ -127,7 +126,7 @@ class ChangeRequestFormHeaderSerializer( ...@@ -127,7 +126,7 @@ class ChangeRequestFormHeaderSerializer(
read_only_fields = ['created', 'form_code'] read_only_fields = ['created', 'form_code']
# 'company_desc', 'department_desc', 'requested_desc',
class ChangeRequestFormHeaderSerializerList( class ChangeRequestFormHeaderSerializerList(
serializers.ModelSerializer serializers.ModelSerializer
): ):
......
...@@ -941,9 +941,6 @@ class ChangeRequestFormPost(APIView): ...@@ -941,9 +941,6 @@ class ChangeRequestFormPost(APIView):
'requested_to_priority': form_header['requested_to_priority'], 'requested_to_priority': form_header['requested_to_priority'],
'description': form_header['description'], 'description': form_header['description'],
'status': form_header['status'], 'status': form_header['status'],
'company_desc': form_header['company_desc'],
'department_desc': form_header['department_desc'],
'requested_desc': form_header['requested_desc'],
'requested_by_department': form_header['requested_by_department'], 'requested_by_department': form_header['requested_by_department'],
'requested_by_user': form_header['requested_by_user'], 'requested_by_user': form_header['requested_by_user'],
'requested_to_company': form_header['requested_to_company'], 'requested_to_company': form_header['requested_to_company'],
...@@ -952,6 +949,10 @@ class ChangeRequestFormPost(APIView): ...@@ -952,6 +949,10 @@ class ChangeRequestFormPost(APIView):
'template_no': form_header['template_no'] 'template_no': form_header['template_no']
} }
# 'company_desc': form_header['company_desc'],
# 'department_desc': form_header['department_desc'],
# 'requested_desc': form_header['requested_desc'],
sp1 = transaction.savepoint() # nothing will save to db sp1 = transaction.savepoint() # nothing will save to db
serializer = serializers.ChangeRequestFormHeaderSerializer( serializer = serializers.ChangeRequestFormHeaderSerializer(
......
...@@ -26,7 +26,6 @@ class UserListTemplate(APIView): ...@@ -26,7 +26,6 @@ class UserListTemplate(APIView):
user_list = models.User.objects.filter( user_list = models.User.objects.filter(
code__in=verified_users code__in=verified_users
) )
page = self.paginate_queryset(user_list) page = self.paginate_queryset(user_list)
if page is not None: if page is not None:
......
...@@ -22,7 +22,7 @@ class ChangeRequestTemplateApproversSerializer( ...@@ -22,7 +22,7 @@ class ChangeRequestTemplateApproversSerializer(
ret['editable_comp'] = True ret['editable_comp'] = True
if instance.department: if instance.department:
ret['department'] = { ret['department'] = {
"id": instance.department.id, "id": instance.department.id,
"code": instance.department.code, "code": instance.department.code,
...@@ -33,7 +33,7 @@ class ChangeRequestTemplateApproversSerializer( ...@@ -33,7 +33,7 @@ class ChangeRequestTemplateApproversSerializer(
ret['editable_dept'] = True ret['editable_dept'] = True
if instance.user: if instance.user:
user_object = { user_object = {
"id": instance.user.id, "id": instance.user.id,
"name": instance.user.name, "name": instance.user.name,
...@@ -59,12 +59,13 @@ class ChangeRequestTemplateApproversSerializer( ...@@ -59,12 +59,13 @@ class ChangeRequestTemplateApproversSerializer(
else: else:
ret['editable_deleg'] = True ret['editable_deleg'] = True
if instance.delegation.name.lower() == 'requestor': if instance.delegation:
if instance.delegation.name.lower() == 'requestor' or instance.delegation.name.lower() == 'vendor/implementor':
ret['editable_user'] = False
ret['editable_comp'] = False ret['editable_user'] = False
ret['editable_dept'] = False ret['editable_comp'] = False
ret['editable_deleg'] = False ret['editable_dept'] = False
ret['editable_deleg'] = False
return ret return ret
except Exception as e: except Exception as e:
......
...@@ -33,7 +33,7 @@ class ChangeRequestTemplatesSerializer( ...@@ -33,7 +33,7 @@ class ChangeRequestTemplatesSerializer(
many=True, read_only=True) many=True, read_only=True)
tmp_details = ChangeRequestTemplateDetailsSerializer( tmp_details = ChangeRequestTemplateDetailsSerializer(
many=True, read_only=True) many=True, read_only=True)
def to_representation(self, instance): def to_representation(self, instance):
ret = super().to_representation(instance) ret = super().to_representation(instance)
try: try:
......
...@@ -14,7 +14,8 @@ from app.applicationlayer.utils import (CustomPagination, ...@@ -14,7 +14,8 @@ from app.applicationlayer.utils import (CustomPagination,
status_message_response) status_message_response)
from app.applicationlayer.cms.utils_cr import ( from app.applicationlayer.cms.utils_cr import (
entity_log_bulk entity_log_bulk,
delete_master_attachment_file
) )
from app.applicationlayer.utils import model_to_dict from app.applicationlayer.utils import model_to_dict
from app.entities import enums, models from app.entities import enums, models
...@@ -23,7 +24,9 @@ from django.db.models import Q ...@@ -23,7 +24,9 @@ from django.db.models import Q
from app.applicationlayer.utils import log_save, CustomPagination from app.applicationlayer.utils import log_save, CustomPagination
from rest_framework.exceptions import ParseError from rest_framework.exceptions import ParseError
from app.businesslayer.changerequest.change_request_template import ( from app.businesslayer.changerequest.change_request_template import (
tmp_add_edit_delete tmp_add_edit_delete,
validation_approver_same_level,
validation_existing_vendor_requestor
) )
from app.applicationlayer.management.account.serializer import ChangeRequestList from app.applicationlayer.management.account.serializer import ChangeRequestList
from app.applicationlayer.cms.template.approver.serializers import ChangeRequestTemplateApproversSerializer from app.applicationlayer.cms.template.approver.serializers import ChangeRequestTemplateApproversSerializer
...@@ -33,6 +36,7 @@ from app.applicationlayer.cms.template.attachment.serializers import ChangeReque ...@@ -33,6 +36,7 @@ from app.applicationlayer.cms.template.attachment.serializers import ChangeReque
from app.applicationlayer.cms.template.header.serializers import ChangeRequestTemplatesSerializer from app.applicationlayer.cms.template.header.serializers import ChangeRequestTemplatesSerializer
from app.applicationlayer.cms.template.header.serializers import ChangeRequestTemplatesSerializerList from app.applicationlayer.cms.template.header.serializers import ChangeRequestTemplatesSerializerList
from app.applicationlayer.cms.template.header.table_filters import HeaderFilterSet from app.applicationlayer.cms.template.header.table_filters import HeaderFilterSet
from app.helper.decorators import *
# from django_filters import rest_framework as filters # from django_filters import rest_framework as filters
...@@ -184,9 +188,10 @@ class ChangeRequestTemplatesViewset(viewsets.ModelViewSet): ...@@ -184,9 +188,10 @@ class ChangeRequestTemplatesViewset(viewsets.ModelViewSet):
return Response(e, return Response(e,
status=status.HTTP_500_INTERNAL_SERVER_ERROR) status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@TemplateValidation
@transaction.atomic @transaction.atomic
def partial_update(self, request, *args, **kwargs): def partial_update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', True) partial = kwargs.pop('partial', True)
instance = self.get_object() instance = self.get_object()
...@@ -339,16 +344,24 @@ class ChangeRequestTemplatesViewset(viewsets.ModelViewSet): ...@@ -339,16 +344,24 @@ class ChangeRequestTemplatesViewset(viewsets.ModelViewSet):
class ChangeRequestTemplatePost(APIView): class ChangeRequestTemplatePost(APIView):
@TemplateValidation
@transaction.atomic() @transaction.atomic()
def post(self, request): def post(self, request):
template_header = request.data template_header = request.data
try: try:
# Check if prefix already exists
prefix = models.ChangeRequestTemplateHeader.objects.filter(
requested_to_template_id=template_header['requested_to_template_id'])
if prefix:
return error_message('400', 'CR Number prefix already exists.',
'failed', status.HTTP_400_BAD_REQUEST)
data_list_approver = [] data_list_approver = []
data_list_stake = [] data_list_stake = []
data_list_attach = [] data_list_attach = []
data_list_detail = [] data_list_detail = []
template_header_data = { template_header_data = {
'requested_to_template_name': template_header['requested_to_template_name'], 'requested_to_template_name': template_header['requested_to_template_name'],
'requested_to_template_id': template_header['requested_to_template_id'], 'requested_to_template_id': template_header['requested_to_template_id'],
...@@ -365,12 +378,6 @@ class ChangeRequestTemplatePost(APIView): ...@@ -365,12 +378,6 @@ class ChangeRequestTemplatePost(APIView):
sp1 = transaction.savepoint() # nothing will save to db sp1 = transaction.savepoint() # nothing will save to db
# cr_prefix = request.data['requested_to_template_id'])
# models.ChangeRequestTemplateHeader.objects.filter(
# requested_to_template_id=cr_prefix
# )
serializer = ChangeRequestTemplatesSerializer( serializer = ChangeRequestTemplatesSerializer(
data=template_header_data) data=template_header_data)
...@@ -385,7 +392,7 @@ class ChangeRequestTemplatePost(APIView): ...@@ -385,7 +392,7 @@ class ChangeRequestTemplatePost(APIView):
for tmp_approver in tmp_approvers: for tmp_approver in tmp_approvers:
tmp_approver['template_no'] = tmp_id tmp_approver['template_no'] = tmp_id
data_list_approver.append(tmp_approver) data_list_approver.append(tmp_approver)
serializerApprover = ChangeRequestTemplateApproversSerializer( serializerApprover = ChangeRequestTemplateApproversSerializer(
data=data_list_approver, many=True) data=data_list_approver, many=True)
...@@ -445,15 +452,25 @@ class ChangeRequestTemplatePost(APIView): ...@@ -445,15 +452,25 @@ class ChangeRequestTemplatePost(APIView):
except ValidationError as e: except ValidationError as e:
transaction.savepoint_rollback(sp1) transaction.savepoint_rollback(sp1)
if template_header['tmp_attachments']:
delete_master_attachment_file(
template_header['tmp_attachments'])
message = { message = {
'code': 400, 'code': 400,
'status': 'failed', 'status': 'failed',
'message': str(e), 'message': str(e),
} }
return Response(message, status=status.HTTP_400_BAD_REQUEST) return Response(message, status=status.HTTP_400_BAD_REQUEST)
except Exception as e: except Exception as e:
transaction.savepoint_rollback(sp1) transaction.savepoint_rollback(sp1)
if template_header['tmp_attachments']:
delete_master_attachment_file(
template_header['tmp_attachments'])
message = { message = {
'code': 500, 'code': 500,
'status': 'failed', 'status': 'failed',
......
...@@ -866,4 +866,11 @@ def send_email_onbehalf(active_user, behalf_usernext_level): ...@@ -866,4 +866,11 @@ def send_email_onbehalf(active_user, behalf_usernext_level):
status, url, recipient, delegation_type, status, url, recipient, delegation_type,
delegation_recipient, admin] delegation_recipient, admin]
main_threading(args, sender.routing_table_actions_required) main_threading(args, sender.routing_table_actions_required)
\ No newline at end of file def delete_master_attachment_file(attachments):
# delete master attachment data and media file attachments
for attachment in attachments:
attach = models.MasterAttachment.objects.filter(
id=attachment['file_upload'])
if attach:
attach.first().delete()
...@@ -25,7 +25,7 @@ class UserDownloadRequest(XLSXFileMixin, ReadOnlyModelViewSet): ...@@ -25,7 +25,7 @@ class UserDownloadRequest(XLSXFileMixin, ReadOnlyModelViewSet):
# id_number = request.user.code # id_number = request.user.code
data = User.objects.all() data = User.objects.all().exclude(id=1)
serializer = headers(data=data, many=True) serializer = headers(data=data, many=True)
serializer.is_valid(raise_exception=False) serializer.is_valid(raise_exception=False)
return Response(serializer.data) return Response(serializer.data)
......
...@@ -11,6 +11,13 @@ from app.entities.models import ( ...@@ -11,6 +11,13 @@ from app.entities.models import (
User, Department, UserImage, AllowedCompany, Application, Module, User, Department, UserImage, AllowedCompany, Application, Module,
ChangeRequestSettings ChangeRequestSettings
) )
import os
import configparser
config = configparser.ConfigParser()
config_file = os.path.join('./', 'env.ini')
config.read(config_file)
import os import os
import configparser import configparser
......
...@@ -55,6 +55,7 @@ class UserViewSet(viewsets.ModelViewSet): ...@@ -55,6 +55,7 @@ class UserViewSet(viewsets.ModelViewSet):
'email', 'contact_no' 'email', 'contact_no'
) )
@rms.AccountValidation
@rms.user_create @rms.user_create
@transaction.atomic @transaction.atomic
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
...@@ -146,22 +147,35 @@ class UserViewSet(viewsets.ModelViewSet): ...@@ -146,22 +147,35 @@ class UserViewSet(viewsets.ModelViewSet):
@transaction.atomic @transaction.atomic
def destroy(self, request, *args, **kwargs): def destroy(self, request, *args, **kwargs):
instance = self.get_object() try:
new_instance = model_to_dict(instance)
UserHistory.objects.filter(username=instance.username).update(deleted=True)
AllowedCompany.objects.filter(id_number=instance.code).delete()
self.perform_destroy(instance)
log_save( instance = self.get_object()
enums.LogEnum.DELETED.value, new_instance = model_to_dict(instance)
enums.LogEntitiesEnum.USER.value, UserHistory.objects.filter(username=instance.username).update(deleted=True)
new_instance['id'], AllowedCompany.objects.filter(id_number=instance.code).delete()
new_instance, self.perform_destroy(instance)
''
) log_save(
enums.LogEnum.DELETED.value,
enums.LogEntitiesEnum.USER.value,
new_instance['id'],
new_instance,
''
)
return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_204_NO_CONTENT)
except IntegrityError as e:
error = f'Cant delete {instance.name} it has an existing transactions on either change request or change request template'
message = {
'code': 400,
'status': 'failed',
'message': error,
}
return Response(message,
status=status.HTTP_400_BAD_REQUEST)
@rms.AccountValidation
@rms.user_create @rms.user_create
@transaction.atomic @transaction.atomic
def update(self, request, *args, **kwargs): def update(self, request, *args, **kwargs):
...@@ -185,9 +199,18 @@ class UserViewSet(viewsets.ModelViewSet): ...@@ -185,9 +199,18 @@ class UserViewSet(viewsets.ModelViewSet):
if cms_form.count() > 0 or cms_template.count() > 0: if cms_form.count() > 0 or cms_template.count() > 0:
raise ParseError( # raise ParseError(
'Cannot update this record the user has a record on change request it might cause a data error' # 'Cannot update this record the user has a record on change request it might cause a data error'
) # )
error = 'Cannot update this record the user has a record on change request it might cause a data error'
message = {
'code': 400,
'status': 'failed',
'message': error,
}
return Response(message,
status=status.HTTP_400_BAD_REQUEST)
serializer = self.get_serializer( serializer = self.get_serializer(
instance, data=request.data, partial=partial instance, data=request.data, partial=partial
...@@ -272,7 +295,15 @@ class UserViewSet(viewsets.ModelViewSet): ...@@ -272,7 +295,15 @@ class UserViewSet(viewsets.ModelViewSet):
else: else:
raise Exception('User not found') # raise Exception('User not found')
error = 'User not found'
message = {
'code': 400,
'status': 'failed',
'message': error,
}
return Response(message,
status=status.HTTP_400_BAD_REQUEST)
return Response( return Response(
{"detail": "Success"}, {"detail": "Success"},
...@@ -296,7 +327,16 @@ class UserViewSet(viewsets.ModelViewSet): ...@@ -296,7 +327,16 @@ class UserViewSet(viewsets.ModelViewSet):
form = request.data form = request.data
if form['new_password'] != form['new_password_confirm']: if form['new_password'] != form['new_password_confirm']:
raise Exception('Passwords must match') # raise Exception('Passwords must match')
error = 'Passwords must match'
message = {
'code': 400,
'status': 'failed',
'message': error,
}
return Response(message,
status=status.HTTP_400_BAD_REQUEST)
existingUser = User.objects.filter(code=code) existingUser = User.objects.filter(code=code)
pk = existingUser.values().first()['id'] pk = existingUser.values().first()['id']
...@@ -322,7 +362,15 @@ class UserViewSet(viewsets.ModelViewSet): ...@@ -322,7 +362,15 @@ class UserViewSet(viewsets.ModelViewSet):
status=status.HTTP_200_OK status=status.HTTP_200_OK
) )
else: else:
raise Exception('User not found') # raise Exception('User not found')
error = 'User not found'
message = {
'code': 400,
'status': 'failed',
'message': error,
}
return Response(message,
status=status.HTTP_400_BAD_REQUEST)
else: else:
serialized.is_valid(raise_exception=True) serialized.is_valid(raise_exception=True)
...@@ -373,7 +421,15 @@ class UserViewSet(viewsets.ModelViewSet): ...@@ -373,7 +421,15 @@ class UserViewSet(viewsets.ModelViewSet):
status=status.HTTP_200_OK status=status.HTTP_200_OK
) )
else: else:
raise Exception('User not found') # raise Exception('User not found')
error = 'User not found'
message = {
'code': 400,
'status': 'failed',
'message': error,
}
return Response(message,
status=status.HTTP_400_BAD_REQUEST)
else: else:
serialized.is_valid(raise_exception=True) serialized.is_valid(raise_exception=True)
...@@ -416,5 +472,13 @@ class UserViewSet(viewsets.ModelViewSet): ...@@ -416,5 +472,13 @@ class UserViewSet(viewsets.ModelViewSet):
status=status.HTTP_201_CREATED, status=status.HTTP_201_CREATED,
headers=headers) headers=headers)
else: else:
raise ParseError('User not found') # raise ParseError('User not found')
error = 'User not found'
message = {
'code': 400,
'status': 'failed',
'message': error,
}
return Response(message,
status=status.HTTP_400_BAD_REQUEST)
return Response(data={"detail": "Success"}) return Response(data={"detail": "Success"})
...@@ -13,6 +13,7 @@ from app.applicationlayer.utils import ( ...@@ -13,6 +13,7 @@ from app.applicationlayer.utils import (
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework import DjangoFilterBackend
from app.applicationlayer.management.application import serializer from app.applicationlayer.management.application import serializer
from app.applicationlayer.management.application.table_filters import ApplicationFilterSet from app.applicationlayer.management.application.table_filters import ApplicationFilterSet
from django.db import IntegrityError
class ApplicationViewSet(viewsets.ModelViewSet): class ApplicationViewSet(viewsets.ModelViewSet):
...@@ -26,6 +27,7 @@ class ApplicationViewSet(viewsets.ModelViewSet): ...@@ -26,6 +27,7 @@ class ApplicationViewSet(viewsets.ModelViewSet):
search_fields = ('name', 'code') search_fields = ('name', 'code')
@decorators.rms.ApplicationValidation
@decorators.rms.application_crate @decorators.rms.application_crate
@transaction.atomic @transaction.atomic
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
...@@ -81,25 +83,32 @@ class ApplicationViewSet(viewsets.ModelViewSet): ...@@ -81,25 +83,32 @@ class ApplicationViewSet(viewsets.ModelViewSet):
return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_204_NO_CONTENT)
@decorators.rms.ApplicationValidation
@decorators.rms.application_crate @decorators.rms.application_crate
@transaction.atomic @transaction.atomic
def update(self, request, *args, **kwargs): def update(self, request, *args, **kwargs):
try:
partial = kwargs.pop('partial', False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
old_instance = model_to_dict(instance)
self.perform_update(serializer)
new_instance = serializer.data
log_save(
enums.LogEnum.UPDATE.value,
enums.LogEntitiesEnum.APPLICATION.value,
old_instance['id'],
old_instance,
new_instance
)
partial = kwargs.pop('partial', False) return Response(serializer.data)
instance = self.get_object() except IntegrityError as e:
serializer = self.get_serializer(instance, data=request.data, partial=partial) return Response(
serializer.is_valid(raise_exception=True) {"message": "Cannot delete or update this reocrd it has foreign key constraint to other tables"},
status=status.HTTP_400_BAD_REQUEST
old_instance = model_to_dict(instance) )
self.perform_update(serializer)
new_instance = serializer.data
log_save(
enums.LogEnum.UPDATE.value,
enums.LogEntitiesEnum.APPLICATION.value,
old_instance['id'],
old_instance,
new_instance
)
return Response(serializer.data)
...@@ -292,18 +292,20 @@ class BatchUploadViewSet(viewsets.ModelViewSet): ...@@ -292,18 +292,20 @@ class BatchUploadViewSet(viewsets.ModelViewSet):
return self.get_paginated_response(message) return self.get_paginated_response(message)
@transaction.atomic # @transaction.atomic
def create(self, request, **kwargs): def create(self, request, **kwargs):
# sp1 = transaction.savepoint() # nothing will save to db
csv_file = request.FILES['file'] csv_file = request.FILES['file']
extension_file = str(csv_file).split('.')[1] extension_file = str(csv_file).split('.')[1]
if extension_file.lower() != 'csv': if extension_file.lower() != 'csv':
return Response( return Response(
{"message": "Only csv extension file is allowed"}, {"message": "Only csv extension file is allowed"},
status=status.HTTP_400_BAD_REQUEST status=status.HTTP_400_BAD_REQUEST
) )
df = pd.read_csv(csv_file, sep=',', skip_blank_lines=True).dropna() df = pd.read_csv(csv_file, sep=',', skip_blank_lines=True)
# df.dropna() df.dropna()
logged_user_type = request.user.user_type logged_user_type = request.user.user_type
logged_user_company = request.user.department.company.name logged_user_company = request.user.department.company.name
logged_user_department = request.user.department.name logged_user_department = request.user.department.name
...@@ -340,7 +342,8 @@ class BatchUploadViewSet(viewsets.ModelViewSet): ...@@ -340,7 +342,8 @@ class BatchUploadViewSet(viewsets.ModelViewSet):
Q(company=user_company) Q(company=user_company)
) )
if not request_department: if not request_department:
# raise ParseError(company_error) etl2.delete()
# transaction.savepoint_rollback(sp1)
return Response( return Response(
{"message": company_error}, {"message": company_error},
# {"message": str(e)}, # {"message": str(e)},
...@@ -349,6 +352,8 @@ class BatchUploadViewSet(viewsets.ModelViewSet): ...@@ -349,6 +352,8 @@ class BatchUploadViewSet(viewsets.ModelViewSet):
elif request.user.user_type == enums_department: elif request.user.user_type == enums_department:
if keys['Department_Code'] != request.user.department.code: if keys['Department_Code'] != request.user.department.code:
etl2.delete()
# transaction.savepoint_rollback(sp1)
return Response( return Response(
{"message": department_error}, {"message": department_error},
# {"message": str(e)}, # {"message": str(e)},
...@@ -429,10 +434,11 @@ class BatchUploadViewSet(viewsets.ModelViewSet): ...@@ -429,10 +434,11 @@ class BatchUploadViewSet(viewsets.ModelViewSet):
code=privilege_department_code code=privilege_department_code
) )
ccr = True if keys['Create_CR'].lower() == 'yes' else False ccr = True if str(keys['Create_CR']).lower() == 'yes' else False
crt = True if keys['Create_Template'].lower() == 'yes' else False crt = True if str(keys['Create_Template']).lower() == 'yes' else False
view_all = True if keys['View_All_CR'].lower() == 'yes' else False view_all = True if str(keys['View_All_CR']).lower() == 'yes' else False
approve_cr = True if keys['Approve_CR'].lower() == 'yes' else False approve_cr = True if str(keys['Approve_CR']).lower() == 'yes' else False
privilege_object = { privilege_object = {
"id_number": current_user, "id_number": current_user,
...@@ -447,6 +453,8 @@ class BatchUploadViewSet(viewsets.ModelViewSet): ...@@ -447,6 +453,8 @@ class BatchUploadViewSet(viewsets.ModelViewSet):
AllowedCompany.objects.create(**privilege_object) AllowedCompany.objects.create(**privilege_object)
except IntegrityError as e: except IntegrityError as e:
etl2.delete()
# transaction.savepoint_rollback(sp1)
return Response( return Response(
{"message": f"Duplicate user privilege at row {data + 2}"}, {"message": f"Duplicate user privilege at row {data + 2}"},
# {"message": str(e)}, # {"message": str(e)},
...@@ -454,26 +462,32 @@ class BatchUploadViewSet(viewsets.ModelViewSet): ...@@ -454,26 +462,32 @@ class BatchUploadViewSet(viewsets.ModelViewSet):
) )
except ObjectDoesNotExist as e: except ObjectDoesNotExist as e:
etl2.delete()
# transaction.savepoint_rollback(sp1)
return Response( return Response(
{"message": f"Department Does not Exist at Privilege row {data + 2}"}, {"message": f"Department Does not Exist at Privilege row {data + 2}"},
status=status.HTTP_400_BAD_REQUEST status=status.HTTP_400_BAD_REQUEST
) )
except IntegrityError as e: except IntegrityError as e:
# etl2.delete() etl2.delete()
# transaction.set_rollback(True) # transaction.savepoint_rollback(sp1)
return Response( return Response(
{"message": f"Record already exist at row {data + 2}"}, {"message": f"Record already exist at row {data + 2}"},
status=status.HTTP_400_BAD_REQUEST status=status.HTTP_400_BAD_REQUEST
) )
except KeyError as e: except KeyError as e:
etl2.delete()
# transaction.savepoint_rollback(sp1)
return Response( return Response(
{"message": f"Missing column {e.args[0]}"}, {"message": f"Missing column {e.args[0]}"},
status=status.HTTP_400_BAD_REQUEST status=status.HTTP_400_BAD_REQUEST
) )
except ObjectDoesNotExist as e: except ObjectDoesNotExist as e:
etl2.delete()
# transaction.savepoint_rollback(sp1)
return Response( return Response(
{"message": f"Department Does not Exist at row {data + 2}"}, {"message": f"Department Does not Exist at row {data + 2}"},
status=status.HTTP_400_BAD_REQUEST status=status.HTTP_400_BAD_REQUEST
......
...@@ -17,6 +17,17 @@ import json ...@@ -17,6 +17,17 @@ import json
REALTIMESERVER_IP = settings.REALTIMESERVER_IP REALTIMESERVER_IP = settings.REALTIMESERVER_IP
def error_message(code, message, status, status_code):
return Response(
{
"code": code,
"message": message,
"status": status
},
status=status_code
)
def model_to_dict(instance): def model_to_dict(instance):
try: try:
mySerializer = copy.deepcopy(DynamicSerializer) mySerializer = copy.deepcopy(DynamicSerializer)
...@@ -37,7 +48,7 @@ class DynamicSerializer(serializers.ModelSerializer): ...@@ -37,7 +48,7 @@ class DynamicSerializer(serializers.ModelSerializer):
class CustomPagination(PageNumberPagination): class CustomPagination(PageNumberPagination):
page_size = 10 page_size = 10
max_page_size = 50 max_page_size = 1000
page_query_param = 'page' page_query_param = 'page'
page_size_query_param = 'page_size' page_size_query_param = 'page_size'
......
...@@ -832,3 +832,4 @@ def list_by_onbehalf_without_dept(user_id_number): ...@@ -832,3 +832,4 @@ def list_by_onbehalf_without_dept(user_id_number):
return True
...@@ -20,6 +20,9 @@ from app.entities import enums, models ...@@ -20,6 +20,9 @@ from app.entities import enums, models
from app.applicationlayer.utils import log_save, CustomPagination from app.applicationlayer.utils import log_save, CustomPagination
from app.applicationlayer.cms.template import serializers from app.applicationlayer.cms.template import serializers
import itertools
from operator import itemgetter
def tmp_add_edit_delete(tmp_request_body, def tmp_add_edit_delete(tmp_request_body,
queryset, queryset,
...@@ -101,3 +104,90 @@ def tmp_add_edit_delete(tmp_request_body, ...@@ -101,3 +104,90 @@ def tmp_add_edit_delete(tmp_request_body,
) )
return True return True
# Check if routing table has Vendor and Requestor
def validation_existing_vendor_requestor(approvers):
approvers_data = sorted(approvers,
key=itemgetter('level'))[-2:]
if (approvers_data[0]['delegation'] == 'DELEGATION-20191119-0000002' and
approvers_data[1]['delegation'] == 'DELEGATION-20191119-0000001'):
return True
else:
return False
# Check if routing table has atleast 1 approver
def validation_existing_approver(approvers):
counter = 0
for approver in approvers:
# count all delegation not equal to Requestor and Vendor
if approver['delegation'] not in ['DELEGATION-20191119-0000002',
'DELEGATION-20191119-0000001']:
counter = counter + 1
return counter
return counter
# Check if a user has multiple same level in routing table
def validation_approver_same_level(approvers):
data_list_appr = []
for approver in approvers:
if 'user' in approver and 'level' in approver:
if not approver['user'] is None:
data_list_appr.append(approver)
# add checking
approvers_data = sorted(data_list_appr,
key=itemgetter('level', 'user'))
for key, value in itertools.groupby(approvers_data,
key=itemgetter('level', 'user')):
count_user_same_level = 0
for i in value:
count_user_same_level = count_user_same_level + 1
user_code = i.get('user')
if count_user_same_level > 1:
user = models.User.objects.get(code=user_code)
user_name = user.name
return user_name
return None
# Check if poc is assigned to another delegation other than Vendor
def validation_poc_vendor_only(poc, approvers):
validate = False
for approver in approvers:
if 'user' in approver and 'delegation' in approver:
if poc == approver['user']:
if not approver['delegation'] == 'DELEGATION-20191119-0000002':
validate = True
return validate
# Check if level if Vendor delegation has same level with other delegation
def validation_vendor_unique_level(approvers):
validate = 0
data_level = []
for approver in approvers:
if 'delegation' in approver:
if approver['delegation'] == 'DELEGATION-20191119-0000002':
data_level.append(approver['level'])
for approver in approvers:
if 'delegation' in approver:
if not approver['delegation'] is None:
if approver['level'] in data_level:
if not approver['delegation'] == 'DELEGATION-20191119-0000002':
validate = approver['level']
return validate
# Generated by Django 2.2 on 2020-02-05 17:07
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('entities', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='changerequestformattachments',
name='file_upload',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.PROTECT, related_name='form_attachments', to='entities.MasterAttachment'),
preserve_default=False,
),
migrations.AlterField(
model_name='changerequesttemplateattachments',
name='file_upload',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.PROTECT, related_name='template_attachments', to='entities.MasterAttachment'),
preserve_default=False,
),
]
# Generated by Django 2.2 on 2020-02-06 14:22
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('entities', '0002_auto_20200205_1707'),
]
operations = [
migrations.RemoveField(
model_name='changerequestformheader',
name='company_desc',
),
migrations.RemoveField(
model_name='changerequestformheader',
name='department_desc',
),
migrations.RemoveField(
model_name='changerequestformheader',
name='requested_desc',
),
]
...@@ -705,9 +705,7 @@ class ChangeRequestTemplateAttachments(BaseAttachment): ...@@ -705,9 +705,7 @@ class ChangeRequestTemplateAttachments(BaseAttachment):
file_upload = models.ForeignKey( file_upload = models.ForeignKey(
MasterAttachment, MasterAttachment,
on_delete=models.PROTECT, on_delete=models.PROTECT,
related_name='template_attachments', related_name='template_attachments'
blank=True,
null=True
) )
template_no = models.ForeignKey( template_no = models.ForeignKey(
ChangeRequestTemplateHeader, ChangeRequestTemplateHeader,
...@@ -784,18 +782,6 @@ class ChangeRequestFormHeader(BaseHeader): ...@@ -784,18 +782,6 @@ class ChangeRequestFormHeader(BaseHeader):
on_delete=models.PROTECT, on_delete=models.PROTECT,
to_field='template_no') to_field='template_no')
status = models.CharField(max_length=50) status = models.CharField(max_length=50)
company_desc = models.CharField(
max_length=255,
null=True,
blank=True)
department_desc = models.CharField(
max_length=255,
null=True,
blank=True)
requested_desc = models.CharField(
max_length=255,
null=True,
blank=True)
requested_to_template_id = models.CharField( requested_to_template_id = models.CharField(
max_length=255) max_length=255)
requested_to_target_date = models.DateTimeField( requested_to_target_date = models.DateTimeField(
...@@ -817,6 +803,18 @@ class ChangeRequestFormHeader(BaseHeader): ...@@ -817,6 +803,18 @@ class ChangeRequestFormHeader(BaseHeader):
self.form_code = code self.form_code = code
self.save() self.save()
# company_desc = models.CharField(
# max_length=255,
# null=True,
# blank=True)
# department_desc = models.CharField(
# max_length=255,
# null=True,
# blank=True)
# requested_desc = models.CharField(
# max_length=255,
# null=True,
# blank=True)
class ChangeRequestFormApprovers(BaseApprover): class ChangeRequestFormApprovers(BaseApprover):
code = models.CharField( code = models.CharField(
...@@ -941,9 +939,7 @@ class ChangeRequestFormAttachments(BaseAttachment): ...@@ -941,9 +939,7 @@ class ChangeRequestFormAttachments(BaseAttachment):
file_upload = models.ForeignKey( file_upload = models.ForeignKey(
MasterAttachment, MasterAttachment,
on_delete=models.PROTECT, on_delete=models.PROTECT,
related_name='form_attachments', related_name='form_attachments'
blank=True,
null=True
) )
class Meta: class Meta:
...@@ -1197,7 +1193,7 @@ class OverdueTrigger(models.Model): ...@@ -1197,7 +1193,7 @@ class OverdueTrigger(models.Model):
class Meta: class Meta:
db_table = 'trigger_overdue' db_table = 'trigger_overdue'
# comment
""" """
********************** **********************
*** AMS TABLES *** *** AMS TABLES ***
......
...@@ -4,9 +4,20 @@ import json ...@@ -4,9 +4,20 @@ import json
from rest_framework.exceptions import ParseError from rest_framework.exceptions import ParseError
from functools import wraps from functools import wraps
from rest_framework.authtoken.models import Token from rest_framework.authtoken.models import Token
from app.entities.models import User, Department, Company from app.entities.models import (User, Department, Company,
ChangeRequestTemplateHeader,
ChangeRequestFormHeader)
from app.entities import enums from app.entities import enums
from django.db.models import Q from django.db.models import Q
from app.businesslayer.changerequest.change_request_template import (
tmp_add_edit_delete,
validation_approver_same_level,
validation_existing_vendor_requestor,
validation_existing_approver,
validation_poc_vendor_only,
validation_vendor_unique_level
)
from app.applicationlayer.utils import error_message
def error_safe(function): def error_safe(function):
...@@ -41,7 +52,7 @@ class rms: ...@@ -41,7 +52,7 @@ class rms:
enums_company = enums.UserTypeEnum.COMPANY_USER_ADMIN.value enums_company = enums.UserTypeEnum.COMPANY_USER_ADMIN.value
enums_department = enums.UserTypeEnum.DEPARTMENT_USER_ADMIN.value enums_department = enums.UserTypeEnum.DEPARTMENT_USER_ADMIN.value
enums_user = enums.UserTypeEnum.USER.value enums_user = enums.UserTypeEnum.USER.value
access_error = "Logged user is not allowed to access this endpoint." access_error = "Logged user is unauthorize to access this section"
department_error = 'Department should be same with the logged user' department_error = 'Department should be same with the logged user'
company_error = 'Company should be same with the logged user' company_error = 'Company should be same with the logged user'
...@@ -61,14 +72,20 @@ class rms: ...@@ -61,14 +72,20 @@ class rms:
def user_create(function): def user_create(function):
@wraps(function) @wraps(function)
def wrapper(self, request, *args, **kwargs): def wrapper(self, request, *args, **kwargs):
print(rms.user_type(self))
if rms.user_type(self) == rms.enums_user: if rms.user_type(self) == rms.enums_user:
raise ParseError( # raise ParseError(
rms.access_error # rms.access_error
# )
return Response(
{"message": rms.access_error},
status=status.HTTP_400_BAD_REQUEST
) )
elif rms.user_type(self) == rms.enums_department: elif rms.user_type(self) == rms.enums_department:
if request.data['department'] != rms.user(self).department.code: if request.data['department'] != rms.user(self).department.code:
raise ParseError( return Response(
rms.department_error {"message": rms.department_error},
status=status.HTTP_400_BAD_REQUEST
) )
elif rms.user_type(self) == rms.enums_company: elif rms.user_type(self) == rms.enums_company:
user_company = rms.user(self).department.company user_company = rms.user(self).department.company
...@@ -77,8 +94,66 @@ class rms: ...@@ -77,8 +94,66 @@ class rms:
Q(company=user_company) Q(company=user_company)
) )
if not request_department: if not request_department:
raise ParseError(rms.company_error) return Response(
{"message": rms.company_error},
status=status.HTTP_400_BAD_REQUEST
)
return function(self, request, *args, **kwargs)
return wrapper
@staticmethod
def ApplicationValidation(function):
@wraps(function)
def wrapper(self, request, *args, **kwargs):
payload = request.data
if ('excel_code' not in payload or
payload['excel_code'].strip() == ''
):
return error_message(
'400', "Excel code is required",
'failed', status.HTTP_400_BAD_REQUEST
)
is_excel_code_exist = self.queryset.filter(
excel_code=payload['excel_code']
)
if request.method.lower() == 'put':
is_excel_code_exist = is_excel_code_exist.exclude(
code=self.kwargs['code']
)
if is_excel_code_exist:
return error_message(
'400', "This excel code is already exists",
'failed', status.HTTP_400_BAD_REQUEST
)
return function(self, request, *args, **kwargs)
return wrapper
@staticmethod
def AccountValidation(function):
@wraps(function)
def wrapper(self, request, *args, **kwargs):
payload = request.data
if 'username' not in payload or payload['username'].strip() == '':
return error_message(
'400',
f"username is required",
'failed',
status.HTTP_400_BAD_REQUEST
)
username = self.queryset.filter(
username=payload['username']
)
if request.method.lower() == 'put':
username = username.exclude(code=self.kwargs['code'])
if username.count() >= 1:
return error_message(
'400',
f"username {username.first().username} is already taken",
'failed',
status.HTTP_400_BAD_REQUEST
)
return function(self, request, *args, **kwargs) return function(self, request, *args, **kwargs)
return wrapper return wrapper
...@@ -218,3 +293,130 @@ class rms: ...@@ -218,3 +293,130 @@ class rms:
return function(self, request, *args, **kwargs) return function(self, request, *args, **kwargs)
return wrapper return wrapper
def TemplateValidation(function):
@wraps(function)
def wrapper(self, request, *args, **kwargs):
template_header = request.data
required = {'requested_to_template_name': 'Template Name',
'requested_to_template_id': 'CR Number prefix',
'requested_to_target_date': 'Lead Time',
'requested_to_company': 'Company',
'requested_to_department': 'Department'}
for key in required.keys():
if (not key in template_header or
str(template_header[key]).strip() == ''):
return error_message('400', required[key] + ' is required',
'failed', status.HTTP_400_BAD_REQUEST)
# Restrict form using Superuser Department
if (template_header['created_by_department'] == 'DEPARTMENT-20190923-0000001' or
template_header['requested_to_department'] == 'DEPARTMENT-20190923-0000001'):
return error_message('400', 'Superuser department cannot be selected',
'failed', status.HTTP_400_BAD_REQUEST)
tmp_approvers = template_header['tmp_approvers']
# Check if Vendor and Requestor are existing on routing table
if len(tmp_approvers) < 2:
return error_message('400', 'Please make sure to add an Approver, Vendor and Requestor into routing table',
'failed', status.HTTP_400_BAD_REQUEST)
else:
result = validation_existing_vendor_requestor(tmp_approvers)
if result is False:
return error_message('400', 'Please add Vendor/Implementor and Requestor into routing table',
'failed', status.HTTP_400_BAD_REQUEST)
# Do not allow adding an approver for the same level
validation_result = validation_approver_same_level(tmp_approvers)
if validation_result is not None:
return error_message('400', validation_result + ' is already exist for the same level of approval.',
'failed', status.HTTP_400_BAD_REQUEST)
# Do not allow saving user as Vendor and other delegation
validate = validation_poc_vendor_only(
template_header['requested_to_user'], tmp_approvers)
if validate is True:
return error_message('400', 'Point of contact can only be assign to Vendor/Implementor',
'failed', status.HTTP_400_BAD_REQUEST)
# Do not allow to save Vendor same level to other delegation
validate = validation_vendor_unique_level(tmp_approvers)
if not validate == 0:
return error_message('400', 'Level ' + str(validate) + ' is already assigned for the Vendor/Implementor.',
'failed', status.HTTP_400_BAD_REQUEST)
return function(self, request, *args, **kwargs)
return wrapper
def FormValidation(function):
@wraps(function)
def wrapper(self, request, *args, **kwargs):
form_header = request.data
required = {'requested_to_template_name': 'CR Name',
'requested_to_target_date': 'Date Required',
'requested_to_company': 'Company',
'requested_to_department': 'Department',
'requested_to_user': 'Point of Contact',
'requested_to_priority': 'Priority Level'}
for key in required.keys():
if not key in form_header or str(form_header[key]).strip() == '':
return error_message('400', required[key] + ' is required',
'failed', status.HTTP_400_BAD_REQUEST)
# restrict superuser department
if (form_header['requested_by_department'] == 'DEPARTMENT-20190923-0000001' or
form_header['requested_to_department'] == 'DEPARTMENT-20190923-0000001'):
return error_message('400', 'Superuser department cannot be selected',
'failed', status.HTTP_400_BAD_REQUEST)
frm_approvers = form_header['frm_approvers']
# Check if Vendor and Requestor are existing on routing table
if len(frm_approvers) < 2:
return error_message('400', 'Please make sure to add an Approver, Vendor and Requestor into routing table',
'failed', status.HTTP_400_BAD_REQUEST)
else:
result = validation_existing_vendor_requestor(frm_approvers)
if result is False:
return error_message('400', 'Please add Vendor/Implementor and Requestor into routing table',
'failed', status.HTTP_400_BAD_REQUEST)
# Do not allow adding an approver for the same level
validation_result = validation_approver_same_level(frm_approvers)
if validation_result is not None:
return error_message('400', validation_result + ' is already exist for the same level of approval.',
'failed', status.HTTP_400_BAD_REQUEST)
# Restrict a requestor to submit a CR without atleast 1 approver
counter = validation_existing_approver(frm_approvers)
if form_header['status'].lower() == 'pending' and counter == 0:
return error_message('400', 'Please select at least 1 approver before submitting this request.',
'failed', status.HTTP_400_BAD_REQUEST)
# Do not allow saving user as Vendor and other delegation
validate = validation_poc_vendor_only(
form_header['requested_to_user'], frm_approvers)
if validate is True:
return error_message('400', 'Point of contact can only be assign to Vendor/Implementor',
'failed', status.HTTP_400_BAD_REQUEST)
# Do not allow to save Vendor same level to other delegation
validate = validation_vendor_unique_level(frm_approvers)
if validate is True:
return error_message('400', 'Vendor/Implementor cannot have same level with other delegation/s',
'failed', status.HTTP_400_BAD_REQUEST)
return function(self, request, *args, **kwargs)
return wrapper
...@@ -13,11 +13,6 @@ https://docs.djangoproject.com/en/2.2/ref/settings/ ...@@ -13,11 +13,6 @@ https://docs.djangoproject.com/en/2.2/ref/settings/
import os import os
import configparser import configparser
config = configparser.ConfigParser()
config_file = os.path.join('./', 'env.ini')
config.read(config_file)
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname( BASE_DIR = os.path.dirname(
os.path.dirname( os.path.dirname(
...@@ -31,10 +26,10 @@ BASE_DIR = os.path.dirname( ...@@ -31,10 +26,10 @@ BASE_DIR = os.path.dirname(
SECRET_KEY = 'w!dkk7gc*dk#4!6ow3s1wc32%_yp$=osgybm=n0vw6k1j^sqo&' SECRET_KEY = 'w!dkk7gc*dk#4!6ow3s1wc32%_yp$=osgybm=n0vw6k1j^sqo&'
# 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
ALLOWED_HOSTS = []
ALLOWED_HOSTS = ['*']
CORS_ORIGIN_ALLOW_ALL = True
# Application definition # Application definition
...@@ -52,7 +47,6 @@ INSTALLED_APPS = [ ...@@ -52,7 +47,6 @@ INSTALLED_APPS = [
'app.accesslayer', 'app.accesslayer',
'app.entities', 'app.entities',
'channels', 'channels',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
...@@ -134,7 +128,7 @@ STATIC_ROOT = os.path.join(BASE_DIR, "static") ...@@ -134,7 +128,7 @@ STATIC_ROOT = os.path.join(BASE_DIR, "static")
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/' MEDIA_URL = '/media/'
# CORS_ORIGIN_ALLOW_ALL = True
REST_SESSION_LOGIN = True REST_SESSION_LOGIN = True
...@@ -174,26 +168,63 @@ EMAIL_HOST_PASSWORD = 'ApK1dtH2qpT/oMl9MEauFvyN9XZDQ1fjzd8TumIs71NG' ...@@ -174,26 +168,63 @@ EMAIL_HOST_PASSWORD = 'ApK1dtH2qpT/oMl9MEauFvyN9XZDQ1fjzd8TumIs71NG'
EMAIL_USE_SSL = False EMAIL_USE_SSL = False
EMAIL_USE_TLS = True EMAIL_USE_TLS = True
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_DEFAULT_SENDER = 'rms.noreply@oneberrysystem.com' EMAIL_DEFAULT_SENDER = 'noreply@rms-hub.com'
###########################################################################
# config
#########################################################################
# EMAIL_TEMPLATES_ROOT = os.path.join(BASE_DIR, "app/helper/email_service/templates")
config = configparser.ConfigParser()
config_file = os.path.join('./', 'env.ini')
config.read(config_file)
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('172.17.0.1', 6379)],
# "hosts": [('127.0.0.1', 6379)],
},
},
}
DATABASES = {
'default': {
'ENGINE': config['SETTINGS']['DATABASE_ENGINE'],
'NAME': config['SETTINGS']['DATABASE_NAME'],
'USER': config['SETTINGS']['DATABASE_USER'],
'PASSWORD': config['SETTINGS']['DATABASE_PASSWORD'],
'HOST': config['SETTINGS']['DATABASE_HOST'],
'PORT': config['SETTINGS']['DATABASE_PORT'],
}
}
# EMAIL_HOST = config['DEV']['EMAIL_HOST'] # ****************
# EMAIL_PORT = config['DEV']['EMAIL_PORT'] # PROGRAM SETTINGS
# EMAIL_HOST_USER = config['DEV']['EMAIL_PORT'] # ****************
# EMAIL_HOST_PASSWORD = config['DEV']['EMAIL_HOST_PASSWORD'] SESSION_TIMEOUT = config['SETTINGS']['SESSION_TIMEOUT']
# EMAIL_USE_SSL = config['DEV']['EMAIL_USE_SSL'] FRONT_END_URL = config['SETTINGS']['FRONT_END_URL']
# EMAIL_USE_TLS = config['DEV']['EMAIL_USE_TLS'] AUTH_ACCESSS_TOKEN_TIMEOUT = config['SETTINGS']['AUTH_ACCESSS_TOKEN_TIMEOUT']
# EMAIL_BACKEND = config['DEV']['EMAIL_BACKEND'] USER_DEFAULT_PASSWORD = config['SETTINGS']['USER_DEFAULT_PASSWORD']
# EMAIL_DEFAULT_SENDER = config['DEV']['EMAIL_DEFAULT_SENDER'] REALTIMESERVER_IP = config['SETTINGS']['REALTIMESERVER_IP']
# Notification Messages
APPROVER_MESSAGE = config['NOTIFICATION_EMAIL']['APPROVER_MESSAGE']
REQUESTOR_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_MESSAGE']
REQUESTOR_REJECT_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_REJECT_MESSAGE']
VENDOR_ACKNOWLEDGE_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_ACKNOWLEDGE_MESSAGE']
REQUESTOR_ACKNOWLEDGE_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_ACKNOWLEDGE_MESSAGE']
REQUESTOR_COMPLETION_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_COMPLETION_MESSAGE']
VENDOR_ACCEPTANCE_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_ACCEPTANCE_MESSAGE']
VENDOR_REJECT_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_REJECT_MESSAGE']
REVISED_MESSAGE = config['NOTIFICATION_EMAIL']['REVISED_MESSAGE']
CANCEL_MESSAGE = config['NOTIFICATION_EMAIL']['CANCEL_MESSAGE']
APPROVER_REJECT_MESSAGE = config['NOTIFICATION_EMAIL']['APPROVER_REJECT_MESSAGE']
#ADMIN PROFILE
CATCH_EMAIL = config['SETTINGS']['CATCH_EMAIL']
CR_FRONT_LINK = config['SETTINGS']['CR_LINK']
# EMAIL_HOST = 'email-smtp.us-west-2.amazonaws.com'
# EMAIL_PORT = 587
# EMAIL_HOST_USER = 'AKIAYA4XVX5XFZHRQATF'
# EMAIL_HOST_PASSWORD = 'BIOG15v+WTbTiBtPKkn+LCjg0UHqO3nLFQezh4pi6g3y'
# EMAIL_USE_SSL = False
# EMAIL_USE_TLS = True
# EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# EMAIL_DEFAULT_SENDER = 'noreply@rms-hub.com'
...@@ -16,9 +16,6 @@ CHANNEL_LAYERS = { ...@@ -16,9 +16,6 @@ CHANNEL_LAYERS = {
'CONFIG': { 'CONFIG': {
"hosts": [('172.17.0.1', 6379)], "hosts": [('172.17.0.1', 6379)],
# "hosts": [('127.0.0.1', 6379)], # "hosts": [('127.0.0.1', 6379)],
# "hosts": [('13.251.192.208', 6379)]
# http://13.251.192.208:7020/
}, },
}, },
} }
......
[SETTINGS]
BATCH_UPLOAD_FORMAT_FILENAME = instruction.pdf
SSL = 1
DATABASE_ENGINE = django.db.backends.mysql
DATABASE_NAME = rms_db
DATABASE_USER = red_database
DATABASE_PASSWORD = password123
DATABASE_HOST = 10.0.75.1
DATABASE_PORT = 3306
SESSION_TIMEOUT = 30
FRONT_END_URL = http://devweb.rmsv2.oneberrysystem.com
AUTH_ACCESSS_TOKEN_TIMEOUT = 3600
USER_DEFAULT_PASSWORD = password
CATCH_EMAIL = gladys@tirsolutions.com
CR_LINK = http://localhost:8000/cms/change-request/form/view
REALTIMESERVER_IP = 127.0.0.1:8000
[NOTIFICATION_EMAIL]
APPROVER_MESSAGE = has sent you an APPROVAL REQUEST for change request;RMS-ACTIONREQUIRED
REQUESTOR_MESSAGE = has APPROVED the change request;RMS-CRAPPROVED
REQUESTOR_REJECT_MESSAGE = has REJECTED the change request;RMS-CRREJECTED
VENDOR_ACKNOWLEDGE_MESSAGE = has sent you an ACKNOWLEDGEMENT REQUEST for change request;RMS-ACTIONREQUIRED-VENDOR
REQUESTOR_ACKNOWLEDGE_MESSAGE = has ACKNOWLEDGED the change request;RMS-CRACKNOWLEDGE
REQUESTOR_COMPLETION_MESSAGE = has COMPLETED the change request;RMS-CRCOMPLETED
VENDOR_ACCEPTANCE_MESSAGE = has ACCEPTED the change request;RMS-CRACCEPTED
VENDOR_REJECT_MESSAGE = has REJECTED the change request;RMS-CRREJECTED-VENDOR
REVISED_MESSAGE = has REJECTED the change request for your revision;RMS-CRREVISED
CANCEL_MESSAGE = has CANCELLED the change request;RMS-CRCANCELLED-USERTRIGGER
APPROVER_REJECT_MESSAGE = has REJECTED the change request for your approval;RMS-CRREJECTED-APPROVER
...@@ -10,7 +10,7 @@ config.read(config_file) ...@@ -10,7 +10,7 @@ config.read(config_file)
if __name__ == "__main__": if __name__ == "__main__":
os.environ.setdefault('DJANGO_SETTINGS_MODULE', os.environ.setdefault('DJANGO_SETTINGS_MODULE',
config['SETTINGS']['CONFIG']) 'config.settings.base')
# os.system('start chrome.exe --kiosk --kiosk-printing # os.system('start chrome.exe --kiosk --kiosk-printing
# http://localhost:8000/') # http://localhost:8000/')
try: try:
......
...@@ -18,5 +18,6 @@ docker run -d --restart=always -p 3001:3000 sit_rms_webv2 npm start ...@@ -18,5 +18,6 @@ docker run -d --restart=always -p 3001:3000 sit_rms_webv2 npm start
Clear Cache REDIS Clear Cache REDIS
docker exec -it container-name redis-cli FLUSHALL
config set stop-writes-on-bgsave-error no config set stop-writes-on-bgsave-error no
docker run -p 6379:6379 -d redis:2.8 docker run -p 6379:6379 -d redis:2.8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment