Commit 82e58763 authored by John Red Medrano's avatar John Red Medrano

Merge pull request #539 in RMS/api-main-service from RMSv2 to staging

* commit '015f53ef': (127 commits)
  add order by on etl endpoint descending order
  email to admin upon bulk create user
  body
  sender body batch email admin
  batch email admin
  requested to user comp and dept details
  batch upload exception
  select_related
  select_related
  try select_related
  vendor email
  approver reject message
  approver msg
  update reject template approver
  replace error at CUA upload user
  replace error key from detail to message to fix the bug on upload users
  updating my copy
  fix route back
  bug fix 2
  bug fix
  ...
parents f56a247c 015f53ef
...@@ -7,7 +7,7 @@ from django.conf import settings ...@@ -7,7 +7,7 @@ from django.conf import settings
class AppTokenAuthentication(TokenAuthentication): class AppTokenAuthentication(TokenAuthentication):
keyword = 'Bearer' keyword = 'Bearer'
def authenticate_credentials(self, key): def authenticate_credentials(self, key):
user, token = super(AppTokenAuthentication, user, token = super(AppTokenAuthentication,
......
...@@ -27,7 +27,7 @@ class Login(ObtainAuthToken): ...@@ -27,7 +27,7 @@ class Login(ObtainAuthToken):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
try: try:
serializer = self.serializer_class(data=request.data, serializer = self.serializer_class(data=request.data,
context={'request': request}) context={'request': request})
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user'] user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user) token, created = Token.objects.get_or_create(user=user)
...@@ -87,7 +87,7 @@ class CurrentUser(APIView): ...@@ -87,7 +87,7 @@ class CurrentUser(APIView):
# @decorators.error_safe # @decorators.error_safe
def get(self, request, token=None, *args, **kwargs): def get(self, request, token=None, *args, **kwargs):
serializer = UserManagementRetreiveSerializer serializer = UserManagementRetreiveSerializer
context = {"request": request} context = {"request": request}
serializer = serializer(request.user, context=context) serializer = serializer(request.user, context=context)
...@@ -164,7 +164,7 @@ class ForgotPassword(APIView): ...@@ -164,7 +164,7 @@ class ForgotPassword(APIView):
created=date_now, created=date_now,
timeout_at=timeout_at timeout_at=timeout_at
).save() ).save()
url = f"{settings.FRONT_END_URL}/forgot-password/reset"\ url = f"{settings.FRONT_END_URL}/forgot-password/reset"\
f"?token={TOKEN}" f"?token={TOKEN}"
......
...@@ -9,7 +9,7 @@ class AllowedCompanySerializer(serializers.ModelSerializer): ...@@ -9,7 +9,7 @@ class AllowedCompanySerializer(serializers.ModelSerializer):
ret['department'] = model_to_dict(instance.group_pivots) ret['department'] = model_to_dict(instance.group_pivots)
ret['company'] = model_to_dict(instance.company_pivot) ret['company'] = model_to_dict(instance.company_pivot)
return ret return ret
class Meta: class Meta:
model = AllowedCompany model = AllowedCompany
fields = '__all__' fields = '__all__'
......
...@@ -11,7 +11,7 @@ class AllowedCompanyFilterSet(filters.FilterSet): ...@@ -11,7 +11,7 @@ class AllowedCompanyFilterSet(filters.FilterSet):
# Q(username__icontains=value) | # Q(username__icontains=value) |
# Q(first_name__icontains=value) | # Q(first_name__icontains=value) |
# Q(last_name__icontains=value)) # Q(last_name__icontains=value))
class Meta: class Meta:
model = AllowedCompany model = AllowedCompany
fields = '__all__' fields = '__all__'
...@@ -20,7 +20,10 @@ from django.db import IntegrityError ...@@ -20,7 +20,10 @@ from django.db import IntegrityError
class AllowedCompanyViewSet(viewsets.ModelViewSet): class AllowedCompanyViewSet(viewsets.ModelViewSet):
queryset = AllowedCompany.objects.all() # queryset = AllowedCompany.objects.all()
queryset = AllowedCompany.objects.select_related(
'id_number', 'company_pivot', 'group_pivots'
).all()
serializer_class = AllowedCompanySerializer serializer_class = AllowedCompanySerializer
pagination_class = CustomPagination pagination_class = CustomPagination
lookup_field = 'code' lookup_field = 'code'
...@@ -47,7 +50,7 @@ class AllowedCompanyViewSet(viewsets.ModelViewSet): ...@@ -47,7 +50,7 @@ class AllowedCompanyViewSet(viewsets.ModelViewSet):
'list of Users found', 'list of Users found',
serializer.data serializer.data
) )
return self.get_paginated_response(message) return self.get_paginated_response(message)
serializer = self.get_serializer(queryset, many=True) serializer = self.get_serializer(queryset, many=True)
...@@ -85,7 +88,6 @@ class AllowedCompanyViewSet(viewsets.ModelViewSet): ...@@ -85,7 +88,6 @@ class AllowedCompanyViewSet(viewsets.ModelViewSet):
return Response(message, status=status.HTTP_400_BAD_REQUEST) return Response(message, status=status.HTTP_400_BAD_REQUEST)
except IntegrityError as e: except IntegrityError as e:
print(str(e))
error = 'Adding the same Department under the same Company is not allowed' error = 'Adding the same Department under the same Company is not allowed'
message = { message = {
'code': 400, 'code': 400,
...@@ -96,8 +98,6 @@ class AllowedCompanyViewSet(viewsets.ModelViewSet): ...@@ -96,8 +98,6 @@ class AllowedCompanyViewSet(viewsets.ModelViewSet):
status=status.HTTP_400_BAD_REQUEST) status=status.HTTP_400_BAD_REQUEST)
except Exception as e: except Exception as e:
# print(str(e))
# error = 'adding the same departments under same Company is not allowed'
message = { message = {
'code': 500, 'code': 500,
'status': 'failed', 'status': 'failed',
......
...@@ -10,11 +10,14 @@ from django.conf import settings ...@@ -10,11 +10,14 @@ from django.conf import settings
from datetime import timedelta from datetime import timedelta
from app.helper.email_service import sender from app.helper.email_service import sender
from app.applicationlayer.utils import main_threading from app.applicationlayer.utils import main_threading
from rest_framework.permissions import AllowAny
CR_FRONT_LINK = settings.CR_FRONT_LINK CR_FRONT_LINK = settings.CR_FRONT_LINK
class CancelTriggerAPIView(views.APIView): class CancelTriggerAPIView(views.APIView):
permission_classes = (AllowAny,)
def get(self, request): def get(self, request):
date_now = datetime.now() date_now = datetime.now()
today_mail = models.CancelTrigger.objects.filter( today_mail = models.CancelTrigger.objects.filter(
...@@ -53,7 +56,7 @@ class CancelTriggerAPIView(views.APIView): ...@@ -53,7 +56,7 @@ class CancelTriggerAPIView(views.APIView):
cancel = models.ChangeRequestFormHeader.objects.filter( cancel = models.ChangeRequestFormHeader.objects.filter(
form_code=data.form_code form_code=data.form_code
).update(status='Cancelled') ).update(status='Cancelled')
list_of_emails.append(data.form_code.form_code) list_of_emails.append(data.form_code.form_code)
today_mail.update(is_sent=True) today_mail.update(is_sent=True)
......
...@@ -10,28 +10,32 @@ from django.conf import settings ...@@ -10,28 +10,32 @@ from django.conf import settings
from datetime import timedelta from datetime import timedelta
from app.helper.email_service import sender from app.helper.email_service import sender
from app.applicationlayer.utils import main_threading from app.applicationlayer.utils import main_threading
from rest_framework.permissions import AllowAny
CR_FRONT_LINK = settings.CR_FRONT_LINK CR_FRONT_LINK = settings.CR_FRONT_LINK
class OverdueTriggerAPIView(views.APIView): class OverdueTriggerAPIView(views.APIView):
permission_classes = (AllowAny,)
def get(self, request): def get(self, request):
date_now = datetime.now() date_now = datetime.now()
today_mail = models.CancelTrigger.objects.filter( today_mail = models.OverdueTrigger.objects.filter(
Q(auto_cancel_date=date_now.strftime('%Y-%m-%d 00:00:00.000')) Q(overdue_date=date_now.strftime('%Y-%m-%d 00:00:00.000')) &
Q(is_sent=False)
) )
list_of_emails = [] list_of_emails = []
for data in today_mail: for data in today_mail:
if data.is_sent == False and data.form_code.status == 'Pending' and data.frm_approver.is_action == True: if data.is_sent == False and (data.form_code.status == 'Pending' or
data.form_code.status == 'Approved' or
data.form_code.status == 'Rejected'):
cr_link = f'{CR_FRONT_LINK}/{data.form_code}' cr_link = f'{CR_FRONT_LINK}/{data.form_code}'
requestor_name = data.form_code.requested_by_user.name requestor_name = data.form_code.requested_by_user.name
auto_cancel_date = data.auto_cancel_date.strftime('%B %d, %Y') target_date = data.form_code.requested_to_target_date.strftime('%B %d, %Y')
date_submitted_last_approver = data.date_submitted_last_approver.strftime('%B %d, %Y')
approver_pending_action = data.frm_approver.user.name
cr_number = data.form_code.requested_to_template_id cr_number = data.form_code.requested_to_template_id
cr_name = data.form_code.requested_to_template_name cr_name = data.form_code.requested_to_template_name
company_requestedto = data.form_code.requested_to_company.name company_requestedto = data.form_code.requested_to_company.name
...@@ -42,17 +46,12 @@ class OverdueTriggerAPIView(views.APIView): ...@@ -42,17 +46,12 @@ class OverdueTriggerAPIView(views.APIView):
requestor_recipient = data.form_code.requested_by_user.email requestor_recipient = data.form_code.requested_by_user.email
admin = 'Test' admin = 'Test'
args_requestor = [requestor_name, auto_cancel_date, args_requestor = [requestor_name, target_date,
date_submitted_last_approver, approver_pending_action,
cr_number, cr_name, company_requestedto, cr_number, cr_name, company_requestedto,
department_requestedto, priority_level, form_status, url, department_requestedto, priority_level, form_status, url,
requestor_recipient, admin] requestor_recipient, admin]
main_threading(args_requestor, sender.routing_table_cancelled) main_threading(args_requestor, sender.routing_table_overdue)
cancel = models.ChangeRequestFormHeader.objects.filter(
form_code=data.form_code
).update(status='Cancelled')
list_of_emails.append(data.form_code.form_code) list_of_emails.append(data.form_code.form_code)
......
...@@ -10,11 +10,14 @@ from django.conf import settings ...@@ -10,11 +10,14 @@ from django.conf import settings
from datetime import timedelta from datetime import timedelta
from app.helper.email_service import sender from app.helper.email_service import sender
from app.applicationlayer.utils import main_threading from app.applicationlayer.utils import main_threading
from rest_framework.permissions import AllowAny
CR_FRONT_LINK = settings.CR_FRONT_LINK CR_FRONT_LINK = settings.CR_FRONT_LINK
class ReminderTriggerAPIView(views.APIView): class ReminderTriggerAPIView(views.APIView):
permission_classes = (AllowAny,)
def get(self, request): def get(self, request):
date_now = datetime.now() date_now = datetime.now()
next_day = date_now + timedelta(days=1) next_day = date_now + timedelta(days=1)
...@@ -23,10 +26,10 @@ class ReminderTriggerAPIView(views.APIView): ...@@ -23,10 +26,10 @@ class ReminderTriggerAPIView(views.APIView):
Q(date_to__lte=date_now.strftime('%Y-%m-%d 00:00:00.000')) & Q(date_to__lte=date_now.strftime('%Y-%m-%d 00:00:00.000')) &
Q(date_to_send=date_now.strftime('%Y-%m-%d 00:00:00.000')) Q(date_to_send=date_now.strftime('%Y-%m-%d 00:00:00.000'))
) )
# print(today_mail)
list_of_emails = [] list_of_emails = []
for data in today_mail: for data in today_mail:
if data.frm_approver.is_action == True: if data.frm_approver.is_action == True and data.form_code.status == 'Pending':
# common details # common details
cr_link = f'{CR_FRONT_LINK}/{data.frm_approver.form_code}' cr_link = f'{CR_FRONT_LINK}/{data.frm_approver.form_code}'
......
...@@ -8,6 +8,7 @@ class ChangeRequestFormApproversSerializer( ...@@ -8,6 +8,7 @@ class ChangeRequestFormApproversSerializer(
): ):
def to_representation(self, instance): def to_representation(self, instance):
ret = super().to_representation(instance) ret = super().to_representation(instance)
print(instance)
try: try:
ret['company'] = { ret['company'] = {
"id": instance.user.department.company.id, "id": instance.user.department.company.id,
...@@ -28,32 +29,53 @@ class ChangeRequestFormApproversSerializer( ...@@ -28,32 +29,53 @@ class ChangeRequestFormApproversSerializer(
"contact_no": instance.user.contact_no "contact_no": instance.user.contact_no
} }
ret['user'] = user_object ret['user'] = user_object
ret['delegation'] = {
"id": instance.delegation.id,
"code": instance.delegation.code,
"name": instance.delegation.name
}
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.lower() == 'requestor':
if instance.tmp_approver.user or instance.tmp_approver.delegation.name.lower() == 'requestor':
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.lower() == 'requestor': if instance.tmp_approver.company or instance.tmp_approver.delegation.name.lower() == 'requestor':
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.lower() == 'requestor': if instance.tmp_approver.department or instance.tmp_approver.delegation.name.lower() == 'requestor':
ret['editable_dept'] = False ret['editable_dept'] = False
else: else:
ret['editable_dept'] = True ret['editable_dept'] = True
# not instance.tmp_approver.delegation.code or
if instance.tmp_approver.delegation:
ret['editable_deleg'] = False
else:
ret['editable_deleg'] = True
# print(instance.tmp_approver.delegation.name)
# comment
# if instance.tmp_approver.delegation.name.lower() == 'requestor':
# ret['editable_user'] = False
# ret['editable_comp'] = False
# ret['editable_dept'] = False
# ret['editable_deleg'] = False
else: else:
ret['editable_user'] = True ret['editable_user'] = True
ret['editable_comp'] = True ret['editable_comp'] = True
ret['editable_dept'] = True ret['editable_dept'] = True
ret['editable_deleg'] = True
else: else:
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
return ret return ret
...@@ -61,13 +83,14 @@ class ChangeRequestFormApproversSerializer( ...@@ -61,13 +83,14 @@ 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.lower() == 'requestor':
if instance.tmp_approver.user or instance.tmp_approver.delegation.name.lower() == 'requestor':
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.lower() == 'requestor': if instance.tmp_approver.company or instance.tmp_approver.delegation.name.lower() == 'requestor':
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,
...@@ -79,7 +102,7 @@ class ChangeRequestFormApproversSerializer( ...@@ -79,7 +102,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.lower() == 'requestor': if instance.tmp_approver.department or instance.tmp_approver.delegation.name.lower() == 'requestor':
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,
...@@ -90,14 +113,35 @@ class ChangeRequestFormApproversSerializer( ...@@ -90,14 +113,35 @@ class ChangeRequestFormApproversSerializer(
ret['department'] = None ret['department'] = None
ret['editable_dept'] = True ret['editable_dept'] = True
if instance.tmp_approver.delegation:
ret['delegation'] = {
"id": instance.tmp_approver.delegation.id,
"code": instance.tmp_approver.delegation.code,
"name": instance.tmp_approver.delegation.name
}
ret['editable_deleg'] = False
else:
ret['delegation'] = None
ret['editable_deleg'] = True
# print(instance.tmp_approver.delegation.name)
# if instance.tmp_approver.delegation.name.lower() == 'requestor':
# ret['editable_user'] = False
# ret['editable_comp'] = False
# ret['editable_dept'] = False
# ret['editable_deleg'] = False
else: else:
ret['editable_user'] = True ret['editable_user'] = True
ret['editable_comp'] = True ret['editable_comp'] = True
ret['editable_dept'] = True ret['editable_dept'] = True
ret['editable_deleg'] = True
else: else:
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
return ret return ret
......
...@@ -13,7 +13,10 @@ from app.applicationlayer.utils import ( ...@@ -13,7 +13,10 @@ from app.applicationlayer.utils import (
class ChangeRequestFormApproversViewset(viewsets.ModelViewSet): class ChangeRequestFormApproversViewset(viewsets.ModelViewSet):
queryset = models.ChangeRequestFormApprovers.objects.all().order_by('level') # queryset = models.ChangeRequestFormApprovers.objects.all().order_by('level')
queryset = models.ChangeRequestFormApprovers.objects.select_related(
'form_code', 'tmp_approver'
).all().order_by('level')
serializer_class = serializers.ChangeRequestFormApproversSerializer serializer_class = serializers.ChangeRequestFormApproversSerializer
pagination_class = CustomPagination pagination_class = CustomPagination
lookup_field = 'code' lookup_field = 'code'
......
...@@ -12,7 +12,10 @@ from app.applicationlayer.utils import ( ...@@ -12,7 +12,10 @@ from app.applicationlayer.utils import (
class ChangeRequestFormAttachmentsViewset(viewsets.ModelViewSet): class ChangeRequestFormAttachmentsViewset(viewsets.ModelViewSet):
queryset = models.ChangeRequestFormAttachments.objects.all() # queryset = models.ChangeRequestFormAttachments.objects.all()
queryset = models.ChangeRequestFormAttachments.objects.select_related(
'form_code', 'file_upload'
).all()
serializer_class = serializers.ChangeRequestFormAttachmentsSerializer serializer_class = serializers.ChangeRequestFormAttachmentsSerializer
pagination_class = CustomPagination pagination_class = CustomPagination
lookup_field = "code" lookup_field = "code"
......
...@@ -13,7 +13,10 @@ from app.applicationlayer.utils import ( ...@@ -13,7 +13,10 @@ from app.applicationlayer.utils import (
class ChangeRequestFormDetailsViewset(viewsets.ModelViewSet): class ChangeRequestFormDetailsViewset(viewsets.ModelViewSet):
queryset = models.ChangeRequestFormDetails.objects.all() # queryset = models.ChangeRequestFormDetails.objects.all()
queryset = models.ChangeRequestFormDetails.objects.select_related(
'form_code'
).all()
serializer_class = serializers.ChangeRequestFormDetailsSerializer serializer_class = serializers.ChangeRequestFormDetailsSerializer
pagination_class = CustomPagination pagination_class = CustomPagination
lookup_field = "code" lookup_field = "code"
......
...@@ -38,7 +38,6 @@ class headers(serializers.ModelSerializer): ...@@ -38,7 +38,6 @@ class headers(serializers.ModelSerializer):
ret['created'] = instance.created.strftime('%Y-%m-%d-%H:%M:%S') ret['created'] = instance.created.strftime('%Y-%m-%d-%H:%M:%S')
ret['action'] = approver ret['action'] = approver
# ret['requested_to_target_date'] = instance.requested_to_target_date.strftime('%Y-%m-%d-%H:%M:%S') # ret['requested_to_target_date'] = instance.requested_to_target_date.strftime('%Y-%m-%d-%H:%M:%S')
print(ret)
return ret return ret
# except Exception as e: # except Exception as e:
# ret['action_required'] = "No" # ret['action_required'] = "No"
......
...@@ -93,19 +93,18 @@ class ChangeRequestFormHeaderSerializer( ...@@ -93,19 +93,18 @@ class ChangeRequestFormHeaderSerializer(
ret['requested_to_company'] = "None" ret['requested_to_company'] = "None"
ret['requested_to_department'] = "None" ret['requested_to_department'] = "None"
ret['requested_to_user'] = "None" ret['requested_to_user'] = "None"
ret['requested_by_user'] ="None" ret['requested_by_user'] = "None"
ret['requested_by_department'] = "None" ret['requested_by_department'] = "None"
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__'
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',
......
...@@ -5,13 +5,14 @@ from app.entities.models import ChangeRequestFormHeader ...@@ -5,13 +5,14 @@ from app.entities.models import ChangeRequestFormHeader
class HeaderFilterSet(filters.FilterSet): class HeaderFilterSet(filters.FilterSet):
# action_required = filters.CharFilter(method='action_required_bar') # action_required = filters.CharFilter(method='action_required_bar')
class Meta:
model = ChangeRequestFormHeader
fields = '__all__'
# def action_required_bar(self, queryset, name, value): # def action_required_bar(self, queryset, name, value):
# return queryset.filter( # return queryset.filter(
# Q(title__icontains=value) | # Q(title__icontains=value) |
# Q(name__icontains=value) | # Q(name__icontains=value) |
# Q(description__icontains=value) # Q(description__icontains=value)
# ) # )
class Meta:
model = ChangeRequestFormHeader
fields = '__all__'
import configparser
import shutil
import os
from django.shortcuts import render from django.shortcuts import render
from rest_framework import viewsets from rest_framework import viewsets
from rest_framework.views import APIView from rest_framework.views import APIView
...@@ -30,7 +33,9 @@ from app.applicationlayer.cms.utils_cr import (number_generator, ...@@ -30,7 +33,9 @@ from app.applicationlayer.cms.utils_cr import (number_generator,
generate_template_id, generate_template_id,
crhistory_create_save, crhistory_create_save,
entity_log_bulk, entity_log_bulk,
reminder_trigger_save) reminder_trigger_save,
overdue_trigger_save,
reset_autoemail_tables)
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
...@@ -62,6 +67,17 @@ from django_filters.rest_framework import DjangoFilterBackend ...@@ -62,6 +67,17 @@ from django_filters.rest_framework import DjangoFilterBackend
import json import json
from app.applicationlayer.utils import main_threading from app.applicationlayer.utils import main_threading
from django.core.files.base import ContentFile
from django.conf import settings
from io import BytesIO
from django.http import HttpResponse
from xhtml2pdf import pisa
config = configparser.ConfigParser()
config_file = os.path.join('./', 'env.ini')
config.read(config_file)
APPROVER_MESSAGE = settings.APPROVER_MESSAGE APPROVER_MESSAGE = settings.APPROVER_MESSAGE
REQUESTOR_MESSAGE = settings.REQUESTOR_MESSAGE REQUESTOR_MESSAGE = settings.REQUESTOR_MESSAGE
REQUESTOR_REJECT_MESSAGE = settings.REQUESTOR_REJECT_MESSAGE REQUESTOR_REJECT_MESSAGE = settings.REQUESTOR_REJECT_MESSAGE
...@@ -74,7 +90,10 @@ VENDOR_REJECT_MESSAGE = settings.VENDOR_REJECT_MESSAGE ...@@ -74,7 +90,10 @@ VENDOR_REJECT_MESSAGE = settings.VENDOR_REJECT_MESSAGE
class ChangeRequestFormsViewset(viewsets.ModelViewSet): class ChangeRequestFormsViewset(viewsets.ModelViewSet):
queryset = models.ChangeRequestFormHeader.objects.all() queryset = models.ChangeRequestFormHeader.objects.select_related(
'requested_by_user', 'requested_by_department', 'template_no'
).all()
# queryset = models.ChangeRequestFormHeader.objects.all()
serializer_class = ChangeRequestFormHeaderSerializer serializer_class = ChangeRequestFormHeaderSerializer
pagination_class = CustomPagination pagination_class = CustomPagination
lookup_field = 'form_code' lookup_field = 'form_code'
...@@ -199,6 +218,22 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -199,6 +218,22 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
overdue_filtered = change_request.filter_overdue(self.queryset) overdue_filtered = change_request.filter_overdue(self.queryset)
overdue = overdue_filtered.count() overdue = overdue_filtered.count()
# server side computations
# status_total = pending + approved + rejected + cancelled + completed
# close = rejected + cancelled + completed
# opened = pending + approved
# open_percent = round((opened/status_total) * 100)
# close_percent = round((close/status_total) * 100)
# priority_total = high + normal
# high_percent = round((high/priority_total) * 100)
# normal_percent = round((normal/priority_total) * 100)
message = { message = {
'account_no': id_number, 'account_no': id_number,
...@@ -211,6 +246,10 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -211,6 +246,10 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
'normal': normal, 'normal': normal,
'awaiting': awaiting, 'awaiting': awaiting,
'overdue': overdue, 'overdue': overdue,
# 'open_percent': open_percent,
# 'close_percent': close_percent,
# 'high_percent': high_percent,
# 'normal_percent': normal_percent,
'code': 200, 'code': 200,
'status': 'success', 'status': 'success',
'message': 'Dashboard Summary' 'message': 'Dashboard Summary'
...@@ -227,7 +266,7 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -227,7 +266,7 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
id_number = self.request.user.code id_number = self.request.user.code
self.queryset = change_request.list_by_user(id_number) self.queryset = change_request.list_by_user(id_number)
self.queryset = change_request.filter_status( self.queryset = change_request.filter_status(
self.queryset, self.queryset,
request.query_params.get('status') request.query_params.get('status')
...@@ -374,21 +413,21 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -374,21 +413,21 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
# queryset = self.get_serializer_class().setup_eager_loading(self.queryset) # queryset = self.get_serializer_class().setup_eager_loading(self.queryset)
models.Notification.objects.filter( # models.Notification.objects.filter(
account_no=id_number, # account_no=id_number,
form_code=form_code, # form_code=form_code,
is_read=False).update(is_read=True) # is_read=False).update(is_read=True)
ROOM = id_number # ROOM = id_number
SENDER = id_number # SENDER = id_number
notif = send_broadcast_message( # notif = send_broadcast_message(
ROOM, # ROOM,
SENDER, # SENDER,
'UPDATE NOTIFICATIONS' # 'UPDATE NOTIFICATIONS'
) # )
main_threading(1, notif) # main_threading(1, notif)
return Response(serializer.data) return Response(serializer.data)
...@@ -494,99 +533,70 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -494,99 +533,70 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
return Response(e, return Response(e,
status=status.HTTP_500_INTERNAL_SERVER_ERROR) status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@transaction.atomic()
@action( @action(
methods=['PATCH'], detail=True, methods=['GET'], detail=True,
url_path='re_route', url_name='re_route' url_path='form-download', url_name='form-download'
) )
def re_route(self, request, *args, **kwargs): def FormDownload(self, request, form_code=None):
args = ['CHANGE_REQUEST_TEMPLATE.html']
# generate batchno history
batchno = get_max_batchno("batch") my_folder = os.path.join(settings.MEDIA_ROOT, f'cr/{request.user.code}')
# partial update attch = models.ChangeRequestFormAttachments.objects.filter(
partial = kwargs.pop('partial', True) form_code=str(form_code)
instance = self.get_object() ).values('file_upload__url')
attch_list = [data['file_upload__url'].split('/')[1] for data in attch]
form_code = kwargs['form_code'] # print(attch.query)
# print(attch)
status_update = {"status": 'Pending'} # print(attch_list)
serializer = self.get_serializer(instance, if os.path.isdir(my_folder):
data=status_update, shutil.rmtree(my_folder)
partial=partial)
user_folder = os.mkdir(my_folder)
serializer.is_valid(raise_exception=True)
old_instance = model_to_dict(instance) for data in args:
self.perform_update(serializer) F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, data), 'r')
result = BytesIO()
form_header = get_object_or_404(models.ChangeRequestFormHeader, pdf = pisa.pisaDocument(F, result)
pk=instance.id) updated_file = ContentFile(result.getvalue())
updated_file.name = f"{data}.pdf"
new_instance = model_to_dict(form_header)
completeName = os.path.join(
# save history in form header os.path.join(settings.MEDIA_ROOT, f'cr/{request.user.code}'),
crhistory_save( updated_file.name
batchno, )
enums.CREnum.REROUTE.value,
enums.CREnum.UPDATE.value,
enums.CREntitiesEnum.CR_FRM_HEADER.value,
form_code,
old_instance,
new_instance
)
approver_data = []
# get all approvers of form
approvers = models.ChangeRequestFormApprovers.objects.filter(
form_code=form_code)
for approver in approvers:
approver_add = {
'id': approver.id,
'action': None,
'remarks': None,
'date_sent': None,
'action_date': None,
'is_action': False
}
approver_data.append(approver_add)
change_request.form_add_edit_delete(
approver_data,
models.ChangeRequestFormApprovers,
enums.CREntitiesEnum.CR_FRM_APPROVER.value,
ChangeRequestFormApproversSerializer,
partial,
self,
form_code,
batchno,
enums.CREnum.REROUTE.value
)
min_level = models.ChangeRequestFormApprovers.objects.filter( file1 = open(completeName, "w")
form_code=form_code file1.close()
).aggregate(Min('level'))
# for file_name in attch_list:
min_level = min_level.get('level__min') # full_file_name = os.path.join(my_folder, file_name)
# if os.path.isfile(full_file_name):
# shutil.copy(full_file_name, dest)
print(attch)
for file_name in attch:
print(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'])
# print(full_file_name)
if os.path.isfile(a):
print('ddd')
print(a)
# print(type(a))
b = open(a, 'r')
shutil.copy(b, my_folder)
else:
print('xxx')
next_approver_email(form_code, min_level) test = shutil.make_archive(my_folder + 'archive', 'zip', my_folder, ".")
# update next approver details
models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) & Q(level=int(min_level))
).update(
date_sent=datetime.now()
)
message = status_message_response( response = HttpResponse(open(test, 'rb'), content_type='application/zip')
200, 'success', response['Content-Disposition'] = 'attachment; filename=change request.zip'
'Change request form successfully re routed', return response
serializer.data
)
return Response(message, status=status.HTTP_200_OK)
@transaction.atomic() @transaction.atomic()
@action( @action(
...@@ -688,16 +698,12 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -688,16 +698,12 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
def actions(self, request, *args, **kwargs): def actions(self, request, *args, **kwargs):
current_user = self.request.user.code current_user = self.request.user.code
action_body = request.data action_body = request.data
id = action_body.get('id', False) id = action_body.get('id', False)
form_code = action_body.get('form_code', False) form_code = action_body.get('form_code', False)
delegation = action_body.get('delegation', False)
action = action_body.get('action', False) action = action_body.get('action', False)
level = action_body.get('level', False)
next_level = int(level) + 1
remarks = action_body.get('remarks', False) remarks = action_body.get('remarks', False)
move_to_level = action_body.get('move_to_level', False)
# generate batchno history # generate batchno history
batchno = get_max_batchno("batch") batchno = get_max_batchno("batch")
...@@ -724,8 +730,6 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -724,8 +730,6 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
self.perform_update(serializer) self.perform_update(serializer)
new_instance = serializer.data new_instance = serializer.data
print(new_instance['action'])
crhistory_save( crhistory_save(
batchno, batchno,
enums.CREnum.ACTION.value, enums.CREnum.ACTION.value,
...@@ -736,248 +740,8 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -736,248 +740,8 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
new_instance new_instance
) )
if action.lower() == 'approved': change_request.cr_routing_actions(new_instance, current_user, move_to_level)
# ---------------- removed code
the_next_vendor = models.ChangeRequestFormApprovers.objects.filter(
form_code=form_code, level=int(next_level),
delegation='Vendor/Implementor'
).first()
if the_next_vendor:
the_last_vendor = models.ChangeRequestFormApprovers.objects.filter(
form_code=form_code, delegation='Vendor/Implementor'
).order_by('level').last()
if the_next_vendor == the_last_vendor:
models.ChangeRequestFormHeader.objects.filter(
form_code=form_code
).update(status='Approved')
# NOTIF MSG FOR REQUESTOR
requestor_notification_msg = REQUESTOR_MESSAGE.split(';')[0]
# NOTIF MSG FOR NEXT APPROVER
notification_msg = APPROVER_MESSAGE.split(';')[0]
# SEND EMAIL AND NOTIF TO REQUESTOR
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action,
remarks, level
)
next_approver_email(form_code, next_level)
date_now = datetime.now()
# update next approver details
models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) & Q(level=int(next_level))
).update(
date_sent=date_now,
is_action=True
)
# update current approver details
models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) & Q(level=int(level))
).update(
is_action=False
)
reminder_trigger_save(form_code, date_now,
approver_instance.date_sent)
elif action.lower() == 'rejected':
# send email to vendor
if delegation.lower() == 'requestor':
notification_msg = VENDOR_REJECT_MESSAGE.split(';')[0]
send_mail_vendor(
current_user, form_code, delegation,
notification_msg, action,
remarks, level
)
prev_level = int(level) - 1
# reset last vendor details
models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) &
Q(level=int(prev_level))
).update(
is_action=True,
action='Acknowledged',
action_date=datetime.now(),
date_sent=datetime.now()
)
else:
prev_vendor = models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) &
Q(action='Completed') &
Q(delegation='Vendor/Implementor') &
Q(level__lte=int(level))
)
if not prev_vendor.count() > 0:
models.ChangeRequestFormHeader.objects.filter(
form_code=form_code
).update(status='Rejected')
# EMAIL CODE FOR REQUESTOR
requestor_notification_msg = REQUESTOR_REJECT_MESSAGE.split(';')[0]
# SEND EMAIL AND NOTIF TO REQUESTOR
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action,
remarks, level
)
else:
# EMAIL CODE FOR REQUESTOR
requestor_notification_msg = REQUESTOR_REJECT_MESSAGE.split(';')[0]
# SEND EMAIL AND NOTIF TO REQUESTOR
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action,
remarks, level
)
notification_msg = VENDOR_REJECT_MESSAGE.split(';')[0]
send_mail_vendor(
current_user, form_code, 'others',
notification_msg, action,
remarks, level
)
last_action_vendor = prev_vendor.last()
models.ChangeRequestFormApprovers.objects.filter(
code=last_action_vendor
).update(
is_action=True,
action='Acknowledged',
action_date=datetime.now(),
date_sent=datetime.now()
)
level = last_action_vendor.level + 1
models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) & Q(level__gte=int(level))
).update(
is_action=False,
action=None,
remarks=None,
action_date=None,
date_sent=None
)
elif action.lower() == 'completed':
the_last_vendor = models.ChangeRequestFormApprovers.objects.filter(
form_code=form_code, delegation='Vendor/Implementor'
).order_by('level').last()
if (current_user == the_last_vendor.user.code and
level == the_last_vendor.level):
models.ChangeRequestFormHeader.objects.filter(
form_code=form_code
).update(status='Approved')
else:
the_next_vendor = models.ChangeRequestFormApprovers.objects.filter(
form_code=form_code, level=int(next_level),
delegation='Vendor/Implementor'
).first()
if the_next_vendor:
if the_next_vendor.user.code == the_last_vendor.user.code:
models.ChangeRequestFormHeader.objects.filter(
form_code=form_code
).update(status='Approved')
else:
models.ChangeRequestFormHeader.objects.filter(
form_code=form_code
).update(status='Pending')
next_approver_email(form_code, next_level)
models.ChangeRequestFormApprovers.objects.filter(
Q(level=int(next_level))
).update(
date_sent=datetime.now(),
is_action=True
)
# update current approver details
models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) & Q(level=int(level))
).update(
is_action=False
)
# EMAIL CODE FOR REQUESTOR
requestor_notification_msg = REQUESTOR_COMPLETION_MESSAGE.split(';')[0]
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action,
remarks, level
)
elif action.lower() == 'acknowledged':
# EMAIL CODE FOR REQUESTOR
requestor_notification_msg = REQUESTOR_ACKNOWLEDGE_MESSAGE.split(';')[0]
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action,
remarks, level
)
elif action.lower() == 'accepted':
models.ChangeRequestFormHeader.objects.filter(
form_code=form_code
).update(status='Completed & Accepted')
# EMAIL CODE FOR VENDOR
requestor_notification_msg = VENDOR_ACCEPTANCE_MESSAGE.split(';')[0]
send_mail_vendor(
current_user, form_code, delegation,
requestor_notification_msg, action,
remarks, level
)
# update is_action for current level
models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) & Q(level=int(level))
).update(
is_action=False
)
elif action.lower() == 'cancelled':
# changed form status to cancelled
models.ChangeRequestFormHeader.objects.filter(
form_code=form_code).update(status='Cancelled')
# update is_action for current level
models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) & Q(level=int(level))
).update(
is_action=False
)
message = status_message_response( message = status_message_response(
200, 'success', 200, 'success',
'Action performed', 'Action performed',
...@@ -1029,8 +793,7 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -1029,8 +793,7 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
self.perform_update(serializer) self.perform_update(serializer)
new_instance = serializer.data new_instance = serializer.data
print(serializer.errors)
# save history in form header # save history in form header
crhistory_save( crhistory_save(
batchno, batchno,
...@@ -1154,9 +917,7 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -1154,9 +917,7 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
pk=instance.id) pk=instance.id)
new_instance = model_to_dict(form_header) new_instance = model_to_dict(form_header)
print(serializer.errors)
# save history in form header # save history in form header
crhistory_create_save( crhistory_create_save(
batchno, batchno,
...@@ -1225,6 +986,8 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -1225,6 +986,8 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
next_approver_email(form_code, min_level) next_approver_email(form_code, min_level)
date_now = datetime.now()
# update next approver details # update next approver details
models.ChangeRequestFormApprovers.objects.filter( models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) & Q(level=int(min_level)) Q(form_code=form_code) & Q(level=int(min_level))
...@@ -1232,7 +995,14 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet): ...@@ -1232,7 +995,14 @@ class ChangeRequestFormsViewset(viewsets.ModelViewSet):
date_sent=datetime.now(), date_sent=datetime.now(),
is_action=True is_action=True
) )
# save details for overdue and auto cancellation
overdue_trigger_save(form_code)
# save details for reminder for first approver
reminder_trigger_save(form_code, date_now,
date_now)
serializer = self.get_serializer(instance) serializer = self.get_serializer(instance)
message = status_message_response( message = status_message_response(
...@@ -1544,14 +1314,47 @@ class ChangeRequestFormPost(APIView): ...@@ -1544,14 +1314,47 @@ class ChangeRequestFormPost(APIView):
next_approver_email(frm_id, min_level) next_approver_email(frm_id, min_level)
date_now = datetime.now()
# update next approver details # update next approver details
models.ChangeRequestFormApprovers.objects.filter( models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=frm_id) & Q(level=int(min_level)) Q(form_code=frm_id) & Q(level=int(min_level))
).update( ).update(
date_sent=datetime.now(), date_sent=date_now,
is_action=True is_action=True
) )
# save details for overdue and auto cancellation
overdue_trigger_save(frm_id)
# save details for reminder for first approver
reminder_trigger_save(frm_id, date_now,
date_now)
else:
template_no = serializer.data['template_no']
CR_Prefix = models.ChangeRequestTemplateHeader.objects.filter(
template_no=template_no
).values('requested_to_template_id')
CR_Prefix = CR_Prefix.values_list('requested_to_template_id', flat=True)[0]
models.ChangeRequestFormHeader.objects.filter(
form_code=frm_id
).update(requested_to_template_id=CR_Prefix)
models.ChangeRequestFormApprovers.objects.filter(
form_code=frm_id
).update(
is_action=False,
action=None,
remarks=None,
action_date=None,
date_sent=None
)
message = { message = {
'code': 201, 'code': 201,
'status': 'success', 'status': 'success',
......
...@@ -12,7 +12,10 @@ from app.applicationlayer.utils import ( ...@@ -12,7 +12,10 @@ from app.applicationlayer.utils import (
class ChangeRequestFormStakeHoldersViewset(viewsets.ModelViewSet): class ChangeRequestFormStakeHoldersViewset(viewsets.ModelViewSet):
queryset = models.ChangeRequestFormStakeHolders.objects.all() # queryset = models.ChangeRequestFormStakeHolders.objects.all()
queryset = models.ChangeRequestFormStakeHolders.objects.select_related(
'form_code'
).all()
serializer_class = serializers.ChangeRequestFormStakeHoldersSerializer serializer_class = serializers.ChangeRequestFormStakeHoldersSerializer
pagination_class = CustomPagination pagination_class = CustomPagination
lookup_field = "code" lookup_field = "code"
......
...@@ -556,12 +556,12 @@ class ChangeRequestFormsViewset(meviewsets.ModelViewSet): ...@@ -556,12 +556,12 @@ class ChangeRequestFormsViewset(meviewsets.ModelViewSet):
the_next_vendor = models.ChangeRequestFormApprovers.objects.filter( the_next_vendor = models.ChangeRequestFormApprovers.objects.filter(
form_code=form_code, level=str(next_level), form_code=form_code, level=str(next_level),
delegation='Vendor/Implementor' delegation__name='Vendor/Implementor'
).first() ).first()
if the_next_vendor: if the_next_vendor:
the_last_vendor = models.ChangeRequestFormApprovers.objects.filter( the_last_vendor = models.ChangeRequestFormApprovers.objects.filter(
form_code=form_code, delegation='Vendor/Implementor' form_code=form_code, delegation__name='Vendor/Implementor'
).order_by('level').last() ).order_by('level').last()
if the_next_vendor == the_last_vendor: if the_next_vendor == the_last_vendor:
...@@ -688,8 +688,7 @@ class ChangeRequestFormsViewset(meviewsets.ModelViewSet): ...@@ -688,8 +688,7 @@ class ChangeRequestFormsViewset(meviewsets.ModelViewSet):
old_instance = model_to_dict(instance) old_instance = model_to_dict(instance)
self.perform_update(serializer) self.perform_update(serializer)
new_instance = serializer.data new_instance = serializer.data
print(serializer.errors)
# save history in form header # save history in form header
crhistory_save( crhistory_save(
batchno, batchno,
...@@ -802,9 +801,7 @@ class ChangeRequestFormsViewset(meviewsets.ModelViewSet): ...@@ -802,9 +801,7 @@ class ChangeRequestFormsViewset(meviewsets.ModelViewSet):
pk=instance.id) pk=instance.id)
new_instance = model_to_dict(form_header) new_instance = model_to_dict(form_header)
print(serializer.errors)
# save history in form header # save history in form header
crhistory_create_save( crhistory_create_save(
batchno, batchno,
......
...@@ -17,16 +17,10 @@ class UserListForm(APIView): ...@@ -17,16 +17,10 @@ class UserListForm(APIView):
try: try:
serializer = ChangeRequestList serializer = ChangeRequestList
dept = self.request.query_params['department_code'] dept = self.request.query_params['department_code']
# company = self.request.query_params['company_code']
# allowed = models.AllowedCompany.objects.filter(
# Q(group_pivots=dept) &
# Q()
# )
user_list = models.User.objects.filter( user_list = models.User.objects.filter(
department=dept department=dept
).exclude(id=1) ).exclude(id=1)
# user_list = user_list.exclude(id=request.user.id)
print(user_list.query)
page = self.paginate_queryset(user_list) page = self.paginate_queryset(user_list)
if page is not None: if page is not None:
......
...@@ -72,9 +72,7 @@ class ChangeRequestCompanyFormViewSet(viewsets.ModelViewSet): ...@@ -72,9 +72,7 @@ class ChangeRequestCompanyFormViewSet(viewsets.ModelViewSet):
Q(requested_by_user=id_number) | Q(requested_by_user=id_number) |
Q(frm_stakes__user__code=id_number) Q(frm_stakes__user__code=id_number)
).values() ).values()
# print(id_number)
# print(forms)
allowed = AllowedCompany.objects.filter( allowed = AllowedCompany.objects.filter(
id_number=id_number id_number=id_number
).values().distinct() ).values().distinct()
......
...@@ -15,4 +15,4 @@ class AdminDepartmentSerializer(serializers.ModelSerializer): ...@@ -15,4 +15,4 @@ class AdminDepartmentSerializer(serializers.ModelSerializer):
fields = '__all__' fields = '__all__'
read_only_fields = ( read_only_fields = (
'created', 'createdby', 'modified', 'modifiedby', 'code', 'created', 'createdby', 'modified', 'modifiedby', 'code',
) )
\ No newline at end of file
...@@ -3,7 +3,7 @@ from rest_framework.response import Response ...@@ -3,7 +3,7 @@ from rest_framework.response import Response
from app.applicationlayer.utils import model_to_dict from app.applicationlayer.utils import model_to_dict
from rest_framework.filters import SearchFilter, OrderingFilter from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters import rest_framework as filters from django_filters import rest_framework as filters
from app.entities.models import Department, AllowedCompany from app.entities.models import Department, AllowedCompany, Delegation
from app.applicationlayer.utils import ( from app.applicationlayer.utils import (
CustomPagination, status_message_response CustomPagination, status_message_response
) )
...@@ -39,7 +39,7 @@ class ChangeRequestDepartmentFormViewSet(viewsets.ModelViewSet): ...@@ -39,7 +39,7 @@ class ChangeRequestDepartmentFormViewSet(viewsets.ModelViewSet):
).values('group_pivots') ).values('group_pivots')
queryset = queryset.filter(code__in=allowed) queryset = queryset.filter(code__in=allowed)
page = self.paginate_queryset(queryset) page = self.paginate_queryset(queryset)
if page is not None: if page is not None:
serializer = self.get_serializer(page, many=True) serializer = self.get_serializer(page, many=True)
...@@ -53,3 +53,8 @@ class ChangeRequestDepartmentFormViewSet(viewsets.ModelViewSet): ...@@ -53,3 +53,8 @@ class ChangeRequestDepartmentFormViewSet(viewsets.ModelViewSet):
serializer = self.get_serializer(queryset, many=True) serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data) return Response(serializer.data)
...@@ -4,8 +4,9 @@ from app.applicationlayer.utils import (CustomPagination, ...@@ -4,8 +4,9 @@ from app.applicationlayer.utils import (CustomPagination,
from app.applicationlayer.management.account.serializer import ChangeRequestList from app.applicationlayer.management.account.serializer import ChangeRequestList
from app.entities import models from app.entities import models
from rest_framework.response import Response from rest_framework.response import Response
from django.db.models import Q from django.db.models import Q, F
from rest_framework import status from rest_framework import status
# from django.db.models import F
class UserListTemplate(APIView): class UserListTemplate(APIView):
...@@ -25,7 +26,8 @@ class UserListTemplate(APIView): ...@@ -25,7 +26,8 @@ class UserListTemplate(APIView):
user_list = models.User.objects.filter( user_list = models.User.objects.filter(
code__in=verified_users code__in=verified_users
) )
print(user_list)
page = self.paginate_queryset(user_list) page = self.paginate_queryset(user_list)
if page is not None: if page is not None:
......
from rest_framework import serializers
from app.entities.models import User
from app.applicationlayer.utils import model_to_dict
class DefaultApproverSerializer(serializers.ModelSerializer):
def to_representation(self, instance):
ret = super().to_representation(instance)
ret['department'] = model_to_dict(instance.department)
ret['company'] = model_to_dict(instance.department.company)
return ret
class Meta:
model = User
fields = ('id', 'code', 'name', 'contact_no', 'email', 'department')
# fields = '__all__'
read_only_fields = (
'created', 'createdby', 'modified', 'modifiedby', 'code',
)
\ No newline at end of file
from django_filters import rest_framework as filters
from django.db.models import Count
from app.entities.models import User
from django.db.models import Q
class DefaultApproverFilterSet(filters.FilterSet):
class Meta:
model = User
fields = '__all__'
from rest_framework import viewsets, status
from rest_framework.response import Response
from app.applicationlayer.utils import model_to_dict
from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters import rest_framework as filters
from app.entities.models import User, AllowedCompany
from app.applicationlayer.utils import (
CustomPagination, status_message_response
)
from django_filters.rest_framework import DjangoFilterBackend
from app.applicationlayer.cms.master.template.default_approver import serializer
from app.applicationlayer.cms.master.template.default_approver.table_filter import (
DefaultApproverFilterSet
)
from app.helper.decorators import rms
from django.db.models import Q
from rest_framework.exceptions import ParseError
class DefaultApproverViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = serializer.DefaultApproverSerializer
pagination_class = CustomPagination
lookup_field = 'code'
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
filterset_class = DefaultApproverFilterSet
ordering_fields = '__all__'
search_fields = ('name', 'department__name', 'code')
def list(self, request, *args, **kwargs):
department = self.request.query_params['department_code']
queryset = self.filter_queryset(self.get_queryset())
default_user = AllowedCompany.objects.filter(
Q(group_pivots=department) &
Q(approve_cr=True)
).values('id_number')
queryset = queryset.filter(code__in=default_user)
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
message = status_message_response(
200,
'success',
'list of Default Approvers found',
serializer.data
)
return self.get_paginated_response(message)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
...@@ -48,18 +48,31 @@ class ChangeRequestTemplateApproversSerializer( ...@@ -48,18 +48,31 @@ class ChangeRequestTemplateApproversSerializer(
else: else:
ret['editable_user'] = True ret['editable_user'] = True
if instance.delegation.lower() == 'requestor': if instance.delegation:
ret['delegation'] = {
"id": instance.delegation.id,
"code": instance.delegation.code,
"name": instance.delegation.name
}
ret['editable_deleg'] = False
else:
ret['editable_deleg'] = True
if instance.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
return ret return ret
except Exception as e: except Exception as e:
ret['editable_user'] = True ret['editable_user'] = True
ret['editable_comp'] = True ret['editable_comp'] = True
ret['editable_dept'] = True ret['editable_dept'] = True
ret['editable_deleg'] = True
return ret return ret
......
...@@ -13,7 +13,10 @@ from app.applicationlayer.utils import ( ...@@ -13,7 +13,10 @@ from app.applicationlayer.utils import (
class ChangeRequestTemplateApproversViewset(viewsets.ModelViewSet): class ChangeRequestTemplateApproversViewset(viewsets.ModelViewSet):
queryset = models.ChangeRequestTemplateApprovers.objects.all() # queryset = models.ChangeRequestTemplateApprovers.objects.all()
queryset = models.ChangeRequestTemplateApprovers.objects.select_related(
'template_no', 'company', 'department'
).all()
serializer_class = serializers.ChangeRequestTemplateApproversSerializer serializer_class = serializers.ChangeRequestTemplateApproversSerializer
pagination_class = CustomPagination pagination_class = CustomPagination
lookup_field = "code" lookup_field = "code"
......
...@@ -13,7 +13,10 @@ from app.applicationlayer.utils import ( ...@@ -13,7 +13,10 @@ from app.applicationlayer.utils import (
class ChangeRequestTemplateAttachmentsViewset(viewsets.ModelViewSet): class ChangeRequestTemplateAttachmentsViewset(viewsets.ModelViewSet):
queryset = models.ChangeRequestTemplateAttachments.objects.all() # queryset = models.ChangeRequestTemplateAttachments.objects.all()
queryset = models.ChangeRequestTemplateAttachments.objects.select_related(
'file_upload', 'template_no'
).all()
serializer_class = serializers.ChangeRequestTemplateAttachmentsSerializer serializer_class = serializers.ChangeRequestTemplateAttachmentsSerializer
pagination_class = CustomPagination pagination_class = CustomPagination
lookup_field = "code" lookup_field = "code"
......
...@@ -13,7 +13,10 @@ from app.applicationlayer.utils import ( ...@@ -13,7 +13,10 @@ from app.applicationlayer.utils import (
class ChangeRequestTemplateDetailsViewset(viewsets.ModelViewSet): class ChangeRequestTemplateDetailsViewset(viewsets.ModelViewSet):
queryset = models.ChangeRequestTemplateDetails.objects.all() # queryset = models.ChangeRequestTemplateDetails.objects.all()
queryset = models.ChangeRequestTemplateDetails.objects.select_related(
'template_no'
).all()
serializer_class = serializers.ChangeRequestTemplateDetailsSerializer serializer_class = serializers.ChangeRequestTemplateDetailsSerializer
pagination_class = CustomPagination pagination_class = CustomPagination
lookup_field = "code" lookup_field = "code"
......
...@@ -43,9 +43,13 @@ class ChangeRequestTemplatesSerializer( ...@@ -43,9 +43,13 @@ class ChangeRequestTemplatesSerializer(
"username": instance.requested_to_user.username, "username": instance.requested_to_user.username,
"code": instance.requested_to_user.code, "code": instance.requested_to_user.code,
"email": instance.requested_to_user.email, "email": instance.requested_to_user.email,
"contact_no": instance.requested_to_user.contact_no "contact_no": instance.requested_to_user.contact_no,
"company_code": instance.requested_to_user.department.company.code,
"company_name": instance.requested_to_user.department.company.name,
"department_code": instance.requested_to_user.department.code,
"department_name": instance.requested_to_user.department.name
} }
ret['requested_to_company'] = { ret['requested_to_company'] = {
"id": instance.requested_to_company.id, "id": instance.requested_to_company.id,
"code": instance.requested_to_company.code, "code": instance.requested_to_company.code,
......
...@@ -46,7 +46,10 @@ from django_filters.rest_framework import DjangoFilterBackend ...@@ -46,7 +46,10 @@ from django_filters.rest_framework import DjangoFilterBackend
class ChangeRequestTemplatesViewset(viewsets.ModelViewSet): class ChangeRequestTemplatesViewset(viewsets.ModelViewSet):
queryset = models.ChangeRequestTemplateHeader.objects.all() # queryset = models.ChangeRequestTemplateHeader.objects.all()
queryset = models.ChangeRequestTemplateHeader.objects.select_related(
'created_by_user', 'created_by_department'
).all()
serializer_class = ChangeRequestTemplatesSerializer serializer_class = ChangeRequestTemplatesSerializer
pagination_class = CustomPagination pagination_class = CustomPagination
lookup_field = 'template_no' lookup_field = 'template_no'
...@@ -61,7 +64,7 @@ class ChangeRequestTemplatesViewset(viewsets.ModelViewSet): ...@@ -61,7 +64,7 @@ class ChangeRequestTemplatesViewset(viewsets.ModelViewSet):
'created', 'created',
'created_by_user__name' 'created_by_user__name'
) )
search_fields = ( search_fields = (
"template_no", "requested_to_template_id", "created_by_user__name", "template_no", "requested_to_template_id", "created_by_user__name",
"created_by_user__code", "created_by_department__name", "created_by_user__code", "created_by_department__name",
...@@ -190,7 +193,7 @@ class ChangeRequestTemplatesViewset(viewsets.ModelViewSet): ...@@ -190,7 +193,7 @@ class ChangeRequestTemplatesViewset(viewsets.ModelViewSet):
template_no = kwargs['template_no'] template_no = kwargs['template_no']
body_data = request.data body_data = request.data
tmp_no_exists = models.ChangeRequestFormHeader.objects.filter( tmp_no_exists = models.ChangeRequestFormHeader.objects.filter(
template_no=template_no) template_no=template_no)
...@@ -361,6 +364,12 @@ class ChangeRequestTemplatePost(APIView): ...@@ -361,6 +364,12 @@ 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)
......
...@@ -13,7 +13,10 @@ from app.applicationlayer.utils import ( ...@@ -13,7 +13,10 @@ from app.applicationlayer.utils import (
class ChangeRequestTemplateStakeholdersViewset(viewsets.ModelViewSet): class ChangeRequestTemplateStakeholdersViewset(viewsets.ModelViewSet):
queryset = models.ChangeRequestTemplateStakeHolders.objects.all() # queryset = models.ChangeRequestTemplateStakeHolders.objects.all()
queryset = models.ChangeRequestTemplateStakeHolders.objects.select_related(
'template_no'
).all()
serializer_class = serializers.ChangeRequestTemplateStakeHoldersSerializer serializer_class = serializers.ChangeRequestTemplateStakeHoldersSerializer
pagination_class = CustomPagination pagination_class = CustomPagination
lookup_field = "code" lookup_field = "code"
......
...@@ -12,6 +12,7 @@ from app.applicationlayer.cms.master.template.company.views import ChangeRequest ...@@ -12,6 +12,7 @@ from app.applicationlayer.cms.master.template.company.views import ChangeRequest
from app.applicationlayer.cms.master.template.department.views import ChangeRequestDepartmentTemplateViewSet from app.applicationlayer.cms.master.template.department.views import ChangeRequestDepartmentTemplateViewSet
from app.applicationlayer.cms.master.template.account.views import UserListTemplate from app.applicationlayer.cms.master.template.account.views import UserListTemplate
from app.applicationlayer.cms.master.template_list.views import ChangeRequestTemplateHeaderMaster from app.applicationlayer.cms.master.template_list.views import ChangeRequestTemplateHeaderMaster
from app.applicationlayer.cms.master.template.default_approver.views import DefaultApproverViewSet
# MASTERS Form # MASTERS Form
...@@ -69,6 +70,7 @@ router.register(r'allowed-companies', allowed.AllowedCompanyViewSet) ...@@ -69,6 +70,7 @@ router.register(r'allowed-companies', allowed.AllowedCompanyViewSet)
router.register(r'template-companies', ChangeRequestCompanyTemplateViewSet) router.register(r'template-companies', ChangeRequestCompanyTemplateViewSet)
router.register(r'template-departments', ChangeRequestDepartmentTemplateViewSet) router.register(r'template-departments', ChangeRequestDepartmentTemplateViewSet)
router.register(r'allowed-templates', ChangeRequestTemplateHeaderMaster) router.register(r'allowed-templates', ChangeRequestTemplateHeaderMaster)
router.register(r'default-approvers', DefaultApproverViewSet)
# filter endpoints under Allowed Companies table # filter endpoints under Allowed Companies table
# filter endpoints under Allowed Companies table # filter endpoints under Allowed Companies table
...@@ -86,7 +88,8 @@ urlpatterns = [ ...@@ -86,7 +88,8 @@ urlpatterns = [
path('template-user-list/', UserListTemplate.as_view(), name="User List"), path('template-user-list/', UserListTemplate.as_view(), name="User List"),
# filter endpoints under Allowed Companies table # filter endpoints under Allowed Companies table
path('reminder/', reminder.ReminderTriggerAPIView.as_view()), path('reminder/', reminder.ReminderTriggerAPIView.as_view()),
# path('cancelled/', cancel.CancelTriggerAPIView.as_view()), path('cancelled/', cancel.CancelTriggerAPIView.as_view()),
path('overdue/', overdue.OverdueTriggerAPIView.as_view()),
] ]
# urlpatterns += format_suffix_patterns(urlpatterns) # urlpatterns += format_suffix_patterns(urlpatterns)
......
...@@ -15,6 +15,7 @@ from rest_framework.exceptions import ParseError ...@@ -15,6 +15,7 @@ from rest_framework.exceptions import ParseError
from django.db import IntegrityError from django.db import IntegrityError
from rest_framework.exceptions import APIException from rest_framework.exceptions import APIException
from django.db.models import Max from django.db.models import Max
import os
CR_FRONT_LINK = settings.CR_FRONT_LINK CR_FRONT_LINK = settings.CR_FRONT_LINK
...@@ -26,11 +27,12 @@ REQUESTOR_ACKNOWLEDGE_MESSAGE = settings.REQUESTOR_ACKNOWLEDGE_MESSAGE ...@@ -26,11 +27,12 @@ REQUESTOR_ACKNOWLEDGE_MESSAGE = settings.REQUESTOR_ACKNOWLEDGE_MESSAGE
REQUESTOR_COMPLETION_MESSAGE = settings.REQUESTOR_COMPLETION_MESSAGE REQUESTOR_COMPLETION_MESSAGE = settings.REQUESTOR_COMPLETION_MESSAGE
VENDOR_ACCEPTANCE_MESSAGE = settings.VENDOR_ACCEPTANCE_MESSAGE VENDOR_ACCEPTANCE_MESSAGE = settings.VENDOR_ACCEPTANCE_MESSAGE
VENDOR_REJECT_MESSAGE = settings.VENDOR_REJECT_MESSAGE VENDOR_REJECT_MESSAGE = settings.VENDOR_REJECT_MESSAGE
REVISED_MESSAGE = settings.REVISED_MESSAGE
CANCEL_MESSAGE = settings.CANCEL_MESSAGE
def entity_log_bulk(queryset, entity, tbl): def entity_log_bulk(queryset, entity, tbl):
try: try:
# print(entity)
for data in queryset: for data in queryset:
test = model_to_dict(data) test = model_to_dict(data)
log_save( log_save(
...@@ -206,12 +208,14 @@ def send_mail_vendor(requestor, ...@@ -206,12 +208,14 @@ def send_mail_vendor(requestor,
recipient = vendor_email recipient = vendor_email
action_type = action action_type = action
delegation_type = delegation delegation_type = delegation
delegation_recipient = 'vendor'
admin = sender_email admin = sender_email
args = [name, action_by, routing_level, status, cr_number, cr_name, args = [name, action_by, routing_level, status, cr_number, cr_name,
company_requestedto, department_requestedto, priority_level, company_requestedto, department_requestedto, priority_level,
url, remarks, recipient, action_type, delegation_type, admin] url, remarks, recipient, action_type, delegation_type,
delegation_recipient, admin]
main_threading(args, sender.routing_table_actions) main_threading(args, sender.routing_table_actions)
message = f"{sender_name} {msg} ({template_name})" message = f"{sender_name} {msg} ({template_name})"
...@@ -219,7 +223,7 @@ def send_mail_vendor(requestor, ...@@ -219,7 +223,7 @@ def send_mail_vendor(requestor,
# create notification # create notification
notification_create(form_code, message, vendor_code, notification_create(form_code, message, vendor_code,
sender_code) sender_code, 'cms')
def send_mail_requestor(current_user, def send_mail_requestor(current_user,
...@@ -274,12 +278,14 @@ def send_mail_requestor(current_user, ...@@ -274,12 +278,14 @@ def send_mail_requestor(current_user,
recipient = requestor_email recipient = requestor_email
action_type = action action_type = action
delegation_type = delegation delegation_type = delegation
delegation_recipient = 'requestor'
admin = sender_email admin = sender_email
args = [name, action_by, routing_level, status, cr_number, cr_name, args = [name, action_by, routing_level, status, cr_number, cr_name,
company_requestedto, department_requestedto, priority_level, company_requestedto, department_requestedto, priority_level,
url, remarks, recipient, action_type, delegation_type, admin] url, remarks, recipient, action_type, delegation_type,
delegation_recipient, admin]
main_threading(args, sender.routing_table_actions) main_threading(args, sender.routing_table_actions)
message = f"{sender_name} {msg} ({template_name})" message = f"{sender_name} {msg} ({template_name})"
...@@ -287,7 +293,78 @@ def send_mail_requestor(current_user, ...@@ -287,7 +293,78 @@ def send_mail_requestor(current_user,
# create notification # create notification
notification_create(form_code, message, requestor_code, notification_create(form_code, message, requestor_code,
current_user) current_user, 'cms')
def send_mail_approver(current_user,
form_code,
delegation,
msg,
action,
remarks,
routing_level,
approver_code):
cr_link = f'{CR_FRONT_LINK}/{form_code}'
template_instance = get_template_instance(form_code)
cr_number = template_instance.requested_to_template_id
template_name = template_instance.requested_to_template_name
requested_to_company = template_instance.requested_to_company.code
requested_to_department = template_instance.requested_to_department.code
requested_by_user = template_instance.requested_by_user.code
requested_to_priority = template_instance.requested_to_priority
cr_status = template_instance.status
# receiver details --------------------------------------------------
approver_instance = get_account_details(approver_code)
approver_name = approver_instance.values_list('name', flat=True)[0]
approver_email = approver_instance.values_list('email', flat=True)[0]
approver_code = approver_instance.values_list('code', flat=True)[0]
# sender details --------------------------------------------------
sender_instance = get_account_details(current_user)
sender_email = sender_instance.values_list('email', flat=True)[0]
sender_name = sender_instance.values_list('name', flat=True)[0]
department = get_dept_details(requested_to_department)
dept_name = department.values_list('name', flat=True)[0]
company = get_companies_details(requested_to_company)
company_name = company.values_list('name', flat=True)[0]
# call sender email
name = approver_name
action_by = sender_name
routing_level = routing_level
status = cr_status
cr_number = cr_number
cr_name = template_name
company_requestedto = company_name
department_requestedto = dept_name
priority_level = requested_to_priority
url = cr_link
recipient = approver_email
action_type = action
delegation_type = delegation
delegation_recipient = 'approver'
admin = sender_email
args = [name, action_by, routing_level, status, cr_number, cr_name,
company_requestedto, department_requestedto, priority_level,
url, remarks, recipient, action_type, delegation_type,
delegation_recipient, admin]
main_threading(args, sender.routing_table_actions)
message = f"{sender_name} {msg} ({template_name})"
# create notification
notification_create(form_code, message, approver_code,
current_user, 'cms')
def next_approver_email(form_code, next_level): def next_approver_email(form_code, next_level):
...@@ -319,14 +396,16 @@ def next_approver_email(form_code, next_level): ...@@ -319,14 +396,16 @@ def next_approver_email(form_code, next_level):
level=str(next_level), level=str(next_level),
form_code=form_code form_code=form_code
) )
# print(next_approver.values())
# LOOP on next approver for sending email # LOOP on next approver for sending email
for n_approver in next_approver: for n_approver in next_approver:
# print(n_approver.delegation)
# NOTIF MSG FOR NEXT APPROVER # NOTIF MSG FOR NEXT APPROVER
msg = APPROVER_MESSAGE.split(';')[0] msg = APPROVER_MESSAGE.split(';')[0]
if n_approver.delegation.lower() == 'vendor/implementor': if n_approver.delegation.name.lower() == 'vendor/implementor':
msg = VENDOR_ACKNOWLEDGE_MESSAGE.split(';')[0] msg = VENDOR_ACKNOWLEDGE_MESSAGE.split(';')[0]
# next approver details -------------------------------------------------- # next approver details --------------------------------------------------
...@@ -347,12 +426,14 @@ def next_approver_email(form_code, next_level): ...@@ -347,12 +426,14 @@ def next_approver_email(form_code, next_level):
url = cr_link url = cr_link
recipient = receiver_email recipient = receiver_email
delegation_type = n_approver.delegation.lower() delegation_type = n_approver.delegation.name.lower()
delegation_recipient = 'None'
admin = sender_email admin = sender_email
args = [name, cr_number, cr_name, args = [name, cr_number, cr_name,
company_requestedto, department_requestedto, priority_level, company_requestedto, department_requestedto, priority_level,
status, url, recipient, delegation_type, admin] status, url, recipient, delegation_type,
delegation_recipient, admin]
main_threading(args, sender.routing_table_actions_required) main_threading(args, sender.routing_table_actions_required)
...@@ -361,7 +442,7 @@ def next_approver_email(form_code, next_level): ...@@ -361,7 +442,7 @@ def next_approver_email(form_code, next_level):
# create notification # create notification
notification_create(form_code, message, receiver_code, notification_create(form_code, message, receiver_code,
sender_code) sender_code, 'cms')
def cancel_overdue(request): def cancel_overdue(request):
...@@ -461,7 +542,6 @@ def crhistory_save(batch_no, main_action, ...@@ -461,7 +542,6 @@ def crhistory_save(batch_no, main_action,
def crhistory_log_bulk_delete(queryset, entity, tbl, form_code, def crhistory_log_bulk_delete(queryset, entity, tbl, form_code,
batch_no, main_action): batch_no, main_action):
try: try:
# print(entity)
for data in queryset: for data in queryset:
test = model_to_dict(data) test = model_to_dict(data)
crhistory_save(batch_no, crhistory_save(batch_no,
...@@ -473,6 +553,44 @@ def crhistory_log_bulk_delete(queryset, entity, tbl, form_code, ...@@ -473,6 +553,44 @@ def crhistory_log_bulk_delete(queryset, entity, tbl, form_code,
'') '')
tbl.objects.filter(id=test['id']).delete() tbl.objects.filter(id=test['id']).delete()
return True
except IntegrityError as exc:
raise APIException(detail=exc)
def crhistory_log_bulk_delete_masterattach(queryset, entity, tbl, form_code,
batch_no, main_action):
try:
for data in queryset:
test = model_to_dict(data)
# print(test)
crhistory_save(batch_no,
main_action,
enums.CREnum.DELETED.value,
entity,
form_code,
test,
'')
tbl.objects.filter(id=test['id']).delete()
# url = models.MasterAttachment.objects.get(id=test['file_upload'])
# models.MasterAttachment.objects.filter(
# id=test['file_upload']).delete()
# r = model_to_dict(url)
# print(r['url'])
# print(settings.MEDIA_ROOT)
# # os.remove(r['url'])
# x = os.path.join(settings.MEDIA_ROOT, r['url'])
# print(x)
# if os.path.exists(os.path.join(settings.MEDIA_ROOT, r['url'])):
# print("file exists")
# # os.remove(r['url'])
# else:
# print("The file does not exist")
return True return True
except IntegrityError as exc: except IntegrityError as exc:
raise APIException(detail=exc) raise APIException(detail=exc)
...@@ -551,7 +669,8 @@ def reminder_trigger_save(form_code, ...@@ -551,7 +669,8 @@ def reminder_trigger_save(form_code,
date_to_send=date_from.strftime('%Y-%m-%d 00:00:00.000'), date_to_send=date_from.strftime('%Y-%m-%d 00:00:00.000'),
auto_cancel_date=auto_cancel_date.strftime('%Y-%m-%d 00:00:00.000'), auto_cancel_date=auto_cancel_date.strftime('%Y-%m-%d 00:00:00.000'),
date_submitted_last_approver=date_submitted_last_approver, date_submitted_last_approver=date_submitted_last_approver,
is_sent=False is_sent=False,
form_code=form_instance
) )
if counter == 0: if counter == 0:
...@@ -560,8 +679,147 @@ def reminder_trigger_save(form_code, ...@@ -560,8 +679,147 @@ def reminder_trigger_save(form_code,
auto_cancel_date=auto_cancel_date.strftime('%Y-%m-%d 00:00:00.000'), auto_cancel_date=auto_cancel_date.strftime('%Y-%m-%d 00:00:00.000'),
date_submitted_last_approver=date_submitted_last_approver, date_submitted_last_approver=date_submitted_last_approver,
is_sent=False, is_sent=False,
frm_approver=approver frm_approver=approver,
cancel_type='from_approval'
) )
counter = counter + 1 counter = counter + 1
return True return True
def overdue_trigger_save(form_code):
form_instance = models.ChangeRequestFormHeader.objects.get(
form_code=form_code)
requested_to_target_date = form_instance.requested_to_target_date
overdue_date = requested_to_target_date + timedelta(days=1)
auto_cancel_date = overdue_date + timedelta(days=30)
models.OverdueTrigger.objects.create(
form_code=form_instance,
overdue_date=overdue_date.strftime('%Y-%m-%d 00:00:00.000'),
is_sent=False
)
models.CancelTrigger.objects.create(
form_code=form_instance,
auto_cancel_date=auto_cancel_date.strftime('%Y-%m-%d 00:00:00.000'),
date_submitted_last_approver=None,
is_sent=False,
frm_approver=None,
cancel_type='from_target_date'
)
return True
def reset_autoemail_tables(form_code):
models.ReminderTrigger.objects.filter(
form_code=form_code
).delete()
models.CancelTrigger.objects.filter(
form_code=form_code
).delete()
models.OverdueTrigger.objects.filter(
form_code=form_code
).delete()
return True
def cancelled_user_trigger(form_code,
action,
routing_level):
cr_link = f'{CR_FRONT_LINK}/{form_code}'
template_instance = get_template_instance(form_code)
cr_number = template_instance.requested_to_template_id
template_name = template_instance.requested_to_template_name
requested_to_company = template_instance.requested_to_company.code
requested_to_department = template_instance.requested_to_department.code
requested_by_user = template_instance.requested_by_user.code
requested_by_username = template_instance.requested_by_user.username
requested_to_priority = template_instance.requested_to_priority
cr_status = template_instance.status
# requestor details --------------------------------------------------
sender_instance = get_account_details(requested_by_user)
sender_email = sender_instance.values_list('email', flat=True)[0]
sender_name = sender_instance.values_list('name', flat=True)[0]
sender_code = sender_instance.values_list('code', flat=True)[0]
department = get_dept_details(requested_to_department)
dept_name = department.values_list('name', flat=True)[0]
company = get_companies_details(requested_to_company)
company_name = company.values_list('name', flat=True)[0]
# get details of approvers received an email about the CR
received_form_approvers = models.ChangeRequestFormApprovers.objects.filter(
~Q(date_sent=None) &
Q(form_code=form_code)
)
received_form_approvers = received_form_approvers.values_list('user_id')
received_history_approvers = models.ChangeRequestHistory.objects.filter(
Q(form_code=form_code) &
Q(entity='CR_FRM_APPROVER') &
Q(main_action='ACTION')
).values_list('modifiedby', flat=True).distinct()
received_history_approvers = models.User.objects.filter(
Q(username__in=received_history_approvers) |
Q(code__in=received_form_approvers)
).exclude(username=requested_by_username)
# comment
# LOOP on next approver for sending email
for n_approver in received_history_approvers:
# NOTIF MSG FOR NEXT APPROVER
msg = CANCEL_MESSAGE.split(';')[0]
# next approver details --------------------------------------------------
receiver_instance = get_account_details(n_approver.code)
receiver_name = receiver_instance.values_list('name', flat=True)[0]
receiver_email = receiver_instance.values_list('email', flat=True)[0]
receiver_code = receiver_instance.values_list('code', flat=True)[0]
# call sender email
name = receiver_name
action_by = sender_name
routing_level = routing_level
status = cr_status
cr_number = cr_number
cr_name = template_name
company_requestedto = company_name
department_requestedto = dept_name
priority_level = requested_to_priority
url = cr_link
remarks = 'None'
recipient = receiver_email
action_type = action
delegation_type = 'others'
delegation_recipient = 'None'
admin = sender_email
args = [name, action_by, routing_level, status, cr_number, cr_name,
company_requestedto, department_requestedto, priority_level,
url, remarks, recipient, action_type, delegation_type,
delegation_recipient, admin]
main_threading(args, sender.routing_table_actions)
message = f"{sender_name} {msg} ({template_name})"
# create notification
notification_create(form_code, message, receiver_code,
sender_code, 'cms')
\ No newline at end of file
...@@ -5,7 +5,6 @@ from django.db.models import Q ...@@ -5,7 +5,6 @@ from django.db.models import Q
class headers(serializers.ModelSerializer): class headers(serializers.ModelSerializer):
def to_representation(self, instance): def to_representation(self, instance):
ret = super().to_representation(instance) ret = super().to_representation(instance)
ret['deparment'] = instance.department.name ret['deparment'] = instance.department.name
...@@ -13,8 +12,6 @@ class headers(serializers.ModelSerializer): ...@@ -13,8 +12,6 @@ class headers(serializers.ModelSerializer):
return ret return ret
class Meta: class Meta:
model = models.User model = models.User
fields = ( fields = (
......
...@@ -20,7 +20,7 @@ class UserDownloadRequest(XLSXFileMixin, ReadOnlyModelViewSet): ...@@ -20,7 +20,7 @@ class UserDownloadRequest(XLSXFileMixin, ReadOnlyModelViewSet):
renderer_classes = (XLSXRenderer,) renderer_classes = (XLSXRenderer,)
filename = 'User List.xlsx' filename = 'User List.xlsx'
permission_classes = (AllowAny,) permission_classes = (AllowAny,)
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
# id_number = request.user.code # id_number = request.user.code
......
...@@ -10,8 +10,7 @@ class headers(serializers.ModelSerializer): ...@@ -10,8 +10,7 @@ class headers(serializers.ModelSerializer):
ret['modified'] = instance.modified.strftime('%Y-%m-%d-%H:%M:%S') ret['modified'] = instance.modified.strftime('%Y-%m-%d-%H:%M:%S')
return ret return ret
class Meta: class Meta:
model = models.Company model = models.Company
fields = ( fields = (
......
...@@ -50,6 +50,15 @@ class UserEditSerializer(serializers.ModelSerializer): ...@@ -50,6 +50,15 @@ class UserEditSerializer(serializers.ModelSerializer):
class ChangeRequestList(serializers.ModelSerializer): class ChangeRequestList(serializers.ModelSerializer):
def to_representation(self, instance):
ret = super().to_representation(instance)
ret['company_name'] = instance.department.company.name
ret['company_code'] = instance.department.company.code
ret['department_code'] = instance.department.code
ret['department_name'] = instance.department.name
return ret
class Meta: class Meta:
model = User model = User
fields = ( fields = (
......
import copy import copy
import threading import threading
import pandas as pd
import csv
import io, os
from app.entities import enums from app.entities import enums
from django.db import transaction from django.db import transaction
from app.helper import decorators from app.helper import decorators
...@@ -13,7 +16,8 @@ from rest_framework.response import Response ...@@ -13,7 +16,8 @@ from rest_framework.response import Response
from app.applicationlayer.utils import model_to_dict from app.applicationlayer.utils import model_to_dict
from app.entities.models import ( from app.entities.models import (
User, EntityLog, PasswordReset, Application, UserImage, User, EntityLog, PasswordReset, Application, UserImage,
ChangeRequestFormHeader, ChangeRequestTemplateHeader ChangeRequestFormHeader, ChangeRequestTemplateHeader,
AllowedCompany, Company, Department, UserHistory
) )
from app.helper.decorators import rms, error_safe from app.helper.decorators import rms, error_safe
from django.contrib.auth.hashers import make_password from django.contrib.auth.hashers import make_password
...@@ -23,6 +27,7 @@ from rest_framework.filters import SearchFilter, OrderingFilter ...@@ -23,6 +27,7 @@ from rest_framework.filters import SearchFilter, OrderingFilter
from app.applicationlayer.management.account.table_filters import AccountFilterset from app.applicationlayer.management.account.table_filters import AccountFilterset
from app.applicationlayer.management.account import serializer from app.applicationlayer.management.account import serializer
from app.helper.file_manager import FileHelper from app.helper.file_manager import FileHelper
from django.db import IntegrityError
from app.applicationlayer.utils import ( from app.applicationlayer.utils import (
CustomPagination, status_message_response, log_save, CustomPagination, status_message_response, log_save,
main_threading main_threading
...@@ -66,8 +71,6 @@ class UserViewSet(viewsets.ModelViewSet): ...@@ -66,8 +71,6 @@ class UserViewSet(viewsets.ModelViewSet):
if request.data['user_type'] != 'USR': if request.data['user_type'] != 'USR':
rms = Application.objects.filter(id=1).values('code').first() rms = Application.objects.filter(id=1).values('code').first()
app.append(rms['code']) app.append(rms['code'])
# else:
# app = request.data['application']
...@@ -145,6 +148,8 @@ class UserViewSet(viewsets.ModelViewSet): ...@@ -145,6 +148,8 @@ class UserViewSet(viewsets.ModelViewSet):
instance = self.get_object() instance = self.get_object()
new_instance = model_to_dict(instance) 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) self.perform_destroy(instance)
log_save( log_save(
...@@ -228,6 +233,193 @@ class UserViewSet(viewsets.ModelViewSet): ...@@ -228,6 +233,193 @@ class UserViewSet(viewsets.ModelViewSet):
) )
# @rms.user_create
# @action(detail=False,
# methods=['put'],
# url_path='batch-upload',
# name="upload User")
# @decorators.error_safe
# @transaction.atomic
# def BatchUpload(self, request):
# csv_file = request.FILES['file']
# df = pd.read_csv(csv_file, sep=',', skiprows=0)
# logged_user_type = request.user.user_type
# logged_user_company = request.user.department.company.name
# logged_user_department = request.user.department.name
# logged_user_email = request.user.email
# email_users = []
# for data, keys in df.iterrows():
# try:
# user_department = Department.objects.filter(
# Q(name__icontains=keys['department']) &
# Q(company__name__icontains=logged_user_company)
# ).first()
# if logged_user_type == 'CUA':
# user_department = Department.objects.filter(
# Q(name__icontains=keys['department']) &
# Q(company__name__icontains=logged_user_company)
# ).first()
# if user_department == None:
# msg = f"company is not the same with the logged user at row {data + 2}"
# return Response(
# {"message": msg},
# status=status.HTTP_400_BAD_REQUEST
# )
# elif logged_user_type == 'DUA':
# user_department = Department.objects.get(
# name__icontains=logged_user_department
# )
# elif logged_user_type == 'USR':
# return Response(
# {"message": "Logged User is not allowed"},
# status=status.HTTP_400_BAD_REQUEST
# )
# else:
# user_department = Department.objects.get(
# name__icontains=keys['department']
# )
# default_app = Application.objects.filter(
# excel_code=keys['default_app']
# ).first()
# enums_super = enums.UserTypeEnum.SUPER_USER.value
# enums_OUA = enums.UserTypeEnum.OVERALL_USER_ADMIN.value
# enums_company = enums.UserTypeEnum.COMPANY_USER_ADMIN.value
# enums_department = enums.UserTypeEnum.DEPARTMENT_USER_ADMIN.value
# enums_user = enums.UserTypeEnum.USER.value
# if keys['user_type'].lower() == 'super user' and logged_user_type == enums_super:
# user_type = enums.UserTypeEnum.SUPER_USER.value
# elif keys['user_type'].lower() == 'super user' and logged_user_type != enums_super:
# return Response(
# {"message": f"This user is not allowed to create super user. data error at row {data + 2}"},
# status=status.HTTP_201_CREATED
# )
# elif keys['user_type'].lower() == 'overall user admin':
# user_type = enums.UserTypeEnum.OVERALL_USER_ADMIN.value
# elif keys['user_type'].lower() == 'company user admin':
# user_type = enums.UserTypeEnum.COMPANY_USER_ADMIN.value
# elif keys['user_type'].lower() == 'department user admin':
# user_type = enums.UserTypeEnum.DEPARTMENT_USER_ADMIN.value
# else:
# user_type = enums.UserTypeEnum.USER.value
# users = {
# "username": keys['username'],
# "name": keys['name'],
# "department": user_department,
# "email": keys['email'],
# "contact_no": keys['contact_no'],
# "default_app": default_app,
# "user_type": user_type
# }
# current_user = User.objects.create(
# **users
# )
# password = User.objects.make_random_password(length=10)
# password_hash = make_password(password)
# current_user.password = password_hash
# current_user.save()
# app = Application.objects.filter(
# excel_code__in=keys['application'].split(',')
# )
# update_user = current_user.application.set(app)
# for instance in keys['privilege'].split(';'):
# privilege_list = instance.split(',')
# this_company = Company.objects.filter(
# name__icontains=privilege_list[0]
# ).first()
# this_department = Department.objects.filter(
# name__icontains=privilege_list[1]
# ).first()
# if privilege_list[2] == 0:
# privilege_list[2] = False
# else:
# privilege_list[2] = True
# if privilege_list[3] == 0:
# privilege_list[3] = False
# else:
# privilege_list[3] = True
# if privilege_list[4] == 0:
# privilege_list[4] = False
# else:
# privilege_list[4] = True
# current_user = User.objects.get(id=current_user.id)
# try:
# privilege_object = {
# "id_number": current_user,
# "company_pivot": this_company,
# "group_pivots": this_department,
# "create_change_request": privilege_list[2],
# "create_change_request_template": privilege_list[3],
# "view_all_change_request": privilege_list[4],
# "approve_cr": privilege_list[5]
# }
# AllowedCompany.objects.create(**privilege_object)
# except IntegrityError as e:
# return Response(
# {"message": f"Duplicate user privilege at row {data + 2}"},
# status=status.HTTP_400_BAD_REQUEST
# )
# except IntegrityError as e:
# return Response(
# {"message": f"Record already exist at row {data + 2}"},
# status=status.HTTP_400_BAD_REQUEST
# )
# except KeyError as e:
# return Response(
# {"message": "Missing column user_type"},
# status=status.HTTP_400_BAD_REQUEST
# )
# del users['department']
# del users['contact_no']
# del users['default_app']
# del users['user_type']
# users['password'] = password
# UserHistory.objects.create(
# **users
# )
# users['admin'] = logged_user_email
# send_mail = UserHistory.objects.filter(sent=False)[0:100].values(
# 'name', 'username', 'email', 'password'
# )
# df = pd.DataFrame(send_mail)
# df.to_csv("users.csv", index=False)
# args = ["users.csv", logged_user_email]
# main_threading(args, sender.batch_email_admin)
# args = [send_mail, logged_user_email]
# main_threading(args, sender.batch_email_users)
# return Response(
# {"message": "File already uploaded"},
# status=status.HTTP_201_CREATED
# )
@action(detail=True, @action(detail=True,
methods=['put'], methods=['put'],
url_path='reset-password', url_path='reset-password',
......
...@@ -24,12 +24,12 @@ class ApplicationViewSet(viewsets.ModelViewSet): ...@@ -24,12 +24,12 @@ class ApplicationViewSet(viewsets.ModelViewSet):
filterset_class = ApplicationFilterSet filterset_class = ApplicationFilterSet
ordering_fields = '__all__' ordering_fields = '__all__'
search_fields = ('name', 'code') search_fields = ('name', 'code')
@decorators.rms.application_crate @decorators.rms.application_crate
@transaction.atomic @transaction.atomic
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data) serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
self.perform_create(serializer) self.perform_create(serializer)
......
from rest_framework import serializers
from app.entities.models import (
ExtractTransformLoad, UserHistory, MasterAttachment
)
class ExtractTransformLoadSerializer(serializers.ModelSerializer):
class Meta:
model = ExtractTransformLoad
fields = '__all__'
read_only_fields = (
'created', 'createdby', 'modified', 'modifiedby', 'code',
)
class UserHistorySerializer(serializers.ModelSerializer):
class Meta:
model = UserHistory
fields = '__all__'
read_only_fields = (
'created', 'createdby', 'modified', 'code'
)
class BatchUploadSerializer(serializers.ModelSerializer):
class Meta:
model = MasterAttachment
fields = '__all__'
read_only_fields = (
'created', 'createdby', 'modified', 'modifiedby', 'code',
)
class BatchUploadSerializer(serializers.ModelSerializer):
class Meta:
model = MasterAttachment
fields = '__all__'
read_only_fields = (
'created', 'createdby', 'modified', 'modifiedby', 'code',
)
from django_filters import rest_framework as filters
from app.entities.models import UserHistory, ExtractTransformLoad
class ExtractTransformLoadFilter(filters.FilterSet):
class Meta:
model = ExtractTransformLoad
fields = '__all__'
import os
import datetime
import threading
import configparser
import pandas as pd
from datetime import datetime
from app.entities import enums
from django.db import transaction
from app.helper import decorators
from django.db import IntegrityError
from app.helper.email_service import sender
from rest_framework import status, viewsets
from rest_framework.response import Response
from app.applicationlayer.management.batchupload.serializer import (
ExtractTransformLoadSerializer,
UserHistorySerializer,
BatchUploadSerializer
)
from app.entities.models import (
User, Application, ExtractTransformLoad,
AllowedCompany, Company, Department, UserHistory, MasterAttachment
)
from app.applicationlayer.utils import (
status_message_response,
main_threading, PaginationForETL
)
from django.db.models import Q
from rest_framework.exceptions import ParseError
from rest_framework.decorators import action
from django.contrib.auth.hashers import make_password
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import SearchFilter, OrderingFilter
from app.applicationlayer.management.batchupload.table_filters import ExtractTransformLoadFilter
from django.db.models import F, Value
from django.core.files.base import ContentFile
config = configparser.ConfigParser()
config_file = os.path.join('./', 'env.ini')
config.read(config_file)
from django.conf import settings
from io import BytesIO
from django.http import HttpResponse
from django.template.loader import get_template
from xhtml2pdf import pisa
from django.core.files.storage import FileSystemStorage
from django.core.exceptions import ObjectDoesNotExist
import sys
import os
import zipfile
import shutil
class BatchUploadViewSet(viewsets.ModelViewSet):
queryset = ExtractTransformLoad.objects.all().order_by('-created')
serializer_class = ExtractTransformLoadSerializer
pagination_class = PaginationForETL
lookup_field = 'code'
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
filterset_class = ExtractTransformLoadFilter
ordering_fields = (
'file_name', 'model_type', 'code'
)
search_fields = (
'file_name', 'model_type', 'code'
)
def list(self, request, *args, **kwargs):
logged_user = request.user.username
queryset = self.filter_queryset(self.get_queryset().filter(createdby=logged_user))
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
message = status_message_response(
200,
'success',
'',
serializer.data
)
return self.get_paginated_response(message)
serializer = self.get_serializer(queryset, many=True)
return Response(
serializer.data,
status=status.HTTP_200_OK
)
@action(
detail=True, methods=['get'],
url_path='users', name='list of batch upload users'
)
def Users(self, request, code=None):
self.serializer_class = UserHistorySerializer
queryset = UserHistory.objects.filter(file_name=code)
page = self.paginate_queryset(queryset)
serializer = self.get_serializer(page, many=True)
message = status_message_response(
200,
'success',
'List of User found',
serializer.data
)
return self.get_paginated_response(message)
@action(
detail=False, methods=['get'],
url_path='pdf-instruction', name='how to upload bulk users'
)
def testpdf(self, request, code=None):
F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, 'RMS-NEWUSER.html'), 'r')
result = BytesIO()
pdf = pisa.pisaDocument(F, result)
updated_file = ContentFile(result.getvalue())
updated_file.name = "cr_download.pdf"
my_folder = os.path.join(settings.MEDIA_ROOT, f'cr/{request.user.code}')
if os.path.isdir(my_folder):
shutil.rmtree(my_folder)
user_folder = os.mkdir(my_folder)
completeName = os.path.join(os.path.join(settings.MEDIA_ROOT, f'cr/{request.user.code}'), updated_file.name)
file1 = open(completeName, "w+")
# response = HttpResponse(open(my_folder, 'rb'), content_type='application/zip')
# response['Content-Disposition'] = 'attachment; filename=any_name_you_like.zip'
# return response
message = status_message_response(
200,
'success',
'test',
"sss"
)
return Response(message)
# return sender.to_pdf()
@action(
detail=False, methods=['get'],
url_path='user-instruction', name='how to upload bulk users'
)
def UserInstruction(self, request, code=None):
self.serializer_class = BatchUploadSerializer
queryset = MasterAttachment.objects.filter(
url__contains=config['SETTINGS']['BATCH_UPLOAD_FORMAT_FILENAME']
)
page = self.paginate_queryset(queryset)
serializer = self.get_serializer(page, many=True)
message = status_message_response(
200,
'success',
'',
serializer.data
)
return self.get_paginated_response(message)
@action(
detail=False, methods=['get'],
url_path='user-format-download', name='Users file format'
)
def UserFormat(self, request, code=None):
attach_user = MasterAttachment.objects.filter(attch_ref='etl_gen')
if attach_user:
attach_user.first().delete()
departments = Department.objects.exclude(id=1).annotate(
Privilege_Company=F('company__name'),
Privilege_Department=F('name'),
Privilege_Department_Code=F('code')
).values(
'Privilege_Company',
'Privilege_Department',
'Privilege_Department_Code'
)
data = {
'Username': ["ob-john"],
'Name': ["John Doe"],
'Company': [departments[0]['Privilege_Company']],
'Department': [departments[0]['Privilege_Department']],
'Department_Code': [departments[0]['Privilege_Department_Code']],
'Email': ["johndoe@gmail.com"],
'Contact_No': ["123456"],
'Application': ["cms,ams"],
'Default_app': ["cms"],
'Privilege_Company': [departments[0]['Privilege_Company']],
'Privilege_Department': [departments[0]['Privilege_Department']],
'Privilege_Department_Code': [departments[0]['Privilege_Department_Code']],
'Create_CR': ["Yes"],
'Create_Template': ["No"],
'View_All_CR': ["Yes"],
'Approve_CR': ["Yes"]
}
cols = ['Username', 'Name', 'Company', 'Department', 'Department_Code']
cols += ['Email', 'Contact_No', 'Application', 'Default_app']
cols += ['Privilege_Company', 'Privilege_Department', 'Privilege_Department_Code']
cols += ['Create_CR', 'Create_Template', 'View_All_CR', 'Approve_CR']
df = pd.DataFrame(data)
header = {"Privilege_Company": ['Please use this department code as reference']}
df3 = pd.DataFrame(
header
)
df2 = pd.DataFrame(
departments
)
df_row_reindex = pd.concat([df, df3, df2])
df_row_reindex = df_row_reindex.reindex(columns=cols)
df_row_reindex = df_row_reindex.to_csv(index=False)
updated_file = ContentFile(df_row_reindex)
updated_file.name = "user_format.csv"
uploaded = MasterAttachment.objects.create(
url=updated_file,
attch_ref='etl_gen'
)
self.serializer_class = BatchUploadSerializer
queryset = MasterAttachment.objects.filter(id=uploaded.id)
page = self.paginate_queryset(queryset)
serializer = self.get_serializer(page, many=True)
message = status_message_response(
200,
'success',
'User File format is found',
serializer.data
)
return self.get_paginated_response(message)
@transaction.atomic
def create(self, request, **kwargs):
csv_file = request.FILES['file']
extension_file = str(csv_file).split('.')[1]
if extension_file.lower() != 'csv':
return Response(
{"message": "Only csv extension file is allowed"},
status=status.HTTP_400_BAD_REQUEST
)
df = pd.read_csv(csv_file, sep=',', skip_blank_lines=True).dropna()
# df.dropna()
logged_user_type = request.user.user_type
logged_user_company = request.user.department.company.name
logged_user_department = request.user.department.name
logged_user_email = request.user.email
email_users = []
department_error = 'Department should be same with the logged user'
company_error = 'Company should be same with the logged user'
etl = ExtractTransformLoad.objects.create(
file_name=str(csv_file),
model_type=enums.GenerateCode.USER.value
)
etl2 = ExtractTransformLoad.objects.get(id=etl.id)
enums_super = enums.UserTypeEnum.SUPER_USER.value
enums_OUA = enums.UserTypeEnum.OVERALL_USER_ADMIN.value
enums_company = enums.UserTypeEnum.COMPANY_USER_ADMIN.value
enums_department = enums.UserTypeEnum.DEPARTMENT_USER_ADMIN.value
enums_user = enums.UserTypeEnum.USER.value
for data, keys in df.iterrows():
try:
default_app = Application.objects.filter(
excel_code=keys['Default_app']
).first()
# user type authorization and user type per user
if request.user.user_type == enums_company:
user_company = request.user.department.company.code
request_department = Department.objects.filter(
Q(code=keys['Department_Code']) &
Q(company=user_company)
)
if not request_department:
# raise ParseError(company_error)
return Response(
{"message": company_error},
# {"message": str(e)},
status=status.HTTP_400_BAD_REQUEST
)
elif request.user.user_type == enums_department:
if keys['Department_Code'] != request.user.department.code:
return Response(
{"message": department_error},
# {"message": str(e)},
status=status.HTTP_400_BAD_REQUEST
)
# raise ParseError(
# department_error
# )
# user type authorization and user type per user
else:
user_department = Department.objects.filter(
name__icontains=keys['Department_Code']
)
default_app = Application.objects.filter(
excel_code=keys['Default_app']
).first()
dept_code = Department.objects.get(
code=keys['Department_Code']
)
users = {
"username": keys['Username'],
"name": keys['Name'],
"department": dept_code,
"email": keys['Email'],
"contact_no": keys['Contact_No'],
"default_app": default_app,
"user_type": enums_user
}
check_user = User.objects.filter(username=keys['Username'])
if not check_user:
current_user = User.objects.create(
**users
)
password = User.objects.make_random_password(length=10)
password_hash = make_password(password)
current_user.password = password_hash
current_user.save()
app = Application.objects.filter(
excel_code__in=keys['Application'].split(',')
)
current_user.application.set(app)
current_user = User.objects.get(id=current_user.id)
del users['department']
del users['contact_no']
del users['default_app']
del users['user_type']
users['file_name'] = etl2
users['password'] = password
# users['admin'] = logged_user_email
UserHistory.objects.create(
**users
)
elif check_user.count() > 0 and not check_user[0].date_joined.strftime('%Y-%m-%d') == datetime.now().strftime('%Y-%m-%d'):
# i insert it on database to make an integrity error it means this row is already exist
current_user = User.objects.create(
**users
)
else:
current_user = check_user[0]
try:
privilege_department_code = keys['Privilege_Department_Code']
privilege_department_code = Department.objects.get(
code=privilege_department_code
)
ccr = True if keys['Create_CR'] == 'Yes' else False
crt = True if keys['Create_Template'] == 'Yes' else False
view_all = True if keys['View_All_CR'] == 'Yes' else False
approve_cr = True if keys['Approve_CR'] == 'Yes' else False
privilege_object = {
"id_number": current_user,
"company_pivot": privilege_department_code.company,
"group_pivots": privilege_department_code,
"create_change_request": ccr,
"create_change_request_template": crt,
"view_all_change_request": view_all,
"approve_cr": approve_cr
}
AllowedCompany.objects.create(**privilege_object)
except IntegrityError as e:
return Response(
{"message": f"Duplicate user privilege at row {data + 2}"},
# {"message": str(e)},
status=status.HTTP_400_BAD_REQUEST
)
except ObjectDoesNotExist as e:
return Response(
{"message": f"Department Does not Exist at Privilege row {data + 2}"},
status=status.HTTP_400_BAD_REQUEST
)
except IntegrityError as e:
# etl2.delete()
# transaction.set_rollback(True)
return Response(
{"message": f"Record already exist at row {data + 2}"},
status=status.HTTP_400_BAD_REQUEST
)
except KeyError as e:
return Response(
{"message": f"Missing column {e.args[0]}"},
status=status.HTTP_400_BAD_REQUEST
)
except ObjectDoesNotExist as e:
return Response(
{"message": f"Department Does not Exist at row {data + 2}"},
status=status.HTTP_400_BAD_REQUEST
)
# except ValueError as e:
# return Response(
# {"message": f"Invalid department code. Please check at line {data + 2}"},
# status=status.HTTP_400_BAD_REQUEST
# )
send_mail = UserHistory.objects.filter(sent=False).values(
'name', 'username', 'email', 'password'
)
df = pd.DataFrame(send_mail)
df.to_csv("users.csv", index=False)
args = ["users.csv", logged_user_email]
main_threading(args, sender.batch_email_admin)
args = [send_mail, logged_user_email, etl.code]
main_threading(args, sender.batch_email_users)
return Response(
{"message": "File already uploaded"},
status=status.HTTP_201_CREATED
)
...@@ -88,7 +88,6 @@ class CompanyViewSet(viewsets.ModelViewSet): ...@@ -88,7 +88,6 @@ class CompanyViewSet(viewsets.ModelViewSet):
partial = kwargs.pop('partial', False) partial = kwargs.pop('partial', False)
instance = self.get_object() instance = self.get_object()
print(request.data)
serializer = self.get_serializer(instance, data=request.data, partial=partial) serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
......
from rest_framework import serializers
from app.entities.models import Delegation
class DelegationSerializer(serializers.ModelSerializer):
class Meta:
model = Delegation
fields = '__all__'
read_only_fields = (
'created', 'createdby', 'modified', 'modifiedby', 'code',
)
from django_filters import rest_framework as filters
from app.entities.models import Delegation
class DelegationFilterSet(filters.FilterSet):
class Meta:
model = Delegation
fields = '__all__'
from app.entities import enums
from django.db import transaction
from rest_framework import viewsets, status
from rest_framework.response import Response
from app.applicationlayer.utils import model_to_dict
from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters import rest_framework as filters
from app.entities.models import Delegation, Department
from app.applicationlayer.utils import (
CustomPagination, status_message_response, log_save
)
from django_filters.rest_framework import DjangoFilterBackend
from app.applicationlayer.management.delegation import serializer
from app.applicationlayer.management.delegation.table_filters import DelegationFilterSet
from app.helper import decorators
class DelegationViewSet(viewsets.ModelViewSet):
queryset = Delegation.objects.all().order_by('-created')
serializer_class = serializer.DelegationSerializer
pagination_class = CustomPagination
lookup_field = 'code'
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
filterset_class = DelegationFilterSet
ordering_fields = '__all__'
search_fields = ('name')
@transaction.atomic
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
message = status_message_response(
201, 'success',
'New Delegation created', serializer.data
)
return Response(
message
)
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
message = status_message_response(
200,
'success',
'list of Delegation found',
serializer.data
)
return self.get_paginated_response(message)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
@decorators.error_safe
@transaction.atomic
def destroy(self, request, *args, **kwargs):
message = {
'code': 400,
'status': 'failed',
'message': 'Delegation/s cannot delete, Please update instead'
}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
@transaction.atomic
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', True)
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)
if not (old_instance['name'].lower() == 'vendor/implementor' or
old_instance['name'].lower() == 'requestor'):
self.perform_update(serializer)
new_instance = serializer.data
log_save(
enums.LogEnum.UPDATE.value,
enums.LogEntitiesEnum.DELEGATION.value,
old_instance['id'],
old_instance,
new_instance
)
return Response(serializer.data)
else:
message = {
'code': 400,
'status': 'failed',
'message': 'Default delegation cannot edit'
}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
...@@ -16,7 +16,7 @@ class SubModuleField(serializers.Field): ...@@ -16,7 +16,7 @@ class SubModuleField(serializers.Field):
class ModuleSerializer(serializers.ModelSerializer): class ModuleSerializer(serializers.ModelSerializer):
sub_module = SubModuleField(source='*', read_only=True) sub_module = SubModuleField(source='*', read_only=True)
def to_representation(self, instance): def to_representation(self, instance):
application_name = Application.objects.filter( application_name = Application.objects.filter(
id=instance.application.id id=instance.application.id
......
...@@ -89,7 +89,6 @@ class NotificationsViewset(meviewsets.ModelViewSet): ...@@ -89,7 +89,6 @@ class NotificationsViewset(meviewsets.ModelViewSet):
def seen(self, request, account_no=None, **kwargs): def seen(self, request, account_no=None, **kwargs):
try: try:
account_no = self.kwargs['account_no'] account_no = self.kwargs['account_no']
print(account_no)
models.Notification.objects.filter(account_no=account_no, models.Notification.objects.filter(account_no=account_no,
id__in=request.data['ids']).update( id__in=request.data['ids']).update(
...@@ -117,8 +116,7 @@ class NotificationsViewset(meviewsets.ModelViewSet): ...@@ -117,8 +116,7 @@ class NotificationsViewset(meviewsets.ModelViewSet):
def seenall(self, request, account_no=None, **kwargs): def seenall(self, request, account_no=None, **kwargs):
try: try:
account_no = self.kwargs['account_no'] account_no = self.kwargs['account_no']
print(account_no)
models.Notification.objects.filter(account_no=account_no).update( models.Notification.objects.filter(account_no=account_no).update(
is_read=True, is_read=True,
modified=datetime.now()) modified=datetime.now())
......
...@@ -19,7 +19,6 @@ class UserManagementSerializer(serializers.ModelSerializer): ...@@ -19,7 +19,6 @@ class UserManagementSerializer(serializers.ModelSerializer):
primayPic = user.user_images.filter(is_primary=True).first() primayPic = user.user_images.filter(is_primary=True).first()
if primayPic: if primayPic:
print(primayPic.image.url)
return request.build_absolute_uri(primayPic.image.url) return request.build_absolute_uri(primayPic.image.url)
else: else:
return request.build_absolute_uri('/media/no-user.png') return request.build_absolute_uri('/media/no-user.png')
...@@ -106,7 +105,6 @@ class UserManagementRetreiveSerializer(serializers.ModelSerializer): ...@@ -106,7 +105,6 @@ class UserManagementRetreiveSerializer(serializers.ModelSerializer):
primayPic = user.user_images.filter(is_primary=True).first() primayPic = user.user_images.filter(is_primary=True).first()
if primayPic: if primayPic:
print(primayPic.image.url)
return request.build_absolute_uri(primayPic.image.url) return request.build_absolute_uri(primayPic.image.url)
else: else:
return request.build_absolute_uri('/media/no-user.png') return request.build_absolute_uri('/media/no-user.png')
......
...@@ -68,9 +68,7 @@ class UsersManagementViewSet(viewsets.ModelViewSet): ...@@ -68,9 +68,7 @@ class UsersManagementViewSet(viewsets.ModelViewSet):
@decorators.error_safe @decorators.error_safe
def list(self, request, *args, **kwargs): def list(self, request, *args, **kwargs):
print(request.data['department__name'])
self.serializer_class = serializers.UserManagementRetreiveSerializer self.serializer_class = serializers.UserManagementRetreiveSerializer
# self.queryset = QuerySetHelper.Sort(self)
return super(UsersManagementViewSet, self).list(request) return super(UsersManagementViewSet, self).list(request)
@decorators.error_safe @decorators.error_safe
...@@ -93,7 +91,7 @@ class UsersManagementViewSet(viewsets.ModelViewSet): ...@@ -93,7 +91,7 @@ class UsersManagementViewSet(viewsets.ModelViewSet):
createdUser = models.User.objects.filter(id=pk).first() createdUser = models.User.objects.filter(id=pk).first()
createdUser.set_password(settings.USER_DEFAULT_PASSWORD) createdUser.set_password(settings.USER_DEFAULT_PASSWORD)
createdUser.save() createdUser.save()
# LOG ADD # LOG ADD
log_save.log_save( log_save.log_save(
enums.LogEnum.ADD.value, enums.LogEnum.ADD.value,
......
...@@ -16,7 +16,8 @@ class AdminAccountSerializer(serializers.ModelSerializer): ...@@ -16,7 +16,8 @@ class AdminAccountSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = User model = User
fields = '__all__' # fields = '__all__'
read_only_fields = ( read_only_fields = (
'created', 'createdby', 'modified', 'modifiedby', 'code', 'created', 'createdby', 'modified', 'modifiedby', 'code',
) )
exclude = ('password',)
from rest_framework import serializers from rest_framework import serializers
from app.entities.models import Department from app.entities.models import Department, Delegation
from app.applicationlayer.utils import model_to_dict from app.applicationlayer.utils import model_to_dict
...@@ -16,3 +16,12 @@ class AdminDepartmentSerializer(serializers.ModelSerializer): ...@@ -16,3 +16,12 @@ class AdminDepartmentSerializer(serializers.ModelSerializer):
read_only_fields = ( read_only_fields = (
'created', 'createdby', 'modified', 'modifiedby', 'code', 'created', 'createdby', 'modified', 'modifiedby', 'code',
) )
class DelegationSerializer(serializers.ModelSerializer):
class Meta:
model = Delegation
fields = '__all__'
read_only_fields = (
'created', 'createdby', 'modified', 'modifiedby', 'code',
)
\ No newline at end of file
...@@ -3,20 +3,23 @@ from rest_framework.response import Response ...@@ -3,20 +3,23 @@ from rest_framework.response import Response
from app.applicationlayer.utils import model_to_dict from app.applicationlayer.utils import model_to_dict
from rest_framework.filters import SearchFilter, OrderingFilter from rest_framework.filters import SearchFilter, OrderingFilter
from django_filters import rest_framework as filters from django_filters import rest_framework as filters
from app.entities.models import Department from app.entities.models import Department, Delegation
from app.applicationlayer.utils import ( from app.applicationlayer.utils import (
CustomPagination, status_message_response CustomPagination, status_message_response
) )
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework import DjangoFilterBackend
from app.applicationlayer.master.department import serializer from app.applicationlayer.master.department.serializer import (
AdminDepartmentSerializer,
DelegationSerializer)
from app.applicationlayer.management.department.table_filters import DepartmentFilterSet from app.applicationlayer.management.department.table_filters import DepartmentFilterSet
from app.helper.decorators import rms from app.helper.decorators import rms
from rest_framework.decorators import action
class AdminDepartmentViewSet(viewsets.ModelViewSet): class AdminDepartmentViewSet(viewsets.ModelViewSet):
queryset = Department.objects.all().order_by('-created') queryset = Department.objects.all().order_by('-created')
serializer_class = serializer.AdminDepartmentSerializer serializer_class = AdminDepartmentSerializer
pagination_class = CustomPagination pagination_class = CustomPagination
lookup_field = 'code' lookup_field = 'code'
filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter) filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
...@@ -44,7 +47,6 @@ class AdminDepartmentViewSet(viewsets.ModelViewSet): ...@@ -44,7 +47,6 @@ class AdminDepartmentViewSet(viewsets.ModelViewSet):
) )
return self.get_paginated_response(message) return self.get_paginated_response(message)
except Exception as e: except Exception as e:
# serializer = self.get_serializer(queryset, many=True)
message = status_message_response( message = status_message_response(
400, 400,
'failed', 'failed',
...@@ -52,3 +54,34 @@ class AdminDepartmentViewSet(viewsets.ModelViewSet): ...@@ -52,3 +54,34 @@ class AdminDepartmentViewSet(viewsets.ModelViewSet):
'' ''
) )
return Response(message) return Response(message)
@action(detail=True,
methods=['get'],
url_path='delegations',
name="Delegation Filtered List")
def delegations(self, request, *args, **kwargs):
try:
dept_code = kwargs['code']
queryset = Delegation.objects.filter(departments__code=dept_code)
page = self.paginate_queryset(queryset)
if page is not None:
self.serializer_class = DelegationSerializer
serializer = self.get_serializer(page, many=True)
message = status_message_response(
200,
'success',
'list of filtered delegations found',
serializer.data
)
return self.get_paginated_response(message)
except Exception as e:
message = status_message_response(
400,
'failed',
str(e),
''
)
return Response(message)
\ No newline at end of file
...@@ -25,7 +25,7 @@ class UserTypeViewSet(APIView): ...@@ -25,7 +25,7 @@ class UserTypeViewSet(APIView):
"code": "200", "code": "200",
"status": "success", "status": "success",
"message": "list of user types", "message": "list of user types",
"results": "results":
# [ # [
{ {
enums_super_key : enums_super, enums_super_key : enums_super,
......
...@@ -7,8 +7,10 @@ from app.applicationlayer.management.company.views import CompanyViewSet ...@@ -7,8 +7,10 @@ from app.applicationlayer.management.company.views import CompanyViewSet
from app.applicationlayer.management.department.views import DepartmentViewSet from app.applicationlayer.management.department.views import DepartmentViewSet
from app.applicationlayer.management.module.views import ModuleViewSet from app.applicationlayer.management.module.views import ModuleViewSet
from app.applicationlayer.management.account.views import UserViewSet from app.applicationlayer.management.account.views import UserViewSet
from app.applicationlayer.management.batchupload.views import BatchUploadViewSet
from app.businesslayer.company.views import AdminCompanyViewSet from app.businesslayer.company.views import AdminCompanyViewSet
from app.applicationlayer.management.notification.views import NotificationsViewset from app.applicationlayer.management.notification.views import NotificationsViewset
from app.applicationlayer.management.delegation.views import DelegationViewSet
from app.applicationlayer.download.accounts.views import UserDownloadRequest from app.applicationlayer.download.accounts.views import UserDownloadRequest
from app.applicationlayer.download.department.views import DepartmentDownloadRequest from app.applicationlayer.download.department.views import DepartmentDownloadRequest
...@@ -26,6 +28,8 @@ router.register(r'notifications', NotificationsViewset) ...@@ -26,6 +28,8 @@ router.register(r'notifications', NotificationsViewset)
router.register(r'user-download', UserDownloadRequest) router.register(r'user-download', UserDownloadRequest)
router.register(r'department-download', DepartmentDownloadRequest) router.register(r'department-download', DepartmentDownloadRequest)
router.register(r'company-download', CompanyDownloadRequest) router.register(r'company-download', CompanyDownloadRequest)
router.register(r'delegations', DelegationViewSet)
router.register(r'extract-transform-load', BatchUploadViewSet)
urlpatterns = ( urlpatterns = (
path('', include(router.urls)), path('', include(router.urls)),
......
...@@ -20,7 +20,7 @@ REALTIMESERVER_IP = settings.REALTIMESERVER_IP ...@@ -20,7 +20,7 @@ REALTIMESERVER_IP = settings.REALTIMESERVER_IP
def model_to_dict(instance): def model_to_dict(instance):
try: try:
mySerializer = copy.deepcopy(DynamicSerializer) mySerializer = copy.deepcopy(DynamicSerializer)
mySerializer.Meta.model = instance.__class__ mySerializer.Meta.model = instance.__class__
return mySerializer(instance).data return mySerializer(instance).data
...@@ -54,6 +54,25 @@ class CustomPagination(PageNumberPagination): ...@@ -54,6 +54,25 @@ class CustomPagination(PageNumberPagination):
}) })
class PaginationForETL(PageNumberPagination):
page_size = 100
max_page_size = 3000
page_query_param = 'page'
page_size_query_param = 'page_size'
def get_paginated_response(self, data):
return Response({
'page_number': self.page.number,
'size_per_page': self.page.paginator.per_page,
'total_pages': self.page.paginator.num_pages,
'total': self.page.paginator.count,
'code': data['code'],
'status': data['status'],
'message': data['message'],
'results': data['results']
})
# def entitylogs_decorator(function): # def entitylogs_decorator(function):
# @wraps(function) # @wraps(function)
# def wrapper(self, request, *args, **kwargs): # def wrapper(self, request, *args, **kwargs):
...@@ -161,7 +180,8 @@ def send_broadcast_message(room_name, sender, message): ...@@ -161,7 +180,8 @@ def send_broadcast_message(room_name, sender, message):
ws.close() ws.close()
def notification_create(form_code, message, account_no, sender_account_no): def notification_create(form_code, message, account_no,
sender_account_no, app):
try: try:
...@@ -170,7 +190,7 @@ def notification_create(form_code, message, account_no, sender_account_no): ...@@ -170,7 +190,7 @@ def notification_create(form_code, message, account_no, sender_account_no):
notif_type='TASK', notif_type='TASK',
message=message, message=message,
is_read=False, is_read=False,
app='APP-20190909-0000002', app=app,
account_no=account_no, account_no=account_no,
sender_account_no=sender_account_no sender_account_no=sender_account_no
) )
...@@ -184,12 +204,6 @@ def notification_create(form_code, message, account_no, sender_account_no): ...@@ -184,12 +204,6 @@ def notification_create(form_code, message, account_no, sender_account_no):
'NEW NOTIFICATIONS' 'NEW NOTIFICATIONS'
) )
# message = {
# 'code': 200,
# 'status': 'success',
# 'message': 'Notification successfully created!',
# }
# return Response(message, status=status.HTTP_200_OK)
return True return True
except Exception as e: except Exception as e:
......
...@@ -13,14 +13,39 @@ from django.http import Http404 ...@@ -13,14 +13,39 @@ from django.http import Http404
from django.db.models import Q from django.db.models import Q
from app.applicationlayer.cms.utils_cr import ( from app.applicationlayer.cms.utils_cr import (
number_generator, crhistory_save, entity_log_bulk, number_generator,
crhistory_log_bulk_delete crhistory_save,
entity_log_bulk,
crhistory_log_bulk_delete,
crhistory_log_bulk_delete_masterattach,
send_mail_requestor,
next_approver_email,
send_mail_vendor,
crhistory_create_save,
reminder_trigger_save,
overdue_trigger_save,
reset_autoemail_tables,
cancelled_user_trigger,
send_mail_approver
) )
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
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
from django.db.models import Min from django.db.models import Min
from django.conf import settings
APPROVER_MESSAGE = settings.APPROVER_MESSAGE
REQUESTOR_MESSAGE = settings.REQUESTOR_MESSAGE
REQUESTOR_REJECT_MESSAGE = settings.REQUESTOR_REJECT_MESSAGE
VENDOR_ACKNOWLEDGE_MESSAGE = settings.VENDOR_ACKNOWLEDGE_MESSAGE
REQUESTOR_ACKNOWLEDGE_MESSAGE = settings.REQUESTOR_ACKNOWLEDGE_MESSAGE
REQUESTOR_COMPLETION_MESSAGE = settings.REQUESTOR_COMPLETION_MESSAGE
VENDOR_ACCEPTANCE_MESSAGE = settings.VENDOR_ACCEPTANCE_MESSAGE
VENDOR_REJECT_MESSAGE = settings.VENDOR_REJECT_MESSAGE
REVISED_MESSAGE = settings.REVISED_MESSAGE
CANCEL_MESSAGE = settings.CANCEL_MESSAGE
APPROVER_REJECT_MESSAGE = settings.APPROVER_REJECT_MESSAGE
def list_by_user(user_id_number): def list_by_user(user_id_number):
...@@ -341,14 +366,14 @@ def attachment_add_edit_delete(form_request_body, ...@@ -341,14 +366,14 @@ def attachment_add_edit_delete(form_request_body,
).exclude( ).exclude(
id__in=request_ids id__in=request_ids
) )
if delete_query.count() > 0: if delete_query.count() > 0:
crhistory_log_bulk_delete(delete_query, crhistory_log_bulk_delete_masterattach(delete_query,
entity, entity,
queryset, queryset,
form_code, form_code,
batch_no, batch_no,
main_action main_action
) )
# update or create # update or create
...@@ -388,15 +413,13 @@ def attachment_add_edit_delete(form_request_body, ...@@ -388,15 +413,13 @@ def attachment_add_edit_delete(form_request_body,
serializer = serializer_data(frm_instance, serializer = serializer_data(frm_instance,
data=data, data=data,
partial=partial, partial=partial,
context={"request":self.request}) context={"request": self.request})
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
self.perform_update(serializer) self.perform_update(serializer)
new_instance = serializer.data new_instance = serializer.data
#
# print(new_instance)
crhistory_save( crhistory_save(
batch_no, batch_no,
main_action, main_action,
...@@ -442,25 +465,322 @@ def check_vendor_level(position, routing_level, form_code): ...@@ -442,25 +465,322 @@ def check_vendor_level(position, routing_level, form_code):
query = models.ChangeRequestFormApprovers.objects.filter( query = models.ChangeRequestFormApprovers.objects.filter(
form_code=form_code, form_code=form_code,
level=int(routing_level), level=int(routing_level),
delegation='Vendor/Implementor' delegation__name='Vendor/Implementor'
) ).first()
return query
elif position == 'last': elif position == 'last':
query = models.ChangeRequestFormApprovers.objects.filter( query = models.ChangeRequestFormApprovers.objects.filter(
form_code=form_code, form_code=form_code,
delegation='Vendor/Implementor' delegation__name='Vendor/Implementor'
).order_by('level').last() ).order_by('level').last()
return query
elif position == 'prev': elif position == 'prev':
query = models.ChangeRequestFormApprovers.objects.filter( query = models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) & Q(form_code=form_code) &
Q(action='Completed') & Q(action='Completed') &
Q(delegation='Vendor/Implementor') & Q(delegation__name='Vendor/Implementor') &
Q(level__lte=int(level)) Q(level__lte=int(routing_level))
)
return query
def update_form_approver(form_code, level, apprv_type, date_now):
if apprv_type == 'next':
# update next approver details
models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) & Q(level=int(level))
).update(
date_sent=date_now,
is_action=True
)
elif apprv_type == 'current':
# update current approver details
models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) & Q(level=int(level))
).update(
is_action=False
)
def update_form_header_status(form_code, status):
models.ChangeRequestFormHeader.objects.filter(
form_code=form_code
).update(status=status)
return True
def cr_routing_actions(approver_instance, current_user, move_to_level):
form_code = approver_instance['form_code']
delegation = approver_instance['delegation']['name']
action = approver_instance['action'].lower()
level = approver_instance['level']
next_level = int(approver_instance['level']) + 1
remarks = approver_instance['remarks']
if approver_instance['action'].lower() == 'approved':
the_next_vendor = check_vendor_level(
'next', next_level, form_code)
if the_next_vendor:
the_last_vendor = check_vendor_level(
'last', level, form_code)
# changed form status to Approved
if the_next_vendor == the_last_vendor:
update_form_header_status(form_code, 'Approved')
# NOTIF MSG FOR REQUESTOR
requestor_notification_msg = REQUESTOR_MESSAGE.split(';')[0]
# SEND EMAIL AND NOTIF TO REQUESTOR
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action,
remarks, level
)
next_approver_email(form_code, next_level)
date_now = datetime.now()
# update next approver details
update_form_approver(form_code, next_level, 'next', date_now)
# update current approver details
update_form_approver(form_code, level, 'current', date_now)
#save details for reminder trigger
reminder_trigger_save(form_code, date_now, date_now)
elif approver_instance['action'].lower() == 'rejected':
# reject from requestor action
if delegation.lower() == 'requestor':
notification_msg = REVISED_MESSAGE.split(';')[0]
# send reject email to vendor
send_mail_vendor(
current_user, form_code, delegation,
notification_msg, action,
remarks, level
)
prev_level = int(level) - 1
# reset last vendor details
models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) &
Q(level=int(prev_level))
).update(
is_action=True,
action='Acknowledged',
action_date=datetime.now(),
date_sent=datetime.now()
)
else:
back_to_approver = models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) &
Q(level=move_to_level) &
(~Q(action=None) | Q(delegation__name='Requestor'))
).first()
if back_to_approver.delegation.name.lower() == 'requestor':
requestor_notification_msg = REQUESTOR_REJECT_MESSAGE.split(';')[0]
# SEND EMAIL AND NOTIF TO REQUESTOR
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action,
remarks, level
) )
# def cr_routing_actions(approver_instance): update_form_header_status(form_code, 'Rejected')
elif back_to_approver.delegation.name.lower() == 'vendor/implementor':
vendor_notification_msg = REVISED_MESSAGE.split(';')[0]
# send reject email to vendor
send_mail_vendor(
current_user, form_code, delegation,
vendor_notification_msg, action,
remarks, level
)
requestor_notification_msg = REQUESTOR_REJECT_MESSAGE.split(';')[0]
# SEND EMAIL AND NOTIF TO REQUESTOR
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action,
remarks, level
)
# reset selected vendor details
models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) &
Q(level=int(move_to_level))
).update(
is_action=True,
action='Acknowledged',
action_date=datetime.now(),
date_sent=datetime.now()
)
else:
approver_code = back_to_approver.user.code
approver_notification_msg = APPROVER_REJECT_MESSAGE.split(';')[0]
send_mail_approver(
current_user, form_code, delegation,
approver_notification_msg, action, remarks,
level, approver_code
)
requestor_notification_msg = REQUESTOR_REJECT_MESSAGE.split(';')[0]
# SEND EMAIL AND NOTIF TO REQUESTOR
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action,
remarks, level
)
# reset selected vendor details
models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) &
Q(level=int(move_to_level))
).update(
is_action=True,
action=None,
action_date=None,
date_sent=datetime.now()
)
models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=form_code) & Q(level__gt=int(move_to_level))
).update(
is_action=False,
action=None,
remarks=None,
action_date=None,
date_sent=None
)
elif approver_instance['action'].lower() == 'completed':
the_last_vendor = check_vendor_level(
'last', level, form_code)
if (the_last_vendor and current_user == the_last_vendor.user.code and
level == the_last_vendor.level):
update_form_header_status(form_code, 'Approved')
else:
the_next_vendor = check_vendor_level(
'next', next_level, form_code)
if the_next_vendor:
if the_next_vendor.user.code == the_last_vendor.user.code:
update_form_header_status(form_code, 'Approved')
else:
update_form_header_status(form_code, 'Pending')
next_approver_email(form_code, next_level)
date_now = datetime.now()
# update next approver details
update_form_approver(form_code, next_level, 'next', date_now)
# update current approver details
update_form_approver(form_code, level, 'current', date_now)
# EMAIL CODE FOR REQUESTOR
requestor_notification_msg = REQUESTOR_COMPLETION_MESSAGE.split(';')[0]
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action,
remarks, level
)
elif action.lower() == 'acknowledged':
# EMAIL CODE FOR REQUESTOR
requestor_notification_msg = REQUESTOR_ACKNOWLEDGE_MESSAGE.split(';')[0]
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action,
remarks, level
)
elif action.lower() == 'accepted':
update_form_header_status(form_code, 'Completed & Accepted')
# EMAIL CODE FOR VENDOR
requestor_notification_msg = VENDOR_ACCEPTANCE_MESSAGE.split(';')[0]
send_mail_vendor(
current_user, form_code, delegation,
requestor_notification_msg, action,
remarks, level
)
date_now = datetime.now()
# update current approver details
update_form_approver(form_code, level, 'current', date_now)
elif action.lower() == 'cancelled':
# send email and notif to anyone who received an email about the change request
cancelled_user_trigger(form_code, action, level)
# changed form status to cancelled
update_form_header_status(form_code, 'Cancelled')
date_now = datetime.now()
# update is_action for current level
update_form_approver(form_code, level, 'current', date_now)
reset_autoemail_tables(form_code)
return True
...@@ -8,4 +8,4 @@ class AdminDepartmentSerializer(serializers.ModelSerializer): ...@@ -8,4 +8,4 @@ class AdminDepartmentSerializer(serializers.ModelSerializer):
fields = '__all__' fields = '__all__'
read_only_fields = ( read_only_fields = (
'created', 'createdby', 'modified', 'modifiedby', 'code', 'created', 'createdby', 'modified', 'modifiedby', 'code',
) )
\ No newline at end of file
...@@ -41,4 +41,4 @@ class AdminDepartmentViewSet(viewsets.ModelViewSet): ...@@ -41,4 +41,4 @@ class AdminDepartmentViewSet(viewsets.ModelViewSet):
return self.get_paginated_response(message) return self.get_paginated_response(message)
serializer = self.get_serializer(queryset, many=True) serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data) return Response(serializer.data)
\ No newline at end of file
...@@ -11,11 +11,11 @@ class UserTypeViewSet(APIView): ...@@ -11,11 +11,11 @@ class UserTypeViewSet(APIView):
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
data = { data = {
'Super user': enums_super, 'Super user': enums_super,
'Overall user admin': enums_OUA, 'Overall user admin': enums_OUA,
"Company user admin": enums_company, "Company user admin": enums_company,
"Department user admin": enums_department, "Department user admin": enums_department,
"user": enums_user "user": enums_user
} }
......
...@@ -29,6 +29,7 @@ class GenerateCode(Enum): ...@@ -29,6 +29,7 @@ class GenerateCode(Enum):
COMPANY = 'COMPANY' COMPANY = 'COMPANY'
DEPARTMENT = 'DEPARTMENT' DEPARTMENT = 'DEPARTMENT'
USER = 'USER' USER = 'USER'
DELEGATION = 'DELEGATION'
NOTIFICATION = 'NOTIF' NOTIFICATION = 'NOTIF'
TEMPLATE = 'TMP' TEMPLATE = 'TMP'
TMP_APPROVER = 'TMPAPR' TMP_APPROVER = 'TMPAPR'
...@@ -40,6 +41,7 @@ class GenerateCode(Enum): ...@@ -40,6 +41,7 @@ class GenerateCode(Enum):
FORM_STAKE = 'FRMSTK' FORM_STAKE = 'FRMSTK'
FORM_ATTACH = 'FRMATCH' FORM_ATTACH = 'FRMATCH'
FORM_DETAIL = 'FRMDETAIL' FORM_DETAIL = 'FRMDETAIL'
ETL = 'ETL'
ASSET_GROUP = 'AMSGRP' ASSET_GROUP = 'AMSGRP'
...@@ -62,6 +64,7 @@ class LogEntitiesEnum(Enum): ...@@ -62,6 +64,7 @@ class LogEntitiesEnum(Enum):
COMPANY = "COMPANY" COMPANY = "COMPANY"
DEPARTMENT = "DEPARTMENT" DEPARTMENT = "DEPARTMENT"
MODULE = "MODULE" MODULE = "MODULE"
DELEGATION = "DELEGATION"
ChangeRequestTemplateHeader = "ChangeRequestTemplateHeader" ChangeRequestTemplateHeader = "ChangeRequestTemplateHeader"
ChangeRequestTemplateApprovers = "ChangeRequestTemplateApprovers" ChangeRequestTemplateApprovers = "ChangeRequestTemplateApprovers"
ChangeRequestTemplateStakeHolders = "ChangeRequestTemplateStakeHolders" ChangeRequestTemplateStakeHolders = "ChangeRequestTemplateStakeHolders"
......
# Generated by Django 2.2 on 2019-11-08 14:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entities', '0027_assetgroup'),
]
operations = [
migrations.AddField(
model_name='application',
name='excel_code',
field=models.CharField(default='rms', max_length=255),
preserve_default=False,
),
]
# Generated by Django 2.2 on 2019-10-29 15:13
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('entities', '0027_assetgroup'),
]
operations = [
migrations.AddField(
model_name='canceltrigger',
name='cancel_type',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name='remindertrigger',
name='form_code',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='entities.ChangeRequestFormHeader', to_field='form_code'),
),
migrations.AlterField(
model_name='canceltrigger',
name='frm_approver',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='entities.ChangeRequestFormApprovers', to_field='code'),
),
]
# Generated by Django 2.2 on 2019-11-04 12:28
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('entities', '0028_auto_20191029_1513'),
]
operations = [
migrations.AlterModelTable(
name='canceltrigger',
table='trigger_cancel',
),
migrations.AlterModelTable(
name='overduetrigger',
table='trigger_overdue',
),
migrations.AlterModelTable(
name='remindertrigger',
table='trigger_reminder',
),
]
# Generated by Django 2.2 on 2019-11-08 15:04
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entities', '0028_application_excel_code'),
]
operations = [
migrations.CreateModel(
name='UserHistory',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(auto_now_add=True)),
('createdby', models.CharField(max_length=255)),
('modified', models.DateTimeField(auto_now=True)),
('modifiedby', models.CharField(max_length=255)),
('name', models.CharField(max_length=255)),
('username', models.CharField(max_length=255, unique=True)),
('email', models.EmailField(max_length=255)),
('password', models.CharField(max_length=255)),
('sent', models.BooleanField(default=False)),
],
options={
'db_table': 'user_history',
},
),
]
# Generated by Django 2.2 on 2019-11-04 15:07
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('entities', '0029_auto_20191104_1228'),
]
operations = [
migrations.AlterModelOptions(
name='assetgroup',
options={'ordering': ['-created']},
),
]
# Generated by Django 2.2 on 2019-11-07 12:39
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('entities', '0030_auto_20191104_1507'),
]
operations = [
migrations.CreateModel(
name='Delegation',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(auto_now_add=True)),
('createdby', models.CharField(max_length=255)),
('modified', models.DateTimeField(auto_now=True)),
('modifiedby', models.CharField(max_length=255)),
('code', models.CharField(max_length=255, unique=True)),
('name', models.CharField(max_length=255, unique=True)),
],
options={
'db_table': 'delegations',
},
),
migrations.AlterField(
model_name='changerequestformapprovers',
name='delegation',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='entities.Delegation', to_field='code'),
),
migrations.AlterField(
model_name='changerequesttemplateapprovers',
name='delegation',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='entities.Delegation', to_field='code'),
),
migrations.AddField(
model_name='department',
name='delegation',
field=models.ManyToManyField(to='entities.Delegation'),
),
]
# Generated by Django 2.2 on 2019-11-08 11:09
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entities', '0031_auto_20191107_1239'),
]
operations = [
migrations.AddField(
model_name='allowedcompany',
name='approve_cr',
field=models.BooleanField(default=True),
),
migrations.AlterField(
model_name='entitylog',
name='entity',
field=models.CharField(choices=[('USER', 'USER'), ('APPLICATION', 'APPLICATION'), ('COMPANY', 'COMPANY'), ('DEPARTMENT', 'DEPARTMENT'), ('MODULE', 'MODULE'), ('DELEGATION', 'DELEGATION'), ('ChangeRequestTemplateHeader', 'ChangeRequestTemplateHeader'), ('ChangeRequestTemplateApprovers', 'ChangeRequestTemplateApprovers'), ('ChangeRequestTemplateStakeHolders', 'ChangeRequestTemplateStakeHolders'), ('ChangeRequestTemplateAttachments', 'ChangeRequestTemplateAttachments'), ('ChangeRequestTemplateDetails', 'ChangeRequestTemplateDetails'), ('ChangeRequestFormHeader', 'ChangeRequestFormHeader'), ('ChangeRequestFormApprovers', 'ChangeRequestFormApprovers'), ('ChangeRequestFormStakeHolders', 'ChangeRequestFormStakeHolders'), ('ChangeRequestFormAttachments', 'ChangeRequestFormAttachments'), ('ChangeRequestFormDetails', 'ChangeRequestFormDetails')], default='Add', max_length=50),
),
]
# Generated by Django 2.2 on 2019-11-08 17:25
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('entities', '0032_auto_20191108_1109'),
('entities', '0029_userhistory'),
]
operations = [
]
# Generated by Django 2.2 on 2019-11-08 19:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entities', '0033_merge_20191108_1725'),
]
operations = [
migrations.AlterField(
model_name='allowedcompany',
name='approve_cr',
field=models.BooleanField(default=False),
),
]
# Generated by Django 2.2 on 2019-11-11 10:42
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entities', '0034_auto_20191108_1924'),
]
operations = [
migrations.AddField(
model_name='changerequesttemplateapprovers',
name='is_default',
field=models.BooleanField(default=False),
),
]
# Generated by Django 2.2 on 2019-11-11 15:49
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entities', '0035_changerequesttemplateapprovers_is_default'),
]
operations = [
migrations.AlterField(
model_name='department',
name='delegation',
field=models.ManyToManyField(related_name='departments', to='entities.Delegation'),
),
]
# Generated by Django 2.2 on 2019-11-12 14:03
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('entities', '0036_auto_20191111_1549'),
]
operations = [
migrations.AlterField(
model_name='changerequestformapprovers',
name='delegation',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='entities.Delegation', to_field='code'),
),
migrations.AlterField(
model_name='changerequesttemplateapprovers',
name='delegation',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='entities.Delegation', to_field='code'),
),
]
# Generated by Django 2.2 on 2019-11-12 14:57
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('entities', '0037_auto_20191112_1403'),
]
operations = [
migrations.AlterField(
model_name='changerequestformapprovers',
name='delegation',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='entities.Delegation', to_field='code'),
),
migrations.AlterField(
model_name='changerequesttemplateapprovers',
name='delegation',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='entities.Delegation', to_field='code'),
),
]
# Generated by Django 2.2 on 2019-11-13 10:16
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('entities', '0038_auto_20191112_1457'),
]
operations = [
migrations.CreateModel(
name='ExtractTransformLoad',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(auto_now_add=True)),
('createdby', models.CharField(max_length=255)),
('modified', models.DateTimeField(auto_now=True)),
('modifiedby', models.CharField(max_length=255)),
('file_name', models.CharField(max_length=255)),
('model_type', models.CharField(choices=[('APP', 'APP'), ('MODULE', 'MODULE'), ('COMPANY', 'COMPANY'), ('DEPARTMENT', 'DEPARTMENT'), ('USER', 'USER'), ('DELEGATION', 'DELEGATION'), ('NOTIF', 'NOTIF'), ('TMP', 'TMP'), ('TMPAPR', 'TMPAPR'), ('TMPSTK', 'TMPSTK'), ('TMPATCH', 'TMPATCH'), ('TMPDETAIL', 'TMPDETAIL'), ('FRM', 'FRM'), ('FRMAPR', 'FRMAPR'), ('FRMSTK', 'FRMSTK'), ('FRMATCH', 'FRMATCH'), ('FRMDETAIL', 'FRMDETAIL'), ('ETL', 'ETL'), ('AMSGRP', 'AMSGRP')], default='USER', max_length=100)),
('code', models.CharField(blank=True, max_length=255, null=True, unique=True)),
],
options={
'db_table': 'csv_filenames',
},
),
migrations.AddField(
model_name='userhistory',
name='file_name',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='extract_transform_load', to='entities.ExtractTransformLoad', to_field='code'),
),
]
# Generated by Django 2.2 on 2019-11-13 15:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entities', '0039_auto_20191113_1016'),
]
operations = [
migrations.AddField(
model_name='userhistory',
name='deleted',
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name='userhistory',
name='username',
field=models.CharField(max_length=255),
),
]
# Generated by Django 2.2 on 2019-11-13 19:23
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('entities', '0040_auto_20191113_1505'),
]
operations = [
migrations.AlterModelTable(
name='extracttransformload',
table='extract_transform_load',
),
migrations.AlterModelTable(
name='userhistory',
table='extract_transform_load_user_history',
),
]
...@@ -32,7 +32,6 @@ class BaseAuditClass(models.Model): ...@@ -32,7 +32,6 @@ class BaseAuditClass(models.Model):
modifiedby = models.CharField(max_length=255) modifiedby = models.CharField(max_length=255)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
# print('333')
if self.createdby and self.modifiedby: if self.createdby and self.modifiedby:
# username = 'Anonymous User' # username = 'Anonymous User'
# self.createdby = username # self.createdby = username
......
...@@ -8,6 +8,9 @@ from datetime import datetime ...@@ -8,6 +8,9 @@ from datetime import datetime
from . import enums from . import enums
from django.utils.text import slugify from django.utils.text import slugify
from datetime import timedelta from datetime import timedelta
import os
from django.conf import settings
# ********************* AUTH TABLES ********************* # ********************* AUTH TABLES *********************
...@@ -27,6 +30,7 @@ class Application(AuditClass): ...@@ -27,6 +30,7 @@ class Application(AuditClass):
max_length=255 max_length=255
) )
name = models.CharField(unique=True, max_length=255) name = models.CharField(unique=True, max_length=255)
excel_code = models.CharField(max_length=255)
class Meta: class Meta:
db_table = 'applications' db_table = 'applications'
...@@ -85,6 +89,29 @@ class Module(AuditClass): ...@@ -85,6 +89,29 @@ class Module(AuditClass):
Module.objects.filter(id=self.id).update(code=code) Module.objects.filter(id=self.id).update(code=code)
class Delegation(AuditClass):
code = models.CharField(
unique=True,
max_length=255
)
name = models.CharField(unique=True, max_length=255)
class Meta:
db_table = 'delegations'
def __str__(self):
return f'{self.name}'
def save(self, *args, **kwargs):
super(Delegation, self).save(*args, **kwargs)
code = number_generator(enums.GenerateCode.DELEGATION.value, self.id)
if self.code == '':
self.code = code
self.created = datetime.now()
self.save()
class Company(AuditClass): class Company(AuditClass):
code = models.CharField( code = models.CharField(
unique=True, unique=True,
...@@ -103,7 +130,6 @@ class Company(AuditClass): ...@@ -103,7 +130,6 @@ class Company(AuditClass):
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
super(Company, self).save(*args, **kwargs) super(Company, self).save(*args, **kwargs)
if self.code == 'com': if self.code == 'com':
print(self.code)
code = enums.GenerateCode.APP.value code = enums.GenerateCode.APP.value
code = number_generator(enums.GenerateCode.COMPANY.value, self.id) code = number_generator(enums.GenerateCode.COMPANY.value, self.id)
Company.objects.filter(id=self.id).update(code=code) Company.objects.filter(id=self.id).update(code=code)
...@@ -128,6 +154,10 @@ class Department(AuditClass): ...@@ -128,6 +154,10 @@ class Department(AuditClass):
default='dept' default='dept'
) )
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
delegation = models.ManyToManyField(
Delegation,
related_name='departments'
)
class Meta: class Meta:
db_table = 'departments' db_table = 'departments'
...@@ -211,6 +241,57 @@ class RolePermission(AuditClass): ...@@ -211,6 +241,57 @@ class RolePermission(AuditClass):
class Meta: class Meta:
db_table = 'role_permissions' db_table = 'role_permissions'
class ExtractTransformLoad(AuditClass):
file_name = models.CharField(max_length=255)
model_type = models.CharField(
choices=[(tag.value, tag.value) for tag in enums.GenerateCode],
default=enums.GenerateCode.USER.value,
max_length=100
)
code = models.CharField(
unique=True,
max_length=255,
blank=True,
null=True
)
class Meta:
db_table = 'extract_transform_load'
def __str__(self):
return f'{self.file_name}'
def save(self, *args, **kwargs):
super(ExtractTransformLoad, self).save(*args, **kwargs)
code = number_generator(enums.GenerateCode.ETL.value, self.id)
print(type(self.code))
if self.code == '' or self.code == None:
self.code = code
self.save()
class UserHistory(AuditClass):
file_name = models.ForeignKey(
ExtractTransformLoad,
to_field='code',
related_name='extract_transform_load',
on_delete=models.DO_NOTHING,
blank=True,
null=True
)
name = models.CharField(max_length=255)
username = models.CharField(max_length=255)
email = models.EmailField(max_length=255, unique=False)
password = models.CharField(max_length=255)
sent = models.BooleanField(default=False)
deleted = models.BooleanField(default=False)
class Meta:
db_table = 'extract_transform_load_user_history'
class User(AbstractUser): class User(AbstractUser):
...@@ -372,33 +453,25 @@ class BaseHeader(models.Model): ...@@ -372,33 +453,25 @@ class BaseHeader(models.Model):
Company, Company,
on_delete=models.PROTECT, on_delete=models.PROTECT,
to_field='code') to_field='code')
requested_to_department = models.ForeignKey( requested_to_department = models.ForeignKey(
Department, Department,
on_delete=models.PROTECT, on_delete=models.PROTECT,
to_field='code') to_field='code')
requested_to_user = models.ForeignKey( requested_to_user = models.ForeignKey(
User, User,
on_delete=models.PROTECT, on_delete=models.PROTECT,
to_field='code') to_field='code')
requested_to_template_name = models.CharField(max_length=255) requested_to_template_name = models.CharField(max_length=255)
requested_to_objective = models.CharField( requested_to_objective = models.CharField(
max_length=255, max_length=255,
blank=True, blank=True,
null=True) null=True)
requested_to_priority = models.CharField(max_length=255) requested_to_priority = models.CharField(max_length=255)
description = models.CharField( description = models.CharField(
max_length=255, max_length=255,
blank=True, blank=True,
null=True) null=True)
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True) is_active = models.BooleanField(default=True)
class Meta: class Meta:
...@@ -407,15 +480,18 @@ class BaseHeader(models.Model): ...@@ -407,15 +480,18 @@ class BaseHeader(models.Model):
class BaseApprover(models.Model): class BaseApprover(models.Model):
level = models.IntegerField() level = models.IntegerField()
user = models.ForeignKey( user = models.ForeignKey(
User, User,
blank=True, blank=True,
null=True, null=True,
on_delete=models.PROTECT, on_delete=models.PROTECT,
to_field='code') to_field='code')
delegation = models.ForeignKey(
delegation = models.CharField(max_length=50, blank=True, null=True) Delegation,
blank=True,
null=True,
on_delete=models.CASCADE,
to_field='code')
created = models.DateTimeField( created = models.DateTimeField(
blank=True, blank=True,
null=True) null=True)
...@@ -449,15 +525,29 @@ class MasterAttachment(models.Model): ...@@ -449,15 +525,29 @@ class MasterAttachment(models.Model):
blank=True, blank=True,
null=True) null=True)
attch_ref = models.TextField() attch_ref = models.TextField()
def delete(self,*args,**kwargs):
print(self.url.name)
if os.path.isfile(self.url.path):
os.remove(self.url.path)
super(MasterAttachment, self).delete(*args,**kwargs)
class Meta: class Meta:
db_table = 'master_attachments' db_table = 'master_attachments'
def delete(self, *args, **kwargs):
# self.url.delete()
# super().delete(*args, **kwargs)
os.remove(os.path.join(settings.MEDIA_ROOT, self.url.name))
super(MasterAttachment, self).delete(*args, **kwargs)
class BaseAttachment(models.Model): class BaseAttachment(models.Model):
attachment_type = models.CharField(max_length=255) attachment_type = models.CharField(max_length=255)
attachment_name = models.CharField(max_length=255) attachment_name = models.CharField(max_length=255)
file_name = models.CharField( file_name = models.CharField(
max_length=255, max_length=255,
blank=True, blank=True,
...@@ -494,7 +584,6 @@ class BaseDetails(models.Model): ...@@ -494,7 +584,6 @@ class BaseDetails(models.Model):
blank=True, blank=True,
null=True null=True
) )
created = models.DateTimeField( created = models.DateTimeField(
blank=True, blank=True,
null=True) null=True)
...@@ -513,23 +602,19 @@ class ChangeRequestTemplateHeader(BaseHeader): ...@@ -513,23 +602,19 @@ class ChangeRequestTemplateHeader(BaseHeader):
template_no = models.CharField( template_no = models.CharField(
unique=True, unique=True,
max_length=255) max_length=255)
requested_to_template_id = models.CharField( requested_to_template_id = models.CharField(
max_length=255, max_length=255,
unique=True) unique=True)
created_by_user = models.ForeignKey( created_by_user = models.ForeignKey(
User, User,
on_delete=models.PROTECT, on_delete=models.PROTECT,
to_field='code', to_field='code',
related_name='created_by_user') related_name='created_by_user')
created_by_department = models.ForeignKey( created_by_department = models.ForeignKey(
Department, Department,
on_delete=models.PROTECT, on_delete=models.PROTECT,
to_field='code', to_field='code',
related_name='created_by_department') related_name='created_by_department')
requested_to_target_date = models.IntegerField() requested_to_target_date = models.IntegerField()
class Meta: class Meta:
...@@ -569,6 +654,9 @@ class ChangeRequestTemplateApprovers(BaseApprover): ...@@ -569,6 +654,9 @@ class ChangeRequestTemplateApprovers(BaseApprover):
null=True, null=True,
on_delete=models.PROTECT, on_delete=models.PROTECT,
to_field='code') to_field='code')
is_default = models.BooleanField(
default=False
)
class Meta: class Meta:
db_table = 'change_request_template_approvers' db_table = 'change_request_template_approvers'
...@@ -699,7 +787,6 @@ class ChangeRequestFormHeader(BaseHeader): ...@@ -699,7 +787,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( company_desc = models.CharField(
max_length=255, max_length=255,
null=True, null=True,
...@@ -821,7 +908,7 @@ class ChangeRequestFormStakeHolders(BaseStakeholder): ...@@ -821,7 +908,7 @@ class ChangeRequestFormStakeHolders(BaseStakeholder):
date_added = models.DateTimeField( date_added = models.DateTimeField(
blank=True, blank=True,
null=True) null=True)
class Meta: class Meta:
db_table = 'change_request_form_stakeholders' db_table = 'change_request_form_stakeholders'
...@@ -1022,9 +1109,10 @@ class AllowedCompany(models.Model): ...@@ -1022,9 +1109,10 @@ class AllowedCompany(models.Model):
create_change_request = models.BooleanField(default=True) create_change_request = models.BooleanField(default=True)
create_change_request_template = models.BooleanField(default=True) create_change_request_template = models.BooleanField(default=True)
view_all_change_request = models.BooleanField(default=True) view_all_change_request = models.BooleanField(default=True)
approve_cr = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
deleted_at = models.DateTimeField(null=True, blank=True) deleted_at = models.DateTimeField(null=True, blank=True)
class Meta: class Meta:
db_table = 'allowed_company' db_table = 'allowed_company'
unique_together = ['company_pivot', 'group_pivots', 'id_number'] unique_together = ['company_pivot', 'group_pivots', 'id_number']
...@@ -1052,9 +1140,15 @@ class ReminderTrigger(models.Model): ...@@ -1052,9 +1140,15 @@ class ReminderTrigger(models.Model):
blank=True) blank=True)
is_sent = models.BooleanField( is_sent = models.BooleanField(
default=False) default=False)
form_code = models.ForeignKey(
ChangeRequestFormHeader,
on_delete=models.PROTECT,
to_field='form_code',
null=True,
blank=True)
class Meta: class Meta:
db_table = 'reminder_trigger' db_table = 'trigger_reminder'
class CancelTrigger(models.Model): class CancelTrigger(models.Model):
...@@ -1065,7 +1159,9 @@ class CancelTrigger(models.Model): ...@@ -1065,7 +1159,9 @@ class CancelTrigger(models.Model):
frm_approver = models.ForeignKey( frm_approver = models.ForeignKey(
ChangeRequestFormApprovers, ChangeRequestFormApprovers,
on_delete=models.PROTECT, on_delete=models.PROTECT,
to_field='code') to_field='code',
blank=True,
null=True)
auto_cancel_date = models.DateTimeField( auto_cancel_date = models.DateTimeField(
null=True, null=True,
blank=True) blank=True)
...@@ -1074,9 +1170,13 @@ class CancelTrigger(models.Model): ...@@ -1074,9 +1170,13 @@ class CancelTrigger(models.Model):
date_submitted_last_approver = models.DateTimeField( date_submitted_last_approver = models.DateTimeField(
null=True, null=True,
blank=True) blank=True)
cancel_type = models.CharField(
null=True,
blank=True,
max_length=255)
class Meta: class Meta:
db_table = 'cancel_trigger' db_table = 'trigger_cancel'
class OverdueTrigger(models.Model): class OverdueTrigger(models.Model):
...@@ -1091,7 +1191,7 @@ class OverdueTrigger(models.Model): ...@@ -1091,7 +1191,7 @@ class OverdueTrigger(models.Model):
default=False) default=False)
class Meta: class Meta:
db_table = 'overdue_trigger' db_table = 'trigger_overdue'
""" """
...@@ -1116,6 +1216,7 @@ class AssetGroup(models.Model): ...@@ -1116,6 +1216,7 @@ class AssetGroup(models.Model):
class Meta: class Meta:
db_table = 'asset_groups' db_table = 'asset_groups'
ordering = ['-created']
def __str__(self): def __str__(self):
return f'{self.code}' return f'{self.code}'
......
...@@ -13,7 +13,7 @@ def error_safe(function): ...@@ -13,7 +13,7 @@ def error_safe(function):
def wrap(request, *args, **kwargs): def wrap(request, *args, **kwargs):
stat = status.HTTP_500_INTERNAL_SERVER_ERROR stat = status.HTTP_500_INTERNAL_SERVER_ERROR
try: try:
return function(request, *args, **kwargs) return function(request, *args, **kwargs)
# except 'DoesNotExist' as ex: # except 'DoesNotExist' as ex:
# print('ddd') # print('ddd')
# stat = status.HTTP_404_NOT_FOUND # stat = status.HTTP_404_NOT_FOUND
...@@ -145,7 +145,8 @@ class rms: ...@@ -145,7 +145,8 @@ class rms:
@wraps(function) @wraps(function)
def wrapper(self, request, *args, **kwargs): def wrapper(self, request, *args, **kwargs):
if rms.user_type(self) == rms.enums_company: if rms.user_type(self) == rms.enums_company or rms.user_type(self) == rms.enums_department:
id = rms.user(self).department.company.id id = rms.user(self).department.company.id
self.queryset = self.queryset.filter( self.queryset = self.queryset.filter(
......
import os import os
from django.core.mail import send_mail from django.core.mail import send_mail, EmailMessage
from app.entities import models from app.entities import models
from django.conf import settings from django.conf import settings
from django.core import mail as email_connection
from django.db import transaction
# from weasyprint import HTML
from io import BytesIO
from django.http import HttpResponse
from django.template.loader import get_template
from xhtml2pdf import pisa
from email.mime.text import MIMEText
def to_pdf():
F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, 'RMS-NEWUSER.html'), 'r')
result = BytesIO()
pdf = pisa.pisaDocument(F, result)
if not pdf.err:
return HttpResponse(result.getvalue(), content_type='application/pdf')
return None
@transaction.atomic
def batch_email_users(args):
connection = email_connection.get_connection()
messages = []
connection.open()
for data in args[0].iterator():
name = data['name']
username = data['username']
password = data['password']
recipient = data['email']
admin = args[1]
F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, 'RMS-NEWUSER.html'), 'r')
FC = F.read()
FC = FC.replace('{name}', name)
FC = FC.replace('{username}', username)
FC = FC.replace('{password}', password)
FC = FC.replace('{url}', settings.FRONT_END_URL + '/cms/profile')
send_mail(
subject='Resource Management System: Welcome!',
message='',
from_email=settings.EMAIL_DEFAULT_SENDER,
recipient_list=(recipient,),
html_message=FC,
fail_silently=False
)
models.UserHistory.objects.filter(username=username).update(sent=True)
connection.close()
return True
def batch_email_admin(args):
filename = args[0]
recipient = args[1]
body = """
Dear Admin,
Please see the attached file as your reference for the recent bulk users you have uploaded as an Administrator in RMS.
This email and any files transmitted with it are confidential and may contain privileged and confidential information,
including personal information protected by privacy laws.
It is intended only for the use of the individual or entity to whom they are addressed.
"""
msg = MIMEText(body)
email = EmailMessage(
'Resource Management System: Bulk Users!',
body,
settings.EMAIL_DEFAULT_SENDER,
[recipient]
)
email.attach_file(filename)
email.send()
os.remove(filename)
# def account_created(args, username, password, receiver) :
def account_created(args): def account_created(args):
name = args[0] name = args[0]
username = args[1] username = args[1]
...@@ -51,20 +125,7 @@ def account_created(args): ...@@ -51,20 +125,7 @@ def account_created(args):
def cronjob(args): def cronjob(args):
# name = args[0]
# username = args[1]
# password = args[2]
# recipient = args[3]
# admin = args[4]
# F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, 'RMS-NEWUSER.html'), 'r')
# FC = F.read()
# FC = FC.replace('{name}', name)
# FC = FC.replace('{username}', username)
# FC = FC.replace('{password}', password)
# FC = FC.replace('{url}', settings.FRONT_END_URL + '/cms/profile') #changed
try: try:
send_mail( send_mail(
subject='Resource Management System: Welcome!', subject='Resource Management System: Welcome!',
...@@ -145,24 +206,6 @@ def forgot_password(args): ...@@ -145,24 +206,6 @@ def forgot_password(args):
) )
# def password_changed(username, date, receiver) :
# F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, 'password-changed.html'), 'r')
# FC = F.read()
# FC = FC.replace('[Username]', username)
# FC = FC.replace('[Datetime]', date)
# FC = FC.replace('[URL]', settings.FRONT_END_URL)
# send_mail(
# subject='OB RMS: Password Changed!',
# message='',
# from_email=settings.EMAIL_DEFAULT_SENDER,
# recipient_list=[receiver,],
# html_message=FC
# )
def admin_changepassword(args): def admin_changepassword(args):
name = args[0] name = args[0]
username = args[1] username = args[1]
...@@ -188,344 +231,9 @@ def admin_changepassword(args): ...@@ -188,344 +231,9 @@ def admin_changepassword(args):
) )
# def account_created(username, password, receiver) :
# F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, 'account-created.html'), 'r')
# FC = F.read()
# FC = FC.replace('[Username]', username)
# FC = FC.replace('[Password]', password)
# FC = FC.replace('[URL]', settings.FRONT_END_URL)
# send_mail(
# subject='OB IMS: Welcome!',
# message='',
# from_email=settings.EMAIL_DEFAULT_SENDER,
# recipient_list=[receiver,],
# html_message=FC
# )
# def stock_requisition_new(sr_id,
# sr_no,
# requestor,
# requested_on,
# project,
# remarks,
# receiver,
# requested_items=[],
# purchase_items=[],
# required_date=None):
# F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, 'stock-requisition.html'), 'r')
# FC = F.read()
# FC = FC.replace('[SR No]', sr_no)
# FC = FC.replace('[Requestor]', requestor)
# FC = FC.replace('[Requested On]', requested_on)
# FC = FC.replace('[Project]', project)
# FC = FC.replace('[Remarks]', remarks)
# # PRINT SR ITEMS
# if requested_items and len(requested_items) > 0:
# appendedList = ''
# for item in requested_items :
# prodNo = str(item.product.product_no)
# prodName = str(item.product.name)
# brand = str(item.product.brand.name)
# qty = str(item.quantity)
# unit = str(item.product.unit_material.name)
# appendedList += '\t\t\t\t \
# <tr bgcolor="#FFFFFF"> \
# <td>' + prodNo + '</td> \
# <td>' + prodName + '</td> \
# <td>' + brand + '</td> \
# <td>' + qty + '</td> \
# <td>' + unit + '</td> \
# </tr>'
# FC = FC.replace('<tr bgcolor="#FFFFFF" id="sr">\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n </tr>', appendedList)
# # PRINT PR ITEMS
# if purchase_items and len(purchase_items) > 0 :
# FC = FC.replace('[Required Date]', required_date)
# appendedList = ''
# for item in purchase_items :
# prodNo = str(item.product.product_no)
# prodName = str(item.product.name)
# brand = str(item.product.brand.name)
# qty = str(item.quantity)
# unit = str(item.product.unit_material.name)
# appendedList += '\t\t\t\t \
# <tr bgcolor="#FFFFFF"> \
# <td>' + prodNo + '</td> \
# <td>' + prodName + '</td> \
# <td>' + brand + '</td> \
# <td>' + qty + '</td> \
# <td>' + unit + '</td> \
# </tr>'
# FC = FC.replace('<tr bgcolor="#FFFFFF" id="pr">\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n </tr>', appendedList)
# urlApprove = f"{settings.FRONT_END_URL}/{'transaction/requisition/approve'}/{sr_id}/basic"
# urlReject = f"{settings.FRONT_END_URL}/{'transaction/requisition/reject'}/{sr_id}/basic"
# FC = FC.replace('ApproveToken', urlApprove)
# FC = FC.replace('RejectToken', urlReject)
# send_mail(
# subject='OB IMS: '+ sr_no +' by ' + requestor,
# message='',
# from_email=settings.EMAIL_DEFAULT_SENDER,
# recipient_list=[receiver,],
# html_message=FC
# )
# def stock_requisition_approve(sr_no,
# requestor,
# requestor_email,
# requested_on,
# requestor_contact,
# project,
# remarks,
# approved_by,
# approved_date,
# requested_items=[],
# purchase_items=[],
# required_date=None):
# # requested_items
# # LIST OF "RequisitionApproveItem"
# # purchase_items
# # LIST OF "PurchaseRequestApproveItem"
# F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, 'stock-requisition-approved.html'), 'r')
# FC = F.read()
# FC = FC.replace('[SR No]', sr_no)
# FC = FC.replace('[Requestor]', requestor)
# FC = FC.replace('[Requested On]', requested_on)
# FC = FC.replace('[Project]', project)
# FC = FC.replace('[Remarks]', remarks)
# FC = FC.replace('[Approved By]', approved_by)
# FC = FC.replace('[Approved On]', approved_date)
# # PRINT SR ITEMS
# if len(requested_items) > 0 :
# appendedList = ''
# for item in requested_items :
# prodNo = item.requisition_product.product.product_no
# prodName = item.requisition_product.product.name
# brand = item.requisition_product.product.brand.name
# qty = str(item.quantity)
# unit = item.requisition_product.product.unit_material.name
# appendedList += '\t\t\t\t \
# <tr bgcolor="#FFFFFF"> \
# <td>' + prodNo + '</td> \
# <td>' + prodName + '</td> \
# <td>' + brand + '</td> \
# <td>' + qty + '</td> \
# <td>' + unit + '</td> \
# </tr>'
# FC = FC.replace('<tr bgcolor="#FFFFFF" id="sr">\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n </tr>', appendedList)
# # PRINT PR ITEMS
# if len(purchase_items) > 0 :
# FC = FC.replace('[Required Date]', required_date)
# appendedList = ''
# for item in purchase_items :
# prodNo = item.purchase_request_item.product.product_no
# prodName = item.purchase_request_item.product.name
# brand = item.purchase_request_item.product.brand.name
# qty = str(item.quantity)
# unit = item.purchase_request_item.product.unit_material.name
# appendedList += '\t\t\t\t \
# <tr bgcolor="#FFFFFF"> \
# <td>' + prodNo + '</td> \
# <td>' + prodName + '</td> \
# <td>' + brand + '</td> \
# <td>' + qty + '</td> \
# <td>' + unit + '</td> \
# </tr>'
# FC = FC.replace('<tr bgcolor="#FFFFFF" id="pr">\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n </tr>', appendedList)
# approver_emails = []
# # roles_receives = ['Receive Stock Requisition Authorization Email',
# # 'Allow Purchase Requests Authorisation',
# # 'Receive Stock Request Email',
# # 'Receive Purchase Request Email']
# # qry = models.User.objects.filter(user_roles__role__code__in=roles_receives).values('email').distinct()
# # for item in qry:
# # approver_emails.append(item['email'])
# approver_emails.append(requestor_email)
# if len(approver_emails) > 0:
# send_mail(
# subject='OB IMS Stock Request: '+ sr_no,
# message='',
# from_email=settings.EMAIL_DEFAULT_SENDER,
# recipient_list=approver_emails,
# html_message=FC
# )
# def stock_requisition_reject(sr_no,
# requestor,
# requestor_email,
# requested_on,
# project,
# remarks,
# rejected_reason,
# rejected_by,
# rejected_date,
# requested_items=[],
# purchase_items=[],
# required_date=None):
# # requested_items
# # LIST OF "RequisitionRejectItem"
# # purchase_items
# # LIST OF "PurchaseRequestRejectItem"
# F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, 'stock-requisition-rejected.html'), 'r')
# FC = F.read()
# FC = FC.replace('[SR No]', sr_no)
# FC = FC.replace('[Requestor]', requestor)
# FC = FC.replace('[Requested On]', requested_on)
# FC = FC.replace('[Project]', project)
# FC = FC.replace('[Remarks]', remarks)
# FC = FC.replace('[Rejected By]', rejected_by)
# FC = FC.replace('[Rejected On]', rejected_date)
# FC = FC.replace('[Rejected Reason]', rejected_reason)
# # PRINT SR ITEMS
# if len(requested_items) > 0 :
# appendedList = ''
# for item in requested_items :
# prodNo = item.requisition_product.product.product_no
# prodName = item.requisition_product.product.name
# brand = item.requisition_product.product.brand.name
# qty = str(item.quantity)
# unit = item.requisition_product.product.unit_material.name
# appendedList += '\t\t\t\t \
# <tr bgcolor="#FFFFFF"> \
# <td>' + prodNo + '</td> \
# <td>' + prodName + '</td> \
# <td>' + brand + '</td> \
# <td>' + qty + '</td> \
# <td>' + unit + '</td> \
# </tr>'
# FC = FC.replace('<tr bgcolor="#FFFFFF" id="sr">\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n </tr>', appendedList)
# # PRINT PR ITEMS
# if len(purchase_items) > 0 :
# FC = FC.replace('[Required Date]', required_date)
# appendedList = ''
# for item in purchase_items :
# prodNo = item.purchase_request_item.product.product_no
# prodName = item.purchase_request_item.product.name
# brand = item.purchase_request_item.product.brand.name
# qty = str(item.quantity)
# unit = item.purchase_request_item.product.unit_material.name
# appendedList += '\t\t\t\t \
# <tr bgcolor="#FFFFFF"> \
# <td>' + prodNo + '</td> \
# <td>' + prodName + '</td> \
# <td>' + brand + '</td> \
# <td>' + qty + '</td> \
# <td>' + unit + '</td> \
# </tr>'
# FC = FC.replace('<tr bgcolor="#FFFFFF" id="pr">\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n <td>&nbsp;</td>\n </tr>', appendedList)
# approver_emails = []
# # roles_receives = ['Receive Stock Requisition Authorization Email', 'Allow Purchase Requests Authorisation', 'Receive Stock Request Email', 'Receive Purchase Request Email']
# # qry = models.User.objects.filter(user_roles__role__code__in=roles_receives).values('email').distinct()
# # for item in qry :
# # approver_emails.append(item['email'])
# approver_emails.append(requestor_email)
# if len(approver_emails) > 0:
# send_mail(
# subject='OB IMS: '+ sr_no +' by ' + requestor,
# message='',
# from_email=settings.EMAIL_DEFAULT_SENDER,
# recipient_list=approver_emails,
# html_message=FC
# )
# # def account_password_reset(username, password, receiver, date_reset) :
# # F = open(os.path.join(EMAIL_TEMPLATES_ROOT, 'reset-password.html'), 'r')
# # FC = F.read()
# # FC = FC.replace('[Username]', username)
# # FC = FC.replace('[Password]', password)
# # FC = FC.replace('[Reset Datetime]', date_reset)
# # send_mail(
# # subject='OB IMS: Password Reset!',
# # message='',
# # from_email=EMAIL_DEFAULT_SENDER,
# # recipient_list=[receiver,],
# # html_message=FC
# # )
# RMS-CRAPPROVED ; RMS-CRACKNOWLEDGE ; RMS-CRCOMPLETED ; RMS-CRACCEPTED ; # RMS-CRAPPROVED ; RMS-CRACKNOWLEDGE ; RMS-CRCOMPLETED ; RMS-CRACCEPTED ;
# RMS-CRREJECTED ; RMS-CRREJECTED-VENDOR # RMS-CRREJECTED ; RMS-CRREJECTED-VENDOR ; RMS-CRREVISED ; RMS-CRCANCELLED-USERTRIGGER ;
# RMS-CRREJECTED-APPROVER
def routing_table_actions(args): def routing_table_actions(args):
...@@ -546,7 +254,8 @@ def routing_table_actions(args): ...@@ -546,7 +254,8 @@ def routing_table_actions(args):
recipient = args[11] recipient = args[11]
action_type = args[12] action_type = args[12]
delegation_type = args[13] delegation_type = args[13]
admin = args[14] delegation_recipient = args[14]
admin = args[15]
if args[12].lower() == 'approved': if args[12].lower() == 'approved':
email_template = 'RMS-CRAPPROVED.html' email_template = 'RMS-CRAPPROVED.html'
...@@ -561,16 +270,23 @@ def routing_table_actions(args): ...@@ -561,16 +270,23 @@ def routing_table_actions(args):
email_template = 'RMS-CRACCEPTED.html' email_template = 'RMS-CRACCEPTED.html'
subject = 'Resource Management System - Change Request Accepted' subject = 'Resource Management System - Change Request Accepted'
elif args[12].lower() == 'rejected': elif args[12].lower() == 'rejected':
subject = 'Resource Management System - Change Request Rejected' if args[14].lower() == 'requestor':
if args[13].lower() == 'requestor' or args[13].lower() == 'others': subject = 'Resource Management System - Change Request Rejected'
email_template = 'RMS-CRREJECTED-VENDOR.html'
else:
email_template = 'RMS-CRREJECTED.html' email_template = 'RMS-CRREJECTED.html'
elif args[14].lower() == 'vendor':
subject = 'Resource Management System - Action Required for Change Request'
email_template = 'RMS-CRREVISED.html'
elif args[14].lower() == 'approver':
subject = 'Resource Management System - Action Required for Change Request'
email_template = 'RMS-CRREJECTED-APPROVER.html'
elif args[12].lower() == 'cancelled':
subject = 'Resource Management System - Change Request Cancelled'
email_template = 'RMS-CRCANCELLED-USERTRIGGER.html'
F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, email_template), 'r') F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, email_template), 'r')
FC = F.read() FC = F.read()
FC = FC.replace('{name}', name) FC = FC.replace('{name}', name)
FC = FC.replace('{action_by}', action_by) FC = FC.replace('{action_by}', action_by)
FC = FC.replace('{routing_level}', routing_level) FC = FC.replace('{routing_level}', routing_level)
...@@ -581,16 +297,10 @@ def routing_table_actions(args): ...@@ -581,16 +297,10 @@ def routing_table_actions(args):
FC = FC.replace('{department_requestedto}', department_requestedto) FC = FC.replace('{department_requestedto}', department_requestedto)
FC = FC.replace('{priority_level}', priority_level) FC = FC.replace('{priority_level}', priority_level)
FC = FC.replace('{url}', url) FC = FC.replace('{url}', url)
if args[12].lower() == 'rejected': if args[12].lower() == 'rejected':
FC = FC.replace('{remarks}', remarks) FC = FC.replace('{remarks}', remarks)
if email_template == 'RMS-CRREJECTED-VENDOR.html':
if args[13].lower() == 'requestor':
FC = FC.replace('{delegation}', 'requestor')
else:
FC = FC.replace('{delegation}', 'approver')
try: try:
send_mail( send_mail(
subject=subject, subject=subject,
......
<!DOCTYPE html>
<html>
<head>
<title>RMS: Change Request Cancelled</title>
</head>
<body style="font-family: arial;">
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Change Request Cancelled</h3><br>
<p>Dear {name},</p><br>
<p>A change request has been cancelled. Please see the details of the change request below.</p><br>
<b>Cancelled By</b><br>{action_by}<br><br>
<b>Routing Level</b><br>{routing_level}<br><br>
<b>Status</b><br>{status}<br><br><br>
<b>CR Number</b><br>{cr_number}<br><br>
<b>CR Name</b><br>{cr_name}<br><br>
<b>Company Requested To</b><br>{company_requestedto}<br><br>
<b>Department Requested To</b><br>{department_requestedto}<br><br>
<b>Priority Level</b><br>{priority_level}<br><br>
<p>Please click <u><a href="{url}" style="text-decoration:underline;color:#007bff;" target="_blank">here</a></u> to access your change request.</p><br>
<p>Sincerely,</p>
<p>RMS Team</p><br><br>
<p>Powered by</p>
<img src="https://s3-ap-southeast-1.amazonaws.com/oneberry/img/logo_oneberry.png" class="img-responsive" style="width:150px;height:auto;" />
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>RMS: Change Request Rejected</title>
</head>
<body style="font-family: arial;">
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Change Request Rejected</h3><br>
<p>Dear {name},</p><br>
<p>A change request you have previously approved, has been re-submitted for your approval. Please see the details of the change request below.</p><br>
<b>Rejected By</b><br>{action_by}<br><br>
<b>Routing Level</b><br>{routing_level}<br><br>
<b>Status</b><br>{status}<br><br><br>
<b>CR Number</b><br>{cr_number}<br><br>
<b>CR Name</b><br>{cr_name}<br><br>
<b>Company Requested To</b><br>{company_requestedto}<br><br>
<b>Department Requested To</b><br>{department_requestedto}<br><br>
<b>Priority Level</b><br>{priority_level}<br><br>
<b>Remarks</b><br>{remarks}<br><br>
<p>Please click <u><a href="{url}" style="text-decoration:underline;color:#007bff;" target="_blank">here</a></u> to access your change request.</p><br>
<p>Sincerely,</p>
<p>RMS Team</p><br><br>
<p>Powered by</p>
<img src="https://s3-ap-southeast-1.amazonaws.com/oneberry/img/logo_oneberry.png" class="img-responsive" style="width:150px;height:auto;" />
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>RMS: Change Request Rejected</title>
</head>
<body style="font-family: arial;">
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Change Request Rejected</h3><br>
<p>Dear {name},</p><br>
<p>A change request has been submitted for your acknowledgement to revise. Please see the details of the change request below.</p><br>
<b>Rejected By</b><br>{action_by}<br><br>
<b>Routing Level</b><br>{routing_level}<br><br>
<b>Status</b><br>{status}<br><br><br>
<b>CR Number</b><br>{cr_number}<br><br>
<b>CR Name</b><br>{cr_name}<br><br>
<b>Company Requested To</b><br>{company_requestedto}<br><br>
<b>Department Requested To</b><br>{department_requestedto}<br><br>
<b>Priority Level</b><br>{priority_level}<br><br>
<b>Remarks</b><br>{remarks}<br><br>
<p>Please click <u><a href="{url}" style="text-decoration:underline;color:#007bff;" target="_blank">here</a></u> to access your change request.</p><br>
<p>Sincerely,</p>
<p>RMS Team</p><br><br>
<p>Powered by</p>
<img src="https://s3-ap-southeast-1.amazonaws.com/oneberry/img/logo_oneberry.png" class="img-responsive" style="width:150px;height:auto;" />
</body>
</html>
\ No newline at end of file
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
font-family: Arial, Helvetica, sans-serif;
margin: 30px 200px 30px 200px;
font-size: 20px;
color: #8B8B8B
}
h1 {
padding-bottom: 80px;
font-size: 24px;
font-weight: 400;
}
h2 {
font-size: 22px;
font-weight: 400;
margin-bottom: 20px;
}
h3 {
font-size: 21px;
font-weight: 400;
margin-bottom: 20px;
margin-top: 20px;
}
.requested-to {
margin-top: 20px;
}
.input {
margin-bottom: 50px;
}
label {
font-size: 19px;
font-weight: 700;
color: #737373;
}
input {
display: block;
width: 500px;
color: #8B8B8B;
font-size: 19px;
border: none;
padding-top: 20px;
margin-bottom: 10px;
border-bottom: 2px #919191 solid;
}
table, th, td {
border-bottom: 1px solid #8B8B8B;
border-collapse: collapse;
}
th {
text-align: left;
}
tr {
border-bottom: 1px solid black;
}
td {
padding: 8px;
}
.table {
margin-top: 100px;
font-size: 16px;
padding: 50px;
background-color: #F2F2F2;
border-radius: 25px;
}
\ No newline at end of file
...@@ -48,6 +48,9 @@ REQUESTOR_ACKNOWLEDGE_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_ACKNOWLE ...@@ -48,6 +48,9 @@ REQUESTOR_ACKNOWLEDGE_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_ACKNOWLE
REQUESTOR_COMPLETION_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_COMPLETION_MESSAGE'] REQUESTOR_COMPLETION_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_COMPLETION_MESSAGE']
VENDOR_ACCEPTANCE_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_ACCEPTANCE_MESSAGE'] VENDOR_ACCEPTANCE_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_ACCEPTANCE_MESSAGE']
VENDOR_REJECT_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_REJECT_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 #ADMIN PROFILE
CATCH_EMAIL = config['DEV']['CATCH_EMAIL'] CATCH_EMAIL = config['DEV']['CATCH_EMAIL']
......
...@@ -45,6 +45,9 @@ REQUESTOR_ACKNOWLEDGE_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_ACKNOWLE ...@@ -45,6 +45,9 @@ REQUESTOR_ACKNOWLEDGE_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_ACKNOWLE
REQUESTOR_COMPLETION_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_COMPLETION_MESSAGE'] REQUESTOR_COMPLETION_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_COMPLETION_MESSAGE']
VENDOR_ACCEPTANCE_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_ACCEPTANCE_MESSAGE'] VENDOR_ACCEPTANCE_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_ACCEPTANCE_MESSAGE']
VENDOR_REJECT_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_REJECT_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 #ADMIN PROFILE
CATCH_EMAIL = config['LOCAL']['CATCH_EMAIL'] CATCH_EMAIL = config['LOCAL']['CATCH_EMAIL']
......
...@@ -48,6 +48,9 @@ REQUESTOR_ACKNOWLEDGE_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_ACKNOWLE ...@@ -48,6 +48,9 @@ REQUESTOR_ACKNOWLEDGE_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_ACKNOWLE
REQUESTOR_COMPLETION_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_COMPLETION_MESSAGE'] REQUESTOR_COMPLETION_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_COMPLETION_MESSAGE']
VENDOR_ACCEPTANCE_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_ACCEPTANCE_MESSAGE'] VENDOR_ACCEPTANCE_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_ACCEPTANCE_MESSAGE']
VENDOR_REJECT_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_REJECT_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 #ADMIN PROFILE
CATCH_EMAIL = config['PRODUCTION']['CATCH_EMAIL'] CATCH_EMAIL = config['PRODUCTION']['CATCH_EMAIL']
......
...@@ -47,6 +47,9 @@ REQUESTOR_ACKNOWLEDGE_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_ACKNOWLE ...@@ -47,6 +47,9 @@ REQUESTOR_ACKNOWLEDGE_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_ACKNOWLE
REQUESTOR_COMPLETION_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_COMPLETION_MESSAGE'] REQUESTOR_COMPLETION_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_COMPLETION_MESSAGE']
VENDOR_ACCEPTANCE_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_ACCEPTANCE_MESSAGE'] VENDOR_ACCEPTANCE_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_ACCEPTANCE_MESSAGE']
VENDOR_REJECT_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_REJECT_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 #ADMIN PROFILE
CATCH_EMAIL = config['STAGING']['CATCH_EMAIL'] CATCH_EMAIL = config['STAGING']['CATCH_EMAIL']
......
...@@ -48,6 +48,9 @@ REQUESTOR_ACKNOWLEDGE_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_ACKNOWLE ...@@ -48,6 +48,9 @@ REQUESTOR_ACKNOWLEDGE_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_ACKNOWLE
REQUESTOR_COMPLETION_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_COMPLETION_MESSAGE'] REQUESTOR_COMPLETION_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_COMPLETION_MESSAGE']
VENDOR_ACCEPTANCE_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_ACCEPTANCE_MESSAGE'] VENDOR_ACCEPTANCE_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_ACCEPTANCE_MESSAGE']
VENDOR_REJECT_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_REJECT_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 #ADMIN PROFILE
CATCH_EMAIL = config['UAT']['CATCH_EMAIL'] CATCH_EMAIL = config['UAT']['CATCH_EMAIL']
......
...@@ -22,8 +22,6 @@ from django.conf import settings ...@@ -22,8 +22,6 @@ from django.conf import settings
from django.conf.urls.static import static from django.conf.urls.static import static
urlpatterns = [ urlpatterns = [
# path('admin/', admin.site.urls), # path('admin/', admin.site.urls),
path('api-auth/', include('rest_framework.urls')), path('api-auth/', include('rest_framework.urls')),
......
...@@ -10,9 +10,8 @@ FRONT_END_URL = ...@@ -10,9 +10,8 @@ FRONT_END_URL =
AUTH_ACCESSS_TOKEN_TIMEOUT = AUTH_ACCESSS_TOKEN_TIMEOUT =
USER_DEFAULT_PASSWORD = USER_DEFAULT_PASSWORD =
CATCH_EMAIL = gladys@tirsolutions.com CATCH_EMAIL = gladys@tirsolutions.com
CR_LINK = http://stagingrms.oneberrysystem.com/cms/change-request/form/view CR_LINK = http://staging.rms.oneberrysystem.com/cms/change-request/form/view
REALTIMESERVER_IP = 127.0.0.1:8000 REALTIMESERVER_IP = 127.0.0.1:8000
CORS_ORIGIN_ALLOW_ALL = False
[UAT] [UAT]
DATABASE_ENGINE = django.db.backends.mysql DATABASE_ENGINE = django.db.backends.mysql
...@@ -22,13 +21,12 @@ DATABASE_PASSWORD = ...@@ -22,13 +21,12 @@ DATABASE_PASSWORD =
DATABASE_HOST = DATABASE_HOST =
DATABASE_PORT = DATABASE_PORT =
SESSION_TIMEOUT = SESSION_TIMEOUT =
FRONT_END_URL = http://stagingrms.oneberrysystem.com FRONT_END_URL = http://staging.rms.oneberrysystem.com
AUTH_ACCESSS_TOKEN_TIMEOUT = AUTH_ACCESSS_TOKEN_TIMEOUT =
USER_DEFAULT_PASSWORD = USER_DEFAULT_PASSWORD =
CATCH_EMAIL = gladys@tirsolutions.com CATCH_EMAIL = gladys@tirsolutions.com
CR_LINK = http://stagingrms.oneberrysystem.com/cms/change-request/form/view CR_LINK = http://staging.rms.oneberrysystem.com/cms/change-request/form/view
REALTIMESERVER_IP = 127.0.0.1:8000 REALTIMESERVER_IP = 127.0.0.1:8000
CORS_ORIGIN_ALLOW_ALL = False
[DEV] [DEV]
DATABASE_ENGINE = django.db.backends.mysql DATABASE_ENGINE = django.db.backends.mysql
...@@ -44,7 +42,6 @@ USER_DEFAULT_PASSWORD = ...@@ -44,7 +42,6 @@ USER_DEFAULT_PASSWORD =
CATCH_EMAIL = gladys@tirsolutions.com CATCH_EMAIL = gladys@tirsolutions.com
CR_LINK = http://devweb.rmsv2.oneberrysystem.com/cms/change-request/form/view CR_LINK = http://devweb.rmsv2.oneberrysystem.com/cms/change-request/form/view
REALTIMESERVER_IP = 127.0.0.1:8000 REALTIMESERVER_IP = 127.0.0.1:8000
CORS_ORIGIN_ALLOW_ALL = True
[STAGING] [STAGING]
...@@ -54,21 +51,20 @@ DATABASE_USER = ...@@ -54,21 +51,20 @@ DATABASE_USER =
DATABASE_PASSWORD = DATABASE_PASSWORD =
DATABASE_HOST = DATABASE_HOST =
DATABASE_PORT = DATABASE_PORT =
SESSION_TIMEOUT = 30 SESSION_TIMEOUT =
FRONT_END_URL = http://stagingrms.oneberrysystem.com FRONT_END_URL = http://staging.rms.oneberrysystem.com
AUTH_ACCESSS_TOKEN_TIMEOUT = 3600 AUTH_ACCESSS_TOKEN_TIMEOUT = 3600
USER_DEFAULT_PASSWORD = password USER_DEFAULT_PASSWORD = password
CATCH_EMAIL = gladys@tirsolutions.com CATCH_EMAIL =
CR_LINK = http://stagingrms.oneberrysystem.com/cms/change-request/form/view CR_LINK = http://staging.rms.oneberrysystem.com/cms/change-request/form/view
REALTIMESERVER_IP = 127.0.0.1:8000 REALTIMESERVER_IP = 127.0.0.1:8000
CORS_ORIGIN_ALLOW_ALL = False
[LOCAL] [LOCAL]
DATABASE_ENGINE = django.db.backends.mysql DATABASE_ENGINE = django.db.backends.mysql
DATABASE_NAME = rms_db DATABASE_NAME = rms_db
DATABASE_USER = root DATABASE_USER = root
DATABASE_PASSWORD = password DATABASE_PASSWORD = 123
DATABASE_HOST = localhost DATABASE_HOST = localhost
DATABASE_PORT = 3306 DATABASE_PORT = 3306
SESSION_TIMEOUT = 30 SESSION_TIMEOUT = 30
...@@ -78,10 +74,10 @@ USER_DEFAULT_PASSWORD = password ...@@ -78,10 +74,10 @@ USER_DEFAULT_PASSWORD = password
CATCH_EMAIL = gladys@tirsolutions.com CATCH_EMAIL = gladys@tirsolutions.com
CR_LINK = http://localhost:8000/cms/change-request/form/view CR_LINK = http://localhost:8000/cms/change-request/form/view
REALTIMESERVER_IP = 127.0.0.1:8000 REALTIMESERVER_IP = 127.0.0.1:8000
CORS_ORIGIN_ALLOW_ALL = True
[SETTINGS] [SETTINGS]
CONFIG = config.settings.staging CONFIG = config.settings.local
BATCH_UPLOAD_FORMAT_FILENAME = instruction.pdf
[NOTIFICATION_EMAIL] [NOTIFICATION_EMAIL]
APPROVER_MESSAGE = has sent you an APPROVAL REQUEST for change request;RMS-ACTIONREQUIRED APPROVER_MESSAGE = has sent you an APPROVAL REQUEST for change request;RMS-ACTIONREQUIRED
...@@ -92,3 +88,6 @@ REQUESTOR_ACKNOWLEDGE_MESSAGE = has ACKNOWLEDGED the change request;RMS-CRACKNOW ...@@ -92,3 +88,6 @@ REQUESTOR_ACKNOWLEDGE_MESSAGE = has ACKNOWLEDGED the change request;RMS-CRACKNOW
REQUESTOR_COMPLETION_MESSAGE = has COMPLETED the change request;RMS-CRCOMPLETED REQUESTOR_COMPLETION_MESSAGE = has COMPLETED the change request;RMS-CRCOMPLETED
VENDOR_ACCEPTANCE_MESSAGE = has ACCEPTED the change request;RMS-CRACCEPTED VENDOR_ACCEPTANCE_MESSAGE = has ACCEPTED the change request;RMS-CRACCEPTED
VENDOR_REJECT_MESSAGE = has REJECTED the change request;RMS-CRREJECTED-VENDOR 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
\ No newline at end of file
{ {
"info": { "info": {
"_postman_id": "6221ba86-d38a-482d-b200-08062062700a", "_postman_id": "e22e74b6-003f-42b5-a067-7e7cc1674e5e",
"name": "RMSv2", "name": "RMSv2",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
}, },
...@@ -497,7 +497,7 @@ ...@@ -497,7 +497,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n \"name\": \"Business Develsopment\",\n \"company\": \"COMPANY-20190923-0000001\"\n}" "raw": "{\n \"name\": \"Product Dept\",\n \"company\": \"COMPANY-20190923-0000001\",\n \"delegation\":[2, 3]\n}"
}, },
"url": { "url": {
"raw": "{{baseurl}}/management/departments/", "raw": "{{baseurl}}/management/departments/",
...@@ -971,6 +971,56 @@ ...@@ -971,6 +971,56 @@
}, },
"response": [] "response": []
}, },
{
"name": "Upload ETL User",
"request": {
"method": "PUT",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"type": "text",
"value": "application/json",
"disabled": true
}
],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"value": "",
"type": "file"
},
{
"key": "name",
"value": "test",
"type": "text",
"disabled": true
},
{
"key": "user",
"value": "USER-20190927-0000012",
"type": "text",
"disabled": true
}
]
},
"url": {
"raw": "{{baseurl}}/management/users/batch-upload/",
"host": [
"{{baseurl}}"
],
"path": [
"management",
"users",
"batch-upload",
""
]
}
},
"response": []
},
{ {
"name": "Change Password", "name": "Change Password",
"request": { "request": {
...@@ -1111,6 +1161,386 @@ ...@@ -1111,6 +1161,386 @@
], ],
"protocolProfileBehavior": {}, "protocolProfileBehavior": {},
"_postman_isSubFolder": true "_postman_isSubFolder": true
},
{
"name": "Delegation Management",
"item": [
{
"name": "List of Delegations",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseurl}}/management/delegations/",
"host": [
"{{baseurl}}"
],
"path": [
"management",
"delegations",
""
]
}
},
"response": []
},
{
"name": "View Delegation",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseurl}}/management/delegations/DELEGATION-20191107-0000002/",
"host": [
"{{baseurl}}"
],
"path": [
"management",
"delegations",
"DELEGATION-20191107-0000002",
""
]
}
},
"response": []
},
{
"name": "Create Delegation",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"name\": \"Head of Department\"\n}"
},
"url": {
"raw": "{{baseurl}}/management/delegations/",
"host": [
"{{baseurl}}"
],
"path": [
"management",
"delegations",
""
]
}
},
"response": []
},
{
"name": "Edit Delegation",
"request": {
"method": "PUT",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"name\": \"SOD/ODs\"\n}"
},
"url": {
"raw": "{{baseurl}}/management/delegations/DELEGATION-20191107-0000002/",
"host": [
"{{baseurl}}"
],
"path": [
"management",
"delegations",
"DELEGATION-20191107-0000002",
""
]
}
},
"response": []
},
{
"name": "Delete Delegation",
"request": {
"method": "DELETE",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "{{baseurl}}/management/delegations/DELEGATION-20191107-0000001/",
"host": [
"{{baseurl}}"
],
"path": [
"management",
"delegations",
"DELEGATION-20191107-0000001",
""
]
}
},
"response": []
}
],
"protocolProfileBehavior": {},
"_postman_isSubFolder": true
},
{
"name": "Extract Transform Load",
"item": [
{
"name": "User",
"item": [
{
"name": "download",
"item": [
{
"name": "User format",
"protocolProfileBehavior": {
"disableBodyPruning": true
},
"request": {
"method": "GET",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"type": "text",
"value": "application/json",
"disabled": true
}
],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"value": "",
"type": "file"
},
{
"key": "name",
"value": "test",
"type": "text",
"disabled": true
},
{
"key": "user",
"value": "USER-20190927-0000012",
"type": "text",
"disabled": true
}
]
},
"url": {
"raw": "{{baseurl}}/management/extract-transform-load/user-format-download/",
"host": [
"{{baseurl}}"
],
"path": [
"management",
"extract-transform-load",
"user-format-download",
""
]
}
},
"response": []
},
{
"name": "User Instruction",
"protocolProfileBehavior": {
"disableBodyPruning": true
},
"request": {
"method": "GET",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"type": "text",
"value": "application/json",
"disabled": true
}
],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"value": "",
"type": "file"
},
{
"key": "name",
"value": "test",
"type": "text",
"disabled": true
},
{
"key": "user",
"value": "USER-20190927-0000012",
"type": "text",
"disabled": true
}
]
},
"url": {
"raw": "{{baseurl}}/management/extract-transform-load/user-instruction/",
"host": [
"{{baseurl}}"
],
"path": [
"management",
"extract-transform-load",
"user-instruction",
""
]
}
},
"response": []
}
],
"protocolProfileBehavior": {},
"_postman_isSubFolder": true
},
{
"name": "Upload Users",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"type": "text",
"value": "application/json",
"disabled": true
}
],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"value": "",
"type": "file"
},
{
"key": "name",
"value": "test",
"type": "text",
"disabled": true
},
{
"key": "user",
"value": "USER-20190927-0000012",
"type": "text",
"disabled": true
}
]
},
"url": {
"raw": "{{baseurl}}/management/extract-transform-load/",
"host": [
"{{baseurl}}"
],
"path": [
"management",
"extract-transform-load",
""
]
}
},
"response": []
},
{
"name": "List of filename",
"protocolProfileBehavior": {
"disableBodyPruning": true
},
"request": {
"method": "GET",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"type": "text",
"value": "application/json",
"disabled": true
}
],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"value": "",
"type": "file"
},
{
"key": "name",
"value": "test",
"type": "text",
"disabled": true
},
{
"key": "user",
"value": "USER-20190927-0000012",
"type": "text",
"disabled": true
}
]
},
"url": {
"raw": "{{baseurl}}/management/extract-transform-load/",
"host": [
"{{baseurl}}"
],
"path": [
"management",
"extract-transform-load",
""
]
}
},
"response": []
},
{
"name": "list of user on uploaded csv",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseurl}}/management/extract-transform-load/ETL-20191113-0000032/users/",
"host": [
"{{baseurl}}"
],
"path": [
"management",
"extract-transform-load",
"ETL-20191113-0000032",
"users",
""
]
}
},
"response": []
}
],
"protocolProfileBehavior": {},
"_postman_isSubFolder": true
}
],
"protocolProfileBehavior": {},
"_postman_isSubFolder": true
} }
], ],
"protocolProfileBehavior": {}, "protocolProfileBehavior": {},
...@@ -1158,7 +1588,7 @@ ...@@ -1158,7 +1588,7 @@
"formdata": [ "formdata": [
{ {
"key": "username", "key": "username",
"value": "ryu", "value": "ob-rita",
"type": "text" "type": "text"
}, },
{ {
...@@ -1323,7 +1753,7 @@ ...@@ -1323,7 +1753,7 @@
"response": [] "response": []
}, },
{ {
"name": "Form Dashboard Copy", "name": "Form Dashboard w/ Filter",
"protocolProfileBehavior": { "protocolProfileBehavior": {
"disableBodyPruning": true "disableBodyPruning": true
}, },
...@@ -1499,66 +1929,6 @@ ...@@ -1499,66 +1929,6 @@
} }
}, },
"response": [] "response": []
},
{
"name": "Form History",
"protocolProfileBehavior": {
"disableBodyPruning": true
},
"request": {
"auth": {
"type": "oauth2",
"oauth2": [
{
"key": "accessToken",
"value": "cJeBxXT2KVtu7yPUQ5HlESDqTmss8G6m",
"type": "string"
},
{
"key": "tokenType",
"type": "any"
},
{
"key": "addTokenTo",
"value": "header",
"type": "string"
}
]
},
"method": "GET",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"type": "text",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "{{baseurl}}/change-request-service/form/FRM-20190823-0000002/history/?page=2",
"host": [
"{{baseurl}}"
],
"path": [
"change-request-service",
"form",
"FRM-20190823-0000002",
"history",
""
],
"query": [
{
"key": "page",
"value": "2"
}
]
}
},
"response": []
} }
], ],
"protocolProfileBehavior": {}, "protocolProfileBehavior": {},
...@@ -1581,7 +1951,7 @@ ...@@ -1581,7 +1951,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\r\n \"requested_to_template_name\": \"XXXXXXX\",\r\n \"requested_to_objective\": \"tesa\",\r\n \"requested_to_target_date\": \"2020-05-24T04:37:36.611000\",\r\n \"requested_to_priority\": \"Normal\",\r\n \"description\": \"test\",\r\n \"status\": \"Pending\",\r\n \"company_desc\": null,\r\n \"department_desc\": null,\r\n \"requested_desc\": null,\r\n \"requested_to_template_id\": \"test555\",\r\n \"requested_to_company\": \"COMPANY-20190923-0000001\",\r\n \"requested_to_department\": \"DEPARTMENT-20191004-0000026\",\r\n \"requested_to_user\": \"USER-20191004-0000087\",\r\n \"requested_by_user\": \"USER-20191004-0000087\",\r\n \"requested_by_department\": \"DEPARTMENT-20191004-0000026\",\r\n \"template_no\": \"TMP-20191004-0000044\",\r\n \"frm_approvers\": [\r\n \t{\r\n \"level\": 1,\r\n \"delegation\": \"Head of Department\",\r\n \"user\": \"USER-20191004-0000082\"\r\n \t}\r\n ],\r\n \"frm_stakes\": [],\r\n \"frm_attachments\": [],\r\n \"frm_details\": []\r\n}" "raw": "{\r\n \"requested_to_template_name\": \"XXXXXXX\",\r\n \"requested_to_objective\": \"tesa\",\r\n \"requested_to_target_date\": \"2020-05-24T04:37:36.611000\",\r\n \"requested_to_priority\": \"Normal\",\r\n \"description\": \"test\",\r\n \"status\": \"Pending\",\r\n \"company_desc\": null,\r\n \"department_desc\": null,\r\n \"requested_desc\": null,\r\n \"requested_to_template_id\": \"test555\",\r\n \"requested_to_company\": \"COMPANY-20191025-0000017\",\r\n \"requested_to_department\": \"DEPARTMENT-20191025-0000050\",\r\n \"requested_to_user\": \"USER-20191025-0000150\",\r\n \"requested_by_user\": \"USER-20191025-0000151\",\r\n \"requested_by_department\": \"DEPARTMENT-20191025-0000050\",\r\n \"template_no\": \"TMP-20191025-0000032\",\r\n \"frm_approvers\": [\r\n \t{\r\n \"level\": 1,\r\n \"delegation\": \"Head of Department\",\r\n \"user\": \"USER-20191025-0000149\"\r\n \t}\r\n ],\r\n \"frm_stakes\": [],\r\n \"frm_attachments\": [],\r\n \"frm_details\": []\r\n}"
}, },
"url": { "url": {
"raw": "{{baseurl}}/change-request/form-post/", "raw": "{{baseurl}}/change-request/form-post/",
...@@ -1603,26 +1973,7 @@ ...@@ -1603,26 +1973,7 @@
"method": "GET", "method": "GET",
"header": [], "header": [],
"url": { "url": {
"raw": "{{baseurl}}/change-request/form/", "raw": "{{baseurl}}/change-request/form/?company_requested_to=COMPANY-20191004-0000011&department_requested_to=DEPARTMENT-20191004-0000029&form_type=closed&date_modified_from=2019-10-11&date_modified_to=2019-10-11",
"host": [
"{{baseurl}}"
],
"path": [
"change-request",
"form",
""
]
}
},
"response": []
},
{
"name": "List of Forms Copy",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseurl}}/change-request/form/?date_modified_from=2019-10-11&date_modified_to=2019-10-11",
"host": [ "host": [
"{{baseurl}}" "{{baseurl}}"
], ],
...@@ -1634,18 +1985,15 @@ ...@@ -1634,18 +1985,15 @@
"query": [ "query": [
{ {
"key": "company_requested_to", "key": "company_requested_to",
"value": "COMPANY-20191004-0000011", "value": "COMPANY-20191004-0000011"
"disabled": true
}, },
{ {
"key": "department_requested_to", "key": "department_requested_to",
"value": "DEPARTMENT-20191004-0000029", "value": "DEPARTMENT-20191004-0000029"
"disabled": true
}, },
{ {
"key": "form_type", "key": "form_type",
"value": "closed", "value": "closed"
"disabled": true
}, },
{ {
"key": "date_modified_from", "key": "date_modified_from",
...@@ -1666,35 +2014,14 @@ ...@@ -1666,35 +2014,14 @@
"method": "GET", "method": "GET",
"header": [], "header": [],
"url": { "url": {
"raw": "{{baseurl}}/change-request/form/FRM-20191021-0000148/", "raw": "{{baseurl}}/change-request/form/FRM-20191121-0000211/",
"host": [ "host": [
"{{baseurl}}" "{{baseurl}}"
], ],
"path": [ "path": [
"change-request", "change-request",
"form", "form",
"FRM-20191021-0000148", "FRM-20191121-0000211",
""
]
}
},
"response": []
},
{
"name": "Re Route for Approval",
"request": {
"method": "PATCH",
"header": [],
"url": {
"raw": "{{baseurl}}/change-request/form/FRM-20190930-0000035/re_route/",
"host": [
"{{baseurl}}"
],
"path": [
"change-request",
"form",
"FRM-20190930-0000035",
"re_route",
"" ""
] ]
} }
...@@ -1706,6 +2033,10 @@ ...@@ -1706,6 +2033,10 @@
"request": { "request": {
"method": "PATCH", "method": "PATCH",
"header": [], "header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": { "url": {
"raw": "{{baseurl}}/change-request/form/FRM-20190930-0000035/re_submit/", "raw": "{{baseurl}}/change-request/form/FRM-20190930-0000035/re_submit/",
"host": [ "host": [
...@@ -1736,12 +2067,7 @@ ...@@ -1736,12 +2067,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\r\n \"id\": 530,\r\n \"form_code\": \"FRM-20191017-0000135\",\r\n \"delegation\": \"Head of Department\",\r\n \"action\": \"Rejected\",\r\n \"level\": \"1\",\r\n \"remarks\": \"This is rejected by approver before vendor\"\r\n}", "raw": "{\r\n \"id\": 1079,\r\n \"form_code\": \"FRM-20191126-0000237\",\r\n \"delegation\": \"DELEGATION-20191119-0000003\",\r\n \"action\": \"Rejected\",\r\n \"level\": \"1\",\r\n \"remarks\": \"try lang\",\r\n \"move_to_level\": \"5\"\r\n}"
"options": {
"raw": {
"language": "json"
}
}
}, },
"url": { "url": {
"raw": "{{baseurl}}/change-request/form/actions/", "raw": "{{baseurl}}/change-request/form/actions/",
...@@ -1772,12 +2098,7 @@ ...@@ -1772,12 +2098,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\r\n \"requested_to_template_name\": \"XXXXXXX\",\r\n \"requested_to_objective\": \"tesaasdaswererytyrtyrt\",\r\n \"requested_to_target_date\": \"2020-05-24T04:37:36.611000\",\r\n \"requested_to_priority\": \"Normal\",\r\n \"description\": \"test\",\r\n \"created\": \"2019-10-04T14:06:51.671702\",\r\n \"cancel_date\": null,\r\n \"company_desc\": null,\r\n \"department_desc\": null,\r\n \"requested_desc\": null,\r\n \"requested_to_template_id\": \"test555-20191004-0000014\",\r\n \"requested_to_company\": \"COMPANY-20190923-0000001\",\r\n \"requested_to_department\": \"DEPARTMENT-20191004-0000026\",\r\n \"requested_to_user\": \"USER-20191004-0000086\",\r\n \"requested_by_user\": \"USER-20191004-0000087\",\r\n \"requested_by_department\": \"DEPARTMENT-20191004-0000026\",\r\n \"template_no\": \"TMP-20191004-0000044\",\r\n \"frm_approvers\": [\r\n {\r\n \"id\": 215,\r\n \"level\": 1,\r\n \"delegation\": \"Head of Department\",\r\n \"created\": \"2019-10-04T14:06:51.687700\",\r\n \"code\": \"FRMAPR-20191004-0000215\",\r\n \"remarks\": null,\r\n \"action\": null,\r\n \"action_date\": null,\r\n \"date_sent\": \"2019-10-04T14:06:51.754714\",\r\n \"user\": \"USER-20191004-0000082\",\r\n \"form_code\": \"FRM-20191004-0000078\"\r\n }\r\n ],\r\n \"frm_stakes\": [],\r\n \"frm_attachments\": [],\r\n \"frm_details\": [],\r\n \"action_required\": \"No\"\r\n}", "raw": "{\r\n \"requested_to_template_name\": \"XXXXXXX\",\r\n \"requested_to_objective\": \"tesaasdaswererytyrtyrt\",\r\n \"requested_to_target_date\": \"2020-05-24T04:37:36.611000\",\r\n \"requested_to_priority\": \"Normal\",\r\n \"description\": \"test\",\r\n \"created\": \"2019-10-04T14:06:51.671702\",\r\n \"cancel_date\": null,\r\n \"company_desc\": null,\r\n \"department_desc\": null,\r\n \"requested_desc\": null,\r\n \"requested_to_template_id\": \"test555-20191004-0000014\",\r\n \"requested_to_company\": \"COMPANY-20190923-0000001\",\r\n \"requested_to_department\": \"DEPARTMENT-20191004-0000026\",\r\n \"requested_to_user\": \"USER-20191004-0000086\",\r\n \"requested_by_user\": \"USER-20191004-0000087\",\r\n \"requested_by_department\": \"DEPARTMENT-20191004-0000026\",\r\n \"template_no\": \"TMP-20191004-0000044\",\r\n \"frm_approvers\": [\r\n {\r\n \"id\": 215,\r\n \"level\": 1,\r\n \"delegation\": \"Head of Department\",\r\n \"created\": \"2019-10-04T14:06:51.687700\",\r\n \"code\": \"FRMAPR-20191004-0000215\",\r\n \"remarks\": null,\r\n \"action\": null,\r\n \"action_date\": null,\r\n \"date_sent\": \"2019-10-04T14:06:51.754714\",\r\n \"user\": \"USER-20191004-0000082\",\r\n \"form_code\": \"FRM-20191004-0000078\"\r\n }\r\n ],\r\n \"frm_stakes\": [],\r\n \"frm_attachments\": [],\r\n \"frm_details\": [],\r\n \"action_required\": \"No\"\r\n}"
"options": {
"raw": {
"language": "json"
}
}
}, },
"url": { "url": {
"raw": "{{baseurl}}/change-request/form/FRM-20191004-0000078/submit/", "raw": "{{baseurl}}/change-request/form/FRM-20191004-0000078/submit/",
...@@ -1809,12 +2130,7 @@ ...@@ -1809,12 +2130,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\r\n \"requested_to_template_name\": \"XXXXXXX\",\r\n \"requested_to_objective\": \"tesass\",\r\n \"requested_to_target_date\": \"2020-05-24T04:37:36.611000\",\r\n \"requested_to_priority\": \"Normal\",\r\n \"description\": \"test\",\r\n \"created\": \"2019-10-04T14:06:51.671702\",\r\n \"cancel_date\": null,\r\n \"company_desc\": null,\r\n \"department_desc\": null,\r\n \"requested_desc\": null,\r\n \"requested_to_template_id\": \"test555-20191004-0000014\",\r\n \"requested_to_company\": \"COMPANY-20190923-0000001\",\r\n \"requested_to_department\": \"DEPARTMENT-20191004-0000026\",\r\n \"requested_to_user\": \"USER-20191004-0000086\",\r\n \"requested_by_user\": \"USER-20191004-0000087\",\r\n \"requested_by_department\": \"DEPARTMENT-20191004-0000026\",\r\n \"template_no\": \"TMP-20191004-0000044\",\r\n \"frm_approvers\": [\r\n {\r\n \"id\": 215,\r\n \"level\": 1,\r\n \"delegation\": \"Head of Department\",\r\n \"created\": \"2019-10-04T14:06:51.687700\",\r\n \"code\": \"FRMAPR-20191004-0000215\",\r\n \"remarks\": null,\r\n \"action\": null,\r\n \"action_date\": null,\r\n \"date_sent\": \"2019-10-04T14:06:51.754714\",\r\n \"user\": \"USER-20191004-0000082\",\r\n \"form_code\": \"FRM-20191004-0000078\"\r\n }\r\n ],\r\n \"frm_stakes\": [],\r\n \"frm_attachments\": [],\r\n \"frm_details\": [],\r\n \"action_required\": \"No\"\r\n}", "raw": "{\r\n \"requested_to_template_name\": \"XXXXXXX\",\r\n \"requested_to_objective\": \"tesass\",\r\n \"requested_to_target_date\": \"2020-05-24T04:37:36.611000\",\r\n \"requested_to_priority\": \"Normal\",\r\n \"description\": \"test\",\r\n \"created\": \"2019-10-04T14:06:51.671702\",\r\n \"cancel_date\": null,\r\n \"company_desc\": null,\r\n \"department_desc\": null,\r\n \"requested_desc\": null,\r\n \"requested_to_template_id\": \"test555-20191004-0000014\",\r\n \"requested_to_company\": \"COMPANY-20190923-0000001\",\r\n \"requested_to_department\": \"DEPARTMENT-20191004-0000026\",\r\n \"requested_to_user\": \"USER-20191004-0000086\",\r\n \"requested_by_user\": \"USER-20191004-0000087\",\r\n \"requested_by_department\": \"DEPARTMENT-20191004-0000026\",\r\n \"template_no\": \"TMP-20191004-0000044\",\r\n \"frm_approvers\": [\r\n {\r\n \"id\": 215,\r\n \"level\": 1,\r\n \"delegation\": \"Head of Department\",\r\n \"created\": \"2019-10-04T14:06:51.687700\",\r\n \"code\": \"FRMAPR-20191004-0000215\",\r\n \"remarks\": null,\r\n \"action\": null,\r\n \"action_date\": null,\r\n \"date_sent\": \"2019-10-04T14:06:51.754714\",\r\n \"user\": \"USER-20191004-0000082\",\r\n \"form_code\": \"FRM-20191004-0000078\"\r\n }\r\n ],\r\n \"frm_stakes\": [],\r\n \"frm_attachments\": [],\r\n \"frm_details\": [],\r\n \"action_required\": \"No\"\r\n}"
"options": {
"raw": {
"language": "json"
}
}
}, },
"url": { "url": {
"raw": "{{baseurl}}/change-request/form/FRM-20191004-0000078/save/", "raw": "{{baseurl}}/change-request/form/FRM-20191004-0000078/save/",
...@@ -1846,12 +2162,7 @@ ...@@ -1846,12 +2162,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "", "raw": ""
"options": {
"raw": {
"language": "json"
}
}
}, },
"url": { "url": {
"raw": "{{baseurl}}/change-request/form/FRM-20191008-0000087/", "raw": "{{baseurl}}/change-request/form/FRM-20191008-0000087/",
...@@ -1893,6 +2204,10 @@ ...@@ -1893,6 +2204,10 @@
"request": { "request": {
"method": "PATCH", "method": "PATCH",
"header": [], "header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": { "url": {
"raw": "{{baseurl}}/change-request/form/FRM-20190930-0000034/", "raw": "{{baseurl}}/change-request/form/FRM-20190930-0000034/",
"host": [ "host": [
...@@ -1947,14 +2262,14 @@ ...@@ -1947,14 +2262,14 @@
"raw": "" "raw": ""
}, },
"url": { "url": {
"raw": "{{baseurl}}/change-request/form/FRM-20191007-0000078/history/", "raw": "{{baseurl}}/change-request/form/FRM-20191025-0000040/history/",
"host": [ "host": [
"{{baseurl}}" "{{baseurl}}"
], ],
"path": [ "path": [
"change-request", "change-request",
"form", "form",
"FRM-20191007-0000078", "FRM-20191025-0000040",
"history", "history",
"" ""
] ]
...@@ -1976,22 +2291,17 @@ ...@@ -1976,22 +2291,17 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\r\n\t\"attachments\": [\r\n\t\t{\r\n\t\t\t\"id\": 2,\r\n\t\t\t\"attachment_type\": \"Before\",\r\n\t\t\t\"attachment_name\": \"we\",\r\n\t\t\t\"file_name\": \"logo_oneberry.png\",\r\n\t\t\t\"description\": \"we\",\r\n\t\t\t\"file_upload\": 140,\r\n\t\t\t\"uploaded_by\": \"USER-20191004-0000098\"\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"attachment_type\": \"hello\",\r\n\t\t\t\"attachment_name\": \"hello name\",\r\n\t\t\t\"file_name\": \"logo_oneberry.png\",\r\n\t\t\t\"description\": \"hello desc\",\r\n\t\t\t\"file_upload\": 139,\r\n\t\t\t\"attachment_no\": \"\",\r\n\t\t\t\"date_uploaded\": \"\",\r\n\t\t\t\"file\": \"\",\r\n\t\t\t\"template_no\": \"\",\r\n\t\t\t\"upload_no\": \"\"\r\n\t\t}\r\n\t]\r\n}\r\n", "raw": "{\r\n\t\"attachments\": [\r\n\t\t{\r\n\t\t\t\"attachment_type\": \"Before\",\r\n\t\t\t\"attachment_name\": \"we\",\r\n\t\t\t\"file_name\": \"logo_oneberry.png\",\r\n\t\t\t\"description\": \"we\",\r\n\t\t\t\"file_upload\": 302,\r\n\t\t\t\"uploaded_by\": \"USER-20191004-0000098\"\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"attachment_type\": \"hello\",\r\n\t\t\t\"attachment_name\": \"hello name\",\r\n\t\t\t\"file_name\": \"logo_oneberry.png\",\r\n\t\t\t\"description\": \"hello desc\",\r\n\t\t\t\"file_upload\": 63,\r\n\t\t\t\"attachment_no\": \"\",\r\n\t\t\t\"date_uploaded\": \"\",\r\n\t\t\t\"file\": \"\",\r\n\t\t\t\"template_no\": \"\",\r\n\t\t\t\"upload_no\": \"\"\r\n\t\t}\r\n\t]\r\n}\r\n"
"options": {
"raw": {
"language": "json"
}
}
}, },
"url": { "url": {
"raw": "{{baseurl}}/change-request/form/FRM-20191004-0000072/file_upload/", "raw": "{{baseurl}}/change-request/form/FRM-20191029-0000171/file_upload/",
"host": [ "host": [
"{{baseurl}}" "{{baseurl}}"
], ],
"path": [ "path": [
"change-request", "change-request",
"form", "form",
"FRM-20191004-0000072", "FRM-20191029-0000171",
"file_upload", "file_upload",
"" ""
] ]
...@@ -2272,14 +2582,14 @@ ...@@ -2272,14 +2582,14 @@
"method": "GET", "method": "GET",
"header": [], "header": [],
"url": { "url": {
"raw": "{{baseurl}}/change-request/template/TMP-20191022-0000092/", "raw": "{{baseurl}}/change-request/template/TMP-20191025-0000032/",
"host": [ "host": [
"{{baseurl}}" "{{baseurl}}"
], ],
"path": [ "path": [
"change-request", "change-request",
"template", "template",
"TMP-20191022-0000092", "TMP-20191025-0000032",
"" ""
] ]
} }
...@@ -2660,6 +2970,31 @@ ...@@ -2660,6 +2970,31 @@
} }
}, },
"response": [] "response": []
},
{
"name": "Default Approver",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseurl}}/change-request/default-approvers/?department_code=DEPARTMENT-20191121-0000064",
"host": [
"{{baseurl}}"
],
"path": [
"change-request",
"default-approvers",
""
],
"query": [
{
"key": "department_code",
"value": "DEPARTMENT-20191121-0000064"
}
]
}
},
"response": []
} }
], ],
"protocolProfileBehavior": {}, "protocolProfileBehavior": {},
...@@ -2738,7 +3073,7 @@ ...@@ -2738,7 +3073,7 @@
"method": "GET", "method": "GET",
"header": [], "header": [],
"url": { "url": {
"raw": "{{baseurl}}/change-request/form-user-list/?department_code=DEPARTMENT-20191001-0000017", "raw": "{{baseurl}}/change-request/form-user-list/?department_code=DEPARTMENT-20191121-0000064",
"host": [ "host": [
"{{baseurl}}" "{{baseurl}}"
], ],
...@@ -2750,7 +3085,7 @@ ...@@ -2750,7 +3085,7 @@
"query": [ "query": [
{ {
"key": "department_code", "key": "department_code",
"value": "DEPARTMENT-20191001-0000017" "value": "DEPARTMENT-20191121-0000064"
} }
] ]
} }
...@@ -2805,7 +3140,7 @@ ...@@ -2805,7 +3140,7 @@
"raw": "" "raw": ""
}, },
"url": { "url": {
"raw": "{{baseurl}}/management/notifications/?account_no=USER-20190927-0000011", "raw": "{{baseurl}}/management/notifications/?account_no=USER-20191025-0000155&app=ams",
"host": [ "host": [
"{{baseurl}}" "{{baseurl}}"
], ],
...@@ -2817,7 +3152,11 @@ ...@@ -2817,7 +3152,11 @@
"query": [ "query": [
{ {
"key": "account_no", "key": "account_no",
"value": "USER-20190927-0000011" "value": "USER-20191025-0000155"
},
{
"key": "app",
"value": "ams"
} }
] ]
} }
...@@ -2974,12 +3313,7 @@ ...@@ -2974,12 +3313,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n\t\"name\": \"Asset Group 1\",\n\t\"asset_group\": \"JTC\"\n}", "raw": "{\n\t\"name\": \"Asset Group 1\",\n\t\"asset_group\": \"JTC\"\n}"
"options": {
"raw": {
"language": "json"
}
}
}, },
"url": { "url": {
"raw": "{{baseurl}}/asset-management/asset-group/", "raw": "{{baseurl}}/asset-management/asset-group/",
...@@ -3009,12 +3343,7 @@ ...@@ -3009,12 +3343,7 @@
], ],
"body": { "body": {
"mode": "raw", "mode": "raw",
"raw": "{\n\t\"name\": \"Asset Group 3\",\n\t\"asset_group\": \"JTCs\"\n}", "raw": "{\n\t\"name\": \"Asset Group 3\",\n\t\"asset_group\": \"JTCs\"\n}"
"options": {
"raw": {
"language": "json"
}
}
}, },
"url": { "url": {
"raw": "{{baseurl}}/asset-management/asset-group/AMSGRP-20191025-0000002/", "raw": "{{baseurl}}/asset-management/asset-group/AMSGRP-20191025-0000002/",
...@@ -3036,6 +3365,10 @@ ...@@ -3036,6 +3365,10 @@
"request": { "request": {
"method": "DELETE", "method": "DELETE",
"header": [], "header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": { "url": {
"raw": "{{baseurl}}/asset-management/asset-group/AMSGRP-20191025-0000002/", "raw": "{{baseurl}}/asset-management/asset-group/AMSGRP-20191025-0000002/",
"host": [ "host": [
...@@ -3070,6 +3403,25 @@ ...@@ -3070,6 +3403,25 @@
} }
}, },
"response": [] "response": []
},
{
"name": "List Asset Group",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseurl}}/asset-management/asset-group/",
"host": [
"{{baseurl}}"
],
"path": [
"asset-management",
"asset-group",
""
]
}
},
"response": []
} }
], ],
"protocolProfileBehavior": {}, "protocolProfileBehavior": {},
...@@ -3084,7 +3436,7 @@ ...@@ -3084,7 +3436,7 @@
"bearer": [ "bearer": [
{ {
"key": "token", "key": "token",
"value": "1e3ef7cc7a343b5fa0b54bd2d1699cfee6ca6afe", "value": "1bc82df8030501015e54bb3f1f78356b9041f796",
"type": "string" "type": "string"
} }
] ]
......
...@@ -6,6 +6,8 @@ async-timeout==3.0.1 ...@@ -6,6 +6,8 @@ async-timeout==3.0.1
attrs==19.1.0 attrs==19.1.0
autobahn==19.9.2 autobahn==19.9.2
Automat==0.7.0 Automat==0.7.0
cairocffi==1.1.0
CairoSVG==2.4.2
certifi==2019.6.16 certifi==2019.6.16
cffi==1.12.3 cffi==1.12.3
channels==2.2.0 channels==2.2.0
...@@ -14,7 +16,9 @@ chardet==3.0.4 ...@@ -14,7 +16,9 @@ chardet==3.0.4
colorama==0.4.1 colorama==0.4.1
constantly==15.1.0 constantly==15.1.0
cryptography==2.7 cryptography==2.7
cssselect2==0.2.2
daphne==2.3.0 daphne==2.3.0
defusedxml==0.6.0
Django==2.2 Django==2.2
django-cors-headers==2.5.2 django-cors-headers==2.5.2
django-filter==2.1.0 django-filter==2.1.0
...@@ -25,6 +29,7 @@ et-xmlfile==1.0.1 ...@@ -25,6 +29,7 @@ et-xmlfile==1.0.1
gevent==1.4.0 gevent==1.4.0
greenlet==0.4.15 greenlet==0.4.15
hiredis==1.0.0 hiredis==1.0.0
html5lib==1.0.1
hyperlink==19.0.0 hyperlink==19.0.0
idna==2.8 idna==2.8
incremental==17.5.0 incremental==17.5.0
...@@ -35,21 +40,31 @@ Markdown==3.1 ...@@ -35,21 +40,31 @@ Markdown==3.1
mccabe==0.6.1 mccabe==0.6.1
msgpack==0.6.1 msgpack==0.6.1
mysqlclient==1.4.2.post1 mysqlclient==1.4.2.post1
numpy==1.17.3
openpyxl==3.0.0 openpyxl==3.0.0
pandas==0.25.3
pep8==1.7.1 pep8==1.7.1
Pillow==6.0.0 Pillow==6.0.0
pycodestyle==2.5.0
pycparser==2.19 pycparser==2.19
PyHamcrest==1.9.0 PyHamcrest==1.9.0
pylint==2.3.1 pylint==2.3.1
PyPDF2==1.26.0
Pyphen==0.9.5
python-dateutil==2.8.1
pytz==2018.9 pytz==2018.9
reportlab==3.5.32
requests==2.22.0 requests==2.22.0
six==1.12.0 six==1.12.0
sqlparse==0.3.0 sqlparse==0.3.0
tinycss2==1.0.2
Twisted==19.7.0 Twisted==19.7.0
txaio==18.8.1 txaio==18.8.1
typed-ast==1.3.1 typed-ast==1.3.1
urllib3==1.25.3 urllib3==1.25.3
webencodings==0.5.1
websocket==0.2.1 websocket==0.2.1
websocket-client==0.54.0 websocket-client==0.54.0
wrapt==1.11.1 wrapt==1.11.1
zope.interface==4.6.0 xhtml2pdf==0.2.3
\ No newline at end of file zope.interface==4.6.0
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