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

Merge pull request #86 in RMS/api-main-service from red-develop to RMSv2

* commit 'dab586ce':
  merge conflict migration
  fixing conflict
  pulled cms
  new rms
parents d48679c9 dab586ce
......@@ -8,7 +8,11 @@ urlpatterns = (
re_path(r'^refresh-token/(?P<token>\w+)/$', views.RefreshToken.as_view(), name="Refresh Token"),
path(r'current-user/', views.CurrentUser.as_view(), name="Current User"),
re_path(r'^forgot-password/(?P<username>\w+)/$', views.ForgotPassword.as_view(), name="Forgot Password"),
re_path(r'^validate-forgot-password-reset-token/(?P<token>\w+)/$', views.ValidateForgotPasswordResetToken.as_view(), name="Validate Forgot Password Reset Token"),
re_path(r'^forgot-password-reset/(?P<token>\w+)/$', views.ForgotPasswordReset.as_view(), name="Forgot Password Reset"),
# re_path(r'^forgot-password/(?P<username>\w+)/$', views.ForgotPassword.as_view(), name="Forgot Password"),
# re_path(r'^validate-forgot-password-reset-token/(?P<token>\w+)/$', views.ValidateForgotPasswordResetToken.as_view(), name="Validate Forgot Password Reset Token"),
# re_path(r'^forgot-password-reset/(?P<token>\w+)/$', views.ForgotPasswordReset.as_view(), name="Forgot Password Reset"),
path('forgot-password/', views.ForgotPassword.as_view()),
path('reset-password-link/', views.ValidateForgotPasswordResetToken.as_view()),
path('forgot-password-reset/', views.ForgotPasswordReset.as_view()),
)
import json
import threading
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.authtoken.views import ObtainAuthToken
......@@ -16,26 +17,33 @@ from datetime import datetime
from random import randrange
from django.conf import settings
from app.helper.email_service import sender
from app.applicationlayer.utils import main_threading
from rest_framework.exceptions import ParseError
class Login(ObtainAuthToken):
@decorators.error_safe
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data,
try:
serializer = self.serializer_class(data=request.data,
context={'request': request})
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
token, created = Token.objects.get_or_create(user=user)
if not created:
token.created = datetime.now()
token.save()
if not created:
token.created = datetime.now()
token.save()
return Response({
'token': token.key,
# 'user_id': user.pk,
# 'email': user.email
})
return Response({
'token': token.key,
# 'user_id': user.pk,
# 'email': user.email
})
except Exception as e:
return Response(
{"message": "Unable to log in with provided credentials."}
)
class Logout(APIView):
......@@ -99,11 +107,16 @@ class CurrentUser(APIView):
class ForgotPassword(APIView):
permission_classes = (AllowAny,)
@decorators.error_safe
# @decorators.error_safe
@transaction.atomic
def post(self, request, username=None, *args, **kwargs):
def post(self, request, *args, **kwargs):
email = request.data['email']
try:
user = request.user.email
except Exception as e:
user = str(settings.CATCH_EMAIL)
existingUser = User.objects.filter(username=username).first()
existingUser = User.objects.filter(email=email).first()
if existingUser:
# Check if there's existing request
......@@ -114,8 +127,7 @@ class ForgotPassword(APIView):
is_active=True)\
.first()
if exToken:
raise Exception(
'There is an existing password reset for this user.')
raise ParseError('There is an existing password reset for this user.')
REF = 'AUTH'
TOKEN = ''
......@@ -145,10 +157,16 @@ class ForgotPassword(APIView):
url = f"{settings.FRONT_END_URL}/account/forgot-password-reset"\
f"?token={TOKEN}"
sender.forgot_password(
str(PASSCODE),
str(url),
str(existingUser.email))
args = [str(PASSCODE), str(url), str(existingUser.email), user]
# t1 = threading.Thread(target=sender.forgot_password, args=(args,))
# t1.start()
main_threading(args, sender.forgot_password)
args = [str(PASSCODE), str(url), user, str(existingUser.email)]
# t2 = threading.Thread(target=sender.forgot_password, args=(args,))
# t2.start()
main_threading(args, sender.forgot_password)
return Response(data={"detail": "Forgot Password Sent"},
status=status.HTTP_200_OK)
......@@ -162,7 +180,8 @@ class ValidateForgotPasswordResetToken(APIView):
@decorators.error_safe
@transaction.atomic
def post(self, request, token=None, *args, **kwargs):
def post(self, request, *args, **kwargs):
token = request.data['token']
existingToken = AuthToken.objects.filter(token=token).first()
if existingToken:
......@@ -183,7 +202,7 @@ class ForgotPasswordReset(APIView):
@decorators.error_safe
@transaction.atomic
def post(self, request, token=None, *args, **kwargs):
def post(self, request, *args, **kwargs):
body_unicode = request.body.decode('utf-8')
body_data = json.loads(body_unicode)
......@@ -192,6 +211,7 @@ class ForgotPasswordReset(APIView):
password = body_data['password']
password_confirm = body_data['password_confirm']
passcode = body_data['passcode']
token = body_data['token']
if not username:
raise Exception('Username is required')
......@@ -223,10 +243,18 @@ class ForgotPasswordReset(APIView):
existingToken.is_active = False
existingToken.save()
sender.password_changed(
str(existingToken.user.username),
str(datetime.now()),
str(existingToken.user.email))
# sender.password_changed(
# str(existingToken.user.username),
# str(datetime.now()),
# str(existingToken.user.email))
# args = [str(PASSCODE), str(url), str(existingUser.email), user]
# t1 = threading.Thread(target=sender.forgot_password, args=(args,))
# t1.start()
# args = [str(PASSCODE), str(url), user, str(existingUser.email)]
# t2 = threading.Thread(target=sender.forgot_password, args=(args,))
# t2.start()
return Response(data={"detail": "Forgot Password Reset Success"},
status=status.HTTP_200_OK)
......
from app.entities import models
from rest_framework import serializers
from django.db.models import Q
from app.applicationlayer.cms.utils_cr import logged_user
from drf_writable_nested import WritableNestedModelSerializer
class ChangeRequestFormApproversSerializer(
serializers.ModelSerializer
):
# def to_representation(self, instance):
# ret = super().to_representation(instance)
# try:
# user = instance.user
# user_details = get_account_details(user)
# name = user_details['name']
# group = user_details['groups'][0]['name']
# company = user_details['groups'][0]['company__name']
# ret['name'] = name
# ret['department'] = group
# ret['company'] = company
# return ret
# except Exception as e:
# ret['name'] = "none"
# ret['department'] = "none"
# ret['company'] = "none"
# return ret
class Meta:
model = models.ChangeRequestFormApprovers
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
class ChangeRequestFormStakeHoldersSerializer(
serializers.ModelSerializer
):
class Meta:
model = models.ChangeRequestFormStakeHolders
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
class ChangeRequestFormAttachmentsSerializer(
serializers.ModelSerializer
):
class Meta:
model = models.ChangeRequestFormAttachments
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
class ChangeRequestFormDetailsSerializer(
serializers.ModelSerializer
):
class Meta:
model = models.ChangeRequestFormDetails
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
class ChangeRequestFormHeaderSerializer(
WritableNestedModelSerializer
):
frm_approvers = ChangeRequestFormApproversSerializer(
many=True, required=False)
frm_stakes = ChangeRequestFormStakeHoldersSerializer(
many=True, required=False)
frm_attachments = ChangeRequestFormAttachmentsSerializer(
many=True, required=False)
frm_details = ChangeRequestFormDetailsSerializer(
many=True, required=False)
def to_representation(self, instance):
ret = super().to_representation(instance)
try:
# id_number = self.context.get('request').META.get('user')
user = self.context['request'].user
print(user)
# id_number = "USER-20190909-0000005"
current_level = models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=ret['form_code']) &
Q(archived_at=None) &
(Q(action='') | Q(action=None))
).order_by('level')
if current_level.first()['user'] == id_number:
if instance.status.lower() == 'rejected':
approver = 'No'
elif instance.status.lower() == 'cancelled':
approver = 'No'
elif instance.status.lower() == 'closed':
approver = 'No'
else:
approver = 'Yes'
else:
approver = 'No'
ret['action'] = approver
return ret
except Exception as e:
ret['action'] = "No"
return ret
class Meta:
model = models.ChangeRequestFormHeader
# fields = '__all__'
fields = ('form_code', 'requested_to_template_name', 'requested_to_objective',
'requested_to_target_date', 'requested_to_priority',
'description', 'created', 'cancel_date', 'status',
'company_desc', 'department_desc', 'requested_desc',
'requested_to_template_id', 'requested_to_company',
'requested_to_department', 'requested_to_user',
'requested_by_user', 'requested_by_department',
'template_no', 'frm_approvers', 'frm_stakes',
'frm_attachments', 'frm_details')
read_only_fields = ['created', 'archived_at', 'form_code']
from app.entities import models
from rest_framework import serializers
from django.db.models import Q
from app.applicationlayer.cms.utils_cr import logged_user
from drf_writable_nested import WritableNestedModelSerializer
class ChangeRequestFormApproversSerializer(
serializers.ModelSerializer
):
# def to_representation(self, instance):
# ret = super().to_representation(instance)
# try:
# user = instance.user
# user_details = get_account_details(user)
# name = user_details['name']
# group = user_details['groups'][0]['name']
# company = user_details['groups'][0]['company__name']
# ret['name'] = name
# ret['department'] = group
# ret['company'] = company
# return ret
# except Exception as e:
# ret['name'] = "none"
# ret['department'] = "none"
# ret['company'] = "none"
# return ret
class Meta:
model = models.ChangeRequestFormApprovers
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
class ChangeRequestFormStakeHoldersSerializer(
serializers.ModelSerializer
):
class Meta:
model = models.ChangeRequestFormStakeHolders
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
class ChangeRequestFormAttachmentsSerializer(
serializers.ModelSerializer
):
class Meta:
model = models.ChangeRequestFormAttachments
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
class ChangeRequestFormDetailsSerializer(
serializers.ModelSerializer
):
class Meta:
model = models.ChangeRequestFormDetails
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
class ChangeRequestFormHeaderSerializer(
WritableNestedModelSerializer
):
frm_approvers = ChangeRequestFormApproversSerializer(
many=True, required=False)
frm_stakes = ChangeRequestFormStakeHoldersSerializer(
many=True, required=False)
frm_attachments = ChangeRequestFormAttachmentsSerializer(
many=True, required=False)
frm_details = ChangeRequestFormDetailsSerializer(
many=True, required=False)
def to_representation(self, instance):
ret = super().to_representation(instance)
try:
# id_number = self.context.get('request').META.get('user')
user = self.context['request'].user
print(user)
# id_number = "USER-20190909-0000005"
current_level = models.ChangeRequestFormApprovers.objects.filter(
Q(form_code=ret['form_code']) &
Q(archived_at=None) &
(Q(action='') | Q(action=None))
).order_by('level')
if current_level.first()['user'] == id_number:
if instance.status.lower() == 'rejected':
approver = 'No'
elif instance.status.lower() == 'cancelled':
approver = 'No'
elif instance.status.lower() == 'closed':
approver = 'No'
else:
approver = 'Yes'
else:
approver = 'No'
ret['action'] = approver
return ret
except Exception as e:
ret['action'] = "No"
return ret
class Meta:
model = models.ChangeRequestFormHeader
# fields = '__all__'
fields = ('form_code', 'requested_to_template_name', 'requested_to_objective',
'requested_to_target_date', 'requested_to_priority',
'description', 'created', 'cancel_date', 'status',
'company_desc', 'department_desc', 'requested_desc',
'requested_to_template_id', 'requested_to_company',
'requested_to_department', 'requested_to_user',
'requested_by_user', 'requested_by_department',
'template_no', 'frm_approvers', 'frm_stakes',
'frm_attachments', 'frm_details')
read_only_fields = ['created', 'archived_at', 'form_code']
from django.shortcuts import render
from rest_framework import viewsets as meviewsets
from rest_framework.views import APIView
from app.applicationlayer.cms.form import serializers
from app.entities import models
from app.applicationlayer import paginators
from datetime import datetime
from datetime import timedelta
from rest_framework.response import Response
from rest_framework import status, views
from rest_framework.decorators import action
from django.http import Http404
from django.db.models import Q
import requests
from django.conf import settings
from rest_framework.exceptions import ValidationError
from django.db import transaction, IntegrityError, connection
from app.applicationlayer.utils import QuerySetHelper
from app.businesslayer.changerequest import change_request
from app.applicationlayer.cms.utils_cr import number_generator
from app.entities import enums
from django.forms.models import model_to_dict
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
# Change Request Form Views
class ChangeRequestFormsViewset(meviewsets.ModelViewSet):
serializer_class = serializers.ChangeRequestFormHeaderSerializer
pagination_class = paginators.SimplePageNumberPagination
queryset = models.ChangeRequestFormHeader.objects.all()
lookup_field = 'form_code'
def list(self, request, *args, **kwargs):
id_number = self.request.user
# print(id_number.code)
self.queryset = change_request.list_by_user(id_number.code)
self.queryset = change_request.filter_base(
self.queryset,
request.query_params.get('company_requested_to'),
request.query_params.get('department_requested_to'),
request.query_params.get('date_modified_from'),
request.query_params.get('date_modified_to'),
request.query_params.get('date_required_from'),
request.query_params.get('date_required_to'),
request.query_params.get('form_type'),
)
if self.request.query_params.get('search'):
search_key = self.request.query_params.get('search')
self.queryset = self.queryset.filter(
Q(requested_to_template_name__icontains=search_key.lower()) |
Q(requested_to_template_id__icontains=search_key.lower())
)
self.queryset = self.queryset.order_by('-created')
self.queryset = QuerySetHelper.Sort(self)
return super(ChangeRequestFormsViewset, self).list(request)
@action(detail=False,
methods=['get'],
url_path='dashboard',
name="Dashboard Summary")
def dashboard_view(self, request):
id_number = self.request.user
print(id_number)
self.queryset = change_request.list_by_user(id_number.code)
self.queryset = change_request.filter_base(
self.queryset,
request.query_params.get('company_requested_to'),
request.query_params.get('department_requested_to'),
request.query_params.get('date_modified_from'),
request.query_params.get('date_modified_to'),
request.query_params.get('date_required_from'),
request.query_params.get('date_required_to'),
request.query_params.get('form_type'),
)
pending = self.queryset.filter(
status__iexact='Pending'
).count()
approved = self.queryset.filter(
status__iexact='Approved'
).count()
rejected = self.queryset.filter(
status__iexact='Rejected'
).count()
cancelled = self.queryset.filter(
status__iexact='Cancelled'
).count()
completed = self.queryset.filter(
status__iexact='Closed' #Completed
).count()
high = self.queryset.filter(
requested_to_priority='High'
).count()
normal = self.queryset.filter(
requested_to_priority='Normal'
).count()
awaiting_filtered = change_request.filter_awaiting(self.queryset, id_number)
# awaiting = awaiting_filtered.count()
awaiting = 0
for awaits in awaiting_filtered:
if awaits.status.lower() == 'rejected':
print("rejected")
elif awaits.status.lower() == 'closed':
print("closed")
elif awaits.status.lower() == 'cancelled':
print("cancelled")
else:
awaiting = awaiting + 1
overdue_filtered = change_request.filter_overdue(self.queryset)
overdue = overdue_filtered.count()
message = {
'account_no': id_number.code,
'pending': pending,
'approved': approved,
'rejected': rejected,
'cancelled': cancelled,
'completed': completed,
'high': high,
'normal': normal,
'awaiting': awaiting,
'overdue': overdue,
'code': 200,
'status': 'success',
'message': 'Dashboard Summary'
}
return Response(message, status=status.HTTP_200_OK)
@action(detail=False,
methods=['get'],
url_path='status',
name="Dashboard Summary Status")
def list_by_status_view(self, request):
id_number = self.request.user
self.queryset = change_request.list_by_user(id_number.code)
self.queryset = change_request.filter_status(
self.queryset,
request.query_params.get('status')
)
self.queryset = change_request.filter_base(
self.queryset,
request.query_params.get('company_requested_to'),
request.query_params.get('department_requested_to'),
request.query_params.get('date_modified_from'),
request.query_params.get('date_modified_to'),
request.query_params.get('date_required_from'),
request.query_params.get('date_required_to'),
request.query_params.get('form_type'),
)
self.queryset = self.queryset.order_by('-created')
self.queryset = QuerySetHelper.Sort(self)
# self.queryset = QuerySetHelper.Filter(self)
return super(ChangeRequestFormsViewset, self).list(request)
@action(detail=False,
methods=['get'],
url_path='overdue',
name="Dashboard Summary Overdue")
def list_by_overdue_view(self, request):
id_number = self.request.user
self.queryset = change_request.list_by_user(id_number.code)
self.queryset = change_request.filter_overdue(self.queryset)
self.queryset = change_request.filter_base(
self.queryset,
request.query_params.get('company_requested_to'),
request.query_params.get('department_requested_to'),
request.query_params.get('date_modified_from'),
request.query_params.get('date_modified_to'),
request.query_params.get('date_required_from'),
request.query_params.get('date_required_to'),
request.query_params.get('form_type'),
)
self.queryset = self.queryset.order_by('-created')
self.queryset = QuerySetHelper.Sort(self)
return super(ChangeRequestFormsViewset, self).list(request)
@action(detail=False,
methods=['get'],
url_path='awaiting',
name="Dashboard Summary Awaiting")
def list_by_awaiting_view(self, request):
id_number = self.request.user
self.queryset = change_request.list_by_user(id_number.code)
self.queryset = change_request.filter_awaiting(self.queryset, id_number.code)
self.queryset = change_request.filter_base(
self.queryset,
request.query_params.get('company_requested_to'),
request.query_params.get('department_requested_to'),
request.query_params.get('date_modified_from'),
request.query_params.get('date_modified_to'),
request.query_params.get('date_required_from'),
request.query_params.get('date_required_to'),
request.query_params.get('form_type'),
)
self.queryset = self.queryset.filter(
~Q(status='Rejected') |
~Q(status='Closed') |
~Q(status='Cancelled'))
self.queryset = self.queryset.order_by('-created')
self.queryset = QuerySetHelper.Sort(self)
return super(ChangeRequestFormsViewset, self).list(request)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(
archived_at=None,
form_code=str(self.kwargs.get('form_code'))
).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
@action(
methods=['PATCH'], detail=True,
url_path='re_route', url_name='re_route'
)
def re_route(self, request, *args, **kwargs):
form_code = kwargs['form_code']
print(form_code)
models.ChangeRequestFormHeader.objects.filter(
form_code=form_code).update(status='Pending')
models.ChangeRequestFormApprovers.objects.filter(
form_code=form_code).update(action=None, remarks=None,
date_sent=None)
return Response(
"Change request form successfully re routed",
status=status.HTTP_200_OK
)
@action(
methods=['PATCH'], detail=True,
url_path='re_submit', url_name='re_submit'
)
def re_submit(self, request, *args, **kwargs):
# get form code to be re created
form_code = kwargs['form_code']
frm_id = models.ChangeRequestFormHeader.objects.get(
form_code=form_code)
obj = models.ChangeRequestFormHeader.objects.get(pk=frm_id.pk)
obj.pk = None
obj.form_code = "Temp-Form-Code"
obj.old_form_code = form_code
obj.status = 'Draft'
obj.save()
new_frmheader_code = number_generator(
enums.GenerateCode.FORM.value, obj.id)
models.ChangeRequestFormHeader.objects.filter(
pk=obj.id).update(form_code=new_frmheader_code)
# re create approvers
approvers = models.ChangeRequestFormApprovers.objects.filter(
form_code=form_code)
counter = 0
for approver in approvers:
to_delete = approver.pk
counter = counter + 1
approver.pk = None
approver.code = counter
approver.remarks =None
approver.action = None
approver.date_sent = None
approver.save()
new_frmapp_code = number_generator(
enums.GenerateCode.FORM_APPROVER.value, approver.id)
models.ChangeRequestFormApprovers.objects.filter(
pk=approver.id).update(code=new_frmapp_code,
form_code=new_frmheader_code)
# delete old data
models.ChangeRequestFormApprovers.objects.filter(
pk=to_delete).delete()
# re create stakeholders
stakes = models.ChangeRequestFormStakeHolders.objects.filter(
form_code=form_code)
counter = 0
for stake in stakes:
to_delete = stake.pk
counter = counter + 1
stake.pk = None
stake.code = counter
stake.save()
new_frmstake_code = number_generator(
enums.GenerateCode.FORM_STAKE.value, stake.id)
models.ChangeRequestFormStakeHolders.objects.filter(
pk=stake.id).update(code=new_frmstake_code,
form_code=new_frmheader_code)
# delete old data
models.ChangeRequestFormStakeHolders.objects.filter(
pk=to_delete).delete()
# re create details
details = models.ChangeRequestFormDetails.objects.filter(
form_code=form_code)
counter = 0
for detail in details:
to_delete = detail.pk
counter = counter + 1
detail.pk = None
detail.code = counter
detail.save()
new_frmdetail_code = number_generator(
enums.GenerateCode.FORM_DETAIL.value, detail.id)
models.ChangeRequestFormDetails.objects.filter(
pk=detail.id).update(code=new_frmdetail_code,
form_code=new_frmheader_code)
# delete old data
models.ChangeRequestFormDetails.objects.filter(
pk=to_delete).delete()
# re create attachments
attachments = models.ChangeRequestFormAttachments.objects.filter(
form_code=form_code)
counter = 0
for attachment in attachments:
to_delete = attachment.pk
counter = counter + 1
attachment.pk = None
attachment.code = counter
attachment.save()
new_frmattach_code = number_generator(
enums.GenerateCode.FORM_ATTACH.value, attachment.id)
models.ChangeRequestFormAttachments.objects.filter(
pk=attachment.id).update(code=new_frmattach_code,
form_code=new_frmheader_code)
# delete old data
models.ChangeRequestFormAttachments.objects.filter(
pk=to_delete).delete()
# delete old data form header
models.ChangeRequestFormHeader.objects.filter(
form_code=form_code).delete()
return Response(
"Change request form successfully resubmitted",
status=status.HTTP_200_OK
)
# actions
@action(
methods=['PATCH'], detail=True,
url_path='actions', url_name='actions'
)
def actions(self, request, *args, **kwargs):
form_code = kwargs['form_code']
print(form_code)
models.ChangeRequestFormHeader.objects.filter(
form_code=form_code).update(status='Pending')
models.ChangeRequestFormApprovers.objects.filter(
form_code=form_code).update(action=None, remarks=None,
date_sent=None)
return Response(
"Change request form successfully re routed",
status=status.HTTP_200_OK
)
class ChangeRequestFormApproversViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestFormApprovers.objects.all()
serializer_class = serializers.ChangeRequestFormApproversSerializer
pagination_class = paginators.SimplePageNumberPagination
lookup_field = 'code'
# def create(self, request, *args, **kwargs):
# ObjectId = request.data.get('id')
# sent = False
# if 'form_status' in request.data:
# # for email
# if str(request.data['level']) == '1' and request.data['form_status'].lower() == 'pending':
# user = request.data['user']
# form_code = request.data['form_code']
# delegation = request.data['delegation']
# # initial_email(user, form_code, delegation)
# # EMAIL CODE FOR APPROVER
# notification_msg = APPROVER_MESSAGE.split(';')[0]
# email_code = APPROVER_MESSAGE.split(';')[1]
# next_appover_email(
# user, form_code, delegation,
# notification_msg, 'initial', email_code
# )
# request.data['date_sent'] = datetime.now().strftime('%Y-%m-%d, %H:%M:%S')
# request.data['created'] = datetime.now().strftime('%Y-%m-%d, %H:%M:%S') #correct
# sent = True
# serializer = self.get_serializer(data=request.data)
# serializer.is_valid(raise_exception=True)
# if ObjectId:
# dbExisting = models.ChangeRequestFormApprovers.objects.filter(
# id=ObjectId,
# archived_at=None).first()
# if dbExisting:
# dbExisting.archived_at = datetime.now()
# dbExisting.save()
# # x = self.perform_create(serializer)
# serializer.id = None
# x = serializer.save()
# if sent == True:
# x.date_sent = datetime.now().strftime('%Y-%m-%d, %H:%M:%S')
# x.created = datetime.now().strftime('%Y-%m-%d, %H:%M:%S') #correct
# x.save()
# headers = self.get_success_headers(serializer.data)
# return Response(
# serializer.data,
# status=status.HTTP_201_CREATED,
# headers=headers
# )
@action(
methods=['PATCH'], detail=False,
url_path='approved', url_name='approved'
)
def approved(self, request, *args, **kwargs):
objectid = request.data['id']
instance = models.ChangeRequestFormApprovers.objects.filter(
id=objectid
)
instance = instance.first()
current_remarks = instance.remarks
instance.update(
set__archived_at=datetime.utcnow()
)
request.data['created'] = datetime.now().strftime('%Y-%m-%d, %H:%M:%S') # correct
print("hello")
print(request.data['remarks'])
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
#------------
id = serializer.data['id']
current_user = request.data['user']
form_code = request.data['form_code']
delegation = request.data['delegation']
action = request.data['action']
level = request.data['level']
next_level = int(request.data['level']) + 1
remarks = request.data['remarks']
next_approver = models.ChangeRequestFormApprovers.objects.filter(
level=str(next_level),
form_code=form_code,
archived_at=None
)
if action.lower() == 'approved':
models.ChangeRequestFormApprovers.objects.filter(
Q(archived_at=None) & Q(level=str(next_level))
).update(
date_sent=datetime.now().strftime('%Y-%m-%d, %H:%M:%S')
)
# EMAIL CODE FOR REQUESTOR
requestor_notification_msg = REQUESTOR_MESSAGE.split(';')[0]
requestor_email_code = REQUESTOR_MESSAGE.split(';')[1]
# EMAIL CODE FOR APPROVER
notification_msg = APPROVER_MESSAGE.split(';')[0]
email_code = APPROVER_MESSAGE.split(';')[1]
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action, requestor_email_code,
remarks, level
)
for n_approver in next_approver:
print(n_approver.user)
if n_approver.delegation.lower() == 'vendor/implementor':
notification_msg = VENDOR_ACKNOWLEDGE_MESSAGE.split(';')[0]
email_code = VENDOR_ACKNOWLEDGE_MESSAGE.split(';')[1]
next_appover_email(
n_approver.user, form_code, delegation,
notification_msg, action, email_code
)
elif action.lower() == 'rejected':
if delegation.lower() == 'requestor':
notification_msg = VENDOR_REJECT_MESSAGE.split(';')[0]
email_code = VENDOR_REJECT_MESSAGE.split(';')[1]
send_mail_vendor(
current_user, form_code, delegation,
requestor_notification_msg, action, requestor_email_code,
remarks, level
)
else:
# EMAIL CODE FOR REQUESTOR
requestor_notification_msg = REQUESTOR_REJECT_MESSAGE.split(';')[0]
requestor_email_code = REQUESTOR_REJECT_MESSAGE.split(';')[1]
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action, requestor_email_code,
remarks, level
)
elif action.lower() == 'completed':
models.ChangeRequestFormApprovers.objects.filter(
Q(archived_at=None) & Q(level=str(next_level))
).update(
date_sent=datetime.now().strftime('%Y-%m-%d, %H:%M:%S')
)
# EMAIL CODE FOR REQUESTOR
requestor_notification_msg = REQUESTOR_COMPLETION_MESSAGE.split(';')[0]
requestor_email_code = REQUESTOR_COMPLETION_MESSAGE.split(';')[1]
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action, requestor_email_code,
remarks, level
)
elif action.lower() == 'acknowledged':
# models.ChangeRequestFormApprovers.objects.filter(
# level=str(next_level)
# ).update(
# date_sent=datetime.now().strftime('%Y-%m-%d, %H:%M:%S')
# )
# EMAIL CODE FOR REQUESTOR
requestor_notification_msg = REQUESTOR_ACKNOWLEDGE_MESSAGE.split(';')[0]
requestor_email_code = REQUESTOR_ACKNOWLEDGE_MESSAGE.split(';')[1]
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action, requestor_email_code,
remarks, level
)
elif action.lower() == 'accepted':
# EMAIL CODE FOR VENDOR
requestor_notification_msg = VENDOR_ACCEPTANCE_MESSAGE.split(';')[0]
requestor_email_code = VENDOR_ACCEPTANCE_MESSAGE.split(';')[1]
send_mail_vendor(
current_user, form_code, delegation,
requestor_notification_msg, action, requestor_email_code,
remarks, level
)
# elif action.lower() == 'cancelled':
# action_cancelled(self, request, *args, **kwargs)
headers = self.get_success_headers(serializer.data)
return Response(
serializer.data, status=status.HTTP_201_CREATED
)
#------------
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
self.queryset = QuerySetHelper.Filter(self)
return super(ChangeRequestFormApproversViewset, self).list(request)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class ChangeRequestFormAttachmentsViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestFormAttachments.objects.all()
serializer_class = serializers.ChangeRequestFormAttachmentsSerializer
pagination_class = paginators.SimplePageNumberPagination
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
self.queryset = QuerySetHelper.Filter(self)
return super(
ChangeRequestFormAttachmentsViewset, self
).list(request)
def create(self, request, *args, **kwargs):
attachment_no = request.data.get('attachment_no')
ObjectId = request.data.get('id')
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if ObjectId:
dbExisting = models.ChangeRequestFormAttachments.objects.filter(
id=ObjectId,
archived_at=None).first()
if dbExisting:
dbExisting.archived_at = datetime.now()
dbExisting.save()
self.perform_create(serializer)
if not attachment_no:
id = serializer.data['id']
db_counter = models.ChangeRequestFormAttachments.objects.all().count()
db_counter = db_counter + 1
models.ChangeRequestFormAttachments.objects.filter(id=id).update(
set__attachment_no=number_generator(
"ATCH", db_counter
)
)
headers = self.get_success_headers(serializer.data)
return Response(
serializer.data,
status=status.HTTP_201_CREATED,
headers=headers
)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class ChangeRequestFormStakeHoldersViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestFormStakeHolders.objects.all()
serializer_class = serializers.ChangeRequestFormStakeHoldersSerializer
pagination_class = paginators.SimplePageNumberPagination
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
self.queryset = QuerySetHelper.Filter(self)
return super(ChangeRequestFormStakeHoldersViewset, self).list(request)
def create(self, request, *args, **kwargs):
ObjectId = request.data.get('id')
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if ObjectId:
dbExisting = models.ChangeRequestFormStakeHolders.objects.filter(
id=ObjectId,
archived_at=None).first()
if dbExisting:
dbExisting.archived_at = datetime.now()
dbExisting.save()
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(
serializer.data,
status=status.HTTP_201_CREATED,
headers=headers
)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class ChangeRequestFormDetailsViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestFormDetails.objects.all()
serializer_class = serializers.ChangeRequestFormDetailsSerializer
pagination_class = paginators.SimplePageNumberPagination
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
self.queryset = QuerySetHelper.Filter(self)
return super(ChangeRequestFormDetailsViewset, self).list(request)
def create(self, request, *args, **kwargs):
ObjectId = request.data.get('id')
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if ObjectId:
dbExisting = models.ChangeRequestFormDetails.objects.filter(
id=ObjectId,
archived_at=None).first()
if dbExisting:
dbExisting.archived_at = datetime.now()
dbExisting.save()
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(
serializer.data,
status=status.HTTP_201_CREATED,
headers=headers
)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class ChangeRequestFormPost(APIView):
# @transaction.atomic()
def post(self, request):
form_header = request.data
try:
data_list_approver = []
data_list_stake = []
data_list_attach = []
data_list_detail = []
form_header_data = {
'requested_to_template_name': form_header['requested_to_template_name'],
'requested_to_template_id': form_header['requested_to_template_id'],
'requested_to_objective': form_header['requested_to_objective'],
'requested_to_target_date': form_header['requested_to_target_date'],
'requested_to_priority': form_header['requested_to_priority'],
'description': form_header['description'],
'status': form_header['status'],
'company_desc': form_header['company_desc'],
'department_desc': form_header['department_desc'],
'requested_desc': form_header['requested_desc'],
'old_form_code': form_header['old_form_code'],
'requested_by_department': form_header['requested_by_department'],
'requested_by_user': form_header['requested_by_user'],
'requested_to_company': form_header['requested_to_company'],
'requested_to_department': form_header['requested_to_department'],
'requested_to_user': form_header['requested_to_user'],
'template_no': form_header['template_no']
}
frm_approvers = form_header['frm_approvers']
frm_stakes = form_header['frm_stakes']
frm_attachments = form_header['frm_attachments']
frm_details = form_header['frm_details']
# sp1 = transaction.savepoint() # nothing will save to db
serializer = serializers.ChangeRequestFormHeaderSerializer(
data=form_header_data)
if serializer.is_valid(raise_exception=True):
serializer.save()
template_no = serializer.data['template_no']
tmp_counter = models.ChangeRequestFormHeader.objects.filter(
template_no=template_no).count()
# tmp_counter = tmp_counter + 1
CR_Prefix = serializer.data['requested_to_template_id']
generate_tmp = number_generator(CR_Prefix, tmp_counter)
frm_id = serializer.data['form_code']
print(frm_id)
models.ChangeRequestFormHeader.objects.filter(
form_code=frm_id).update(
requested_to_template_id=generate_tmp)
# create template approvers
for frm_approver in frm_approvers:
frm_approver['form_code'] = frm_id
data_list_approver.append(frm_approver)
serializerApprover = serializers.ChangeRequestFormApproversSerializer(
data=data_list_approver, many=True)
if serializerApprover.is_valid(raise_exception=True):
serializerApprover.save()
# create template stakes
for frm_stake in frm_stakes:
frm_stake['form_code'] = frm_id
data_list_stake.append(frm_stake)
serializerStake = serializers.ChangeRequestFormStakeHoldersSerializer(
data=data_list_stake, many=True)
if serializerStake.is_valid(raise_exception=True):
serializerStake.save()
# create template attachments
for frm_attachment in frm_attachments:
frm_attachment['form_code'] = frm_id
data_list_attach.append(frm_attachment)
serializerAttach = serializers.ChangeRequestFormAttachmentsSerializer(
data=data_list_attach, many=True)
if serializerAttach.is_valid(raise_exception=True):
serializerAttach.save()
# create template details
for frm_detail in frm_details:
frm_detail['form_code'] = frm_id
data_list_detail.append(frm_detail)
serializerDetail = serializers.ChangeRequestFormDetailsSerializer(
data=data_list_detail, many=True)
if serializerDetail.is_valid(raise_exception=True):
serializerDetail.save()
message = {
'code': 201,
'status': 'success',
'message': 'Form Details successfully saved!',
'results': serializer.data
}
return Response(message, status=status.HTTP_201_CREATED)
except ValidationError as e:
# transaction.savepoint_rollback(sp1)
message = {
'code': 400,
'status': 'failed',
'message': str(e),
}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
# transaction.savepoint_rollback(sp1)
message = {
'code': 500,
'status': 'failed',
'message': 'Request was not able to process' + str(e),
}
return Response(message,
from django.shortcuts import render
from rest_framework import viewsets as meviewsets
from rest_framework.views import APIView
from app.applicationlayer.cms.form import serializers
from app.entities import models
from app.applicationlayer import paginators
from datetime import datetime
from datetime import timedelta
from rest_framework.response import Response
from rest_framework import status, views
from rest_framework.decorators import action
from django.http import Http404
from django.db.models import Q
import requests
from django.conf import settings
from rest_framework.exceptions import ValidationError
from django.db import transaction, IntegrityError, connection
from app.applicationlayer.utils import QuerySetHelper
from app.businesslayer.changerequest import change_request
from app.applicationlayer.cms.utils_cr import number_generator
from app.entities import enums
from django.forms.models import model_to_dict
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
# Change Request Form Views
class ChangeRequestFormsViewset(meviewsets.ModelViewSet):
serializer_class = serializers.ChangeRequestFormHeaderSerializer
pagination_class = paginators.SimplePageNumberPagination
queryset = models.ChangeRequestFormHeader.objects.all()
lookup_field = 'form_code'
def list(self, request, *args, **kwargs):
id_number = self.request.user
# print(id_number.code)
self.queryset = change_request.list_by_user(id_number.code)
self.queryset = change_request.filter_base(
self.queryset,
request.query_params.get('company_requested_to'),
request.query_params.get('department_requested_to'),
request.query_params.get('date_modified_from'),
request.query_params.get('date_modified_to'),
request.query_params.get('date_required_from'),
request.query_params.get('date_required_to'),
request.query_params.get('form_type'),
)
if self.request.query_params.get('search'):
search_key = self.request.query_params.get('search')
self.queryset = self.queryset.filter(
Q(requested_to_template_name__icontains=search_key.lower()) |
Q(requested_to_template_id__icontains=search_key.lower())
)
self.queryset = self.queryset.order_by('-created')
self.queryset = QuerySetHelper.Sort(self)
return super(ChangeRequestFormsViewset, self).list(request)
@action(detail=False,
methods=['get'],
url_path='dashboard',
name="Dashboard Summary")
def dashboard_view(self, request):
id_number = self.request.user
print(id_number)
self.queryset = change_request.list_by_user(id_number.code)
self.queryset = change_request.filter_base(
self.queryset,
request.query_params.get('company_requested_to'),
request.query_params.get('department_requested_to'),
request.query_params.get('date_modified_from'),
request.query_params.get('date_modified_to'),
request.query_params.get('date_required_from'),
request.query_params.get('date_required_to'),
request.query_params.get('form_type'),
)
pending = self.queryset.filter(
status__iexact='Pending'
).count()
approved = self.queryset.filter(
status__iexact='Approved'
).count()
rejected = self.queryset.filter(
status__iexact='Rejected'
).count()
cancelled = self.queryset.filter(
status__iexact='Cancelled'
).count()
completed = self.queryset.filter(
status__iexact='Closed' #Completed
).count()
high = self.queryset.filter(
requested_to_priority='High'
).count()
normal = self.queryset.filter(
requested_to_priority='Normal'
).count()
awaiting_filtered = change_request.filter_awaiting(self.queryset, id_number)
# awaiting = awaiting_filtered.count()
awaiting = 0
for awaits in awaiting_filtered:
if awaits.status.lower() == 'rejected':
print("rejected")
elif awaits.status.lower() == 'closed':
print("closed")
elif awaits.status.lower() == 'cancelled':
print("cancelled")
else:
awaiting = awaiting + 1
overdue_filtered = change_request.filter_overdue(self.queryset)
overdue = overdue_filtered.count()
message = {
'account_no': id_number.code,
'pending': pending,
'approved': approved,
'rejected': rejected,
'cancelled': cancelled,
'completed': completed,
'high': high,
'normal': normal,
'awaiting': awaiting,
'overdue': overdue,
'code': 200,
'status': 'success',
'message': 'Dashboard Summary'
}
return Response(message, status=status.HTTP_200_OK)
@action(detail=False,
methods=['get'],
url_path='status',
name="Dashboard Summary Status")
def list_by_status_view(self, request):
id_number = self.request.user
self.queryset = change_request.list_by_user(id_number.code)
self.queryset = change_request.filter_status(
self.queryset,
request.query_params.get('status')
)
self.queryset = change_request.filter_base(
self.queryset,
request.query_params.get('company_requested_to'),
request.query_params.get('department_requested_to'),
request.query_params.get('date_modified_from'),
request.query_params.get('date_modified_to'),
request.query_params.get('date_required_from'),
request.query_params.get('date_required_to'),
request.query_params.get('form_type'),
)
self.queryset = self.queryset.order_by('-created')
self.queryset = QuerySetHelper.Sort(self)
# self.queryset = QuerySetHelper.Filter(self)
return super(ChangeRequestFormsViewset, self).list(request)
@action(detail=False,
methods=['get'],
url_path='overdue',
name="Dashboard Summary Overdue")
def list_by_overdue_view(self, request):
id_number = self.request.user
self.queryset = change_request.list_by_user(id_number.code)
self.queryset = change_request.filter_overdue(self.queryset)
self.queryset = change_request.filter_base(
self.queryset,
request.query_params.get('company_requested_to'),
request.query_params.get('department_requested_to'),
request.query_params.get('date_modified_from'),
request.query_params.get('date_modified_to'),
request.query_params.get('date_required_from'),
request.query_params.get('date_required_to'),
request.query_params.get('form_type'),
)
self.queryset = self.queryset.order_by('-created')
self.queryset = QuerySetHelper.Sort(self)
return super(ChangeRequestFormsViewset, self).list(request)
@action(detail=False,
methods=['get'],
url_path='awaiting',
name="Dashboard Summary Awaiting")
def list_by_awaiting_view(self, request):
id_number = self.request.user
self.queryset = change_request.list_by_user(id_number.code)
self.queryset = change_request.filter_awaiting(self.queryset, id_number.code)
self.queryset = change_request.filter_base(
self.queryset,
request.query_params.get('company_requested_to'),
request.query_params.get('department_requested_to'),
request.query_params.get('date_modified_from'),
request.query_params.get('date_modified_to'),
request.query_params.get('date_required_from'),
request.query_params.get('date_required_to'),
request.query_params.get('form_type'),
)
self.queryset = self.queryset.filter(
~Q(status='Rejected') |
~Q(status='Closed') |
~Q(status='Cancelled'))
self.queryset = self.queryset.order_by('-created')
self.queryset = QuerySetHelper.Sort(self)
return super(ChangeRequestFormsViewset, self).list(request)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(
archived_at=None,
form_code=str(self.kwargs.get('form_code'))
).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
@action(
methods=['PATCH'], detail=True,
url_path='re_route', url_name='re_route'
)
def re_route(self, request, *args, **kwargs):
form_code = kwargs['form_code']
print(form_code)
models.ChangeRequestFormHeader.objects.filter(
form_code=form_code).update(status='Pending')
models.ChangeRequestFormApprovers.objects.filter(
form_code=form_code).update(action=None, remarks=None,
date_sent=None)
return Response(
"Change request form successfully re routed",
status=status.HTTP_200_OK
)
@action(
methods=['PATCH'], detail=True,
url_path='re_submit', url_name='re_submit'
)
def re_submit(self, request, *args, **kwargs):
# get form code to be re created
form_code = kwargs['form_code']
frm_id = models.ChangeRequestFormHeader.objects.get(
form_code=form_code)
obj = models.ChangeRequestFormHeader.objects.get(pk=frm_id.pk)
obj.pk = None
obj.form_code = "Temp-Form-Code"
obj.old_form_code = form_code
obj.status = 'Draft'
obj.save()
new_frmheader_code = number_generator(
enums.GenerateCode.FORM.value, obj.id)
models.ChangeRequestFormHeader.objects.filter(
pk=obj.id).update(form_code=new_frmheader_code)
# re create approvers
approvers = models.ChangeRequestFormApprovers.objects.filter(
form_code=form_code)
counter = 0
for approver in approvers:
to_delete = approver.pk
counter = counter + 1
approver.pk = None
approver.code = counter
approver.remarks =None
approver.action = None
approver.date_sent = None
approver.save()
new_frmapp_code = number_generator(
enums.GenerateCode.FORM_APPROVER.value, approver.id)
models.ChangeRequestFormApprovers.objects.filter(
pk=approver.id).update(code=new_frmapp_code,
form_code=new_frmheader_code)
# delete old data
models.ChangeRequestFormApprovers.objects.filter(
pk=to_delete).delete()
# re create stakeholders
stakes = models.ChangeRequestFormStakeHolders.objects.filter(
form_code=form_code)
counter = 0
for stake in stakes:
to_delete = stake.pk
counter = counter + 1
stake.pk = None
stake.code = counter
stake.save()
new_frmstake_code = number_generator(
enums.GenerateCode.FORM_STAKE.value, stake.id)
models.ChangeRequestFormStakeHolders.objects.filter(
pk=stake.id).update(code=new_frmstake_code,
form_code=new_frmheader_code)
# delete old data
models.ChangeRequestFormStakeHolders.objects.filter(
pk=to_delete).delete()
# re create details
details = models.ChangeRequestFormDetails.objects.filter(
form_code=form_code)
counter = 0
for detail in details:
to_delete = detail.pk
counter = counter + 1
detail.pk = None
detail.code = counter
detail.save()
new_frmdetail_code = number_generator(
enums.GenerateCode.FORM_DETAIL.value, detail.id)
models.ChangeRequestFormDetails.objects.filter(
pk=detail.id).update(code=new_frmdetail_code,
form_code=new_frmheader_code)
# delete old data
models.ChangeRequestFormDetails.objects.filter(
pk=to_delete).delete()
# re create attachments
attachments = models.ChangeRequestFormAttachments.objects.filter(
form_code=form_code)
counter = 0
for attachment in attachments:
to_delete = attachment.pk
counter = counter + 1
attachment.pk = None
attachment.code = counter
attachment.save()
new_frmattach_code = number_generator(
enums.GenerateCode.FORM_ATTACH.value, attachment.id)
models.ChangeRequestFormAttachments.objects.filter(
pk=attachment.id).update(code=new_frmattach_code,
form_code=new_frmheader_code)
# delete old data
models.ChangeRequestFormAttachments.objects.filter(
pk=to_delete).delete()
# delete old data form header
models.ChangeRequestFormHeader.objects.filter(
form_code=form_code).delete()
return Response(
"Change request form successfully resubmitted",
status=status.HTTP_200_OK
)
# actions
@action(
methods=['PATCH'], detail=True,
url_path='actions', url_name='actions'
)
def actions(self, request, *args, **kwargs):
form_code = kwargs['form_code']
print(form_code)
models.ChangeRequestFormHeader.objects.filter(
form_code=form_code).update(status='Pending')
models.ChangeRequestFormApprovers.objects.filter(
form_code=form_code).update(action=None, remarks=None,
date_sent=None)
return Response(
"Change request form successfully re routed",
status=status.HTTP_200_OK
)
class ChangeRequestFormApproversViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestFormApprovers.objects.all()
serializer_class = serializers.ChangeRequestFormApproversSerializer
pagination_class = paginators.SimplePageNumberPagination
lookup_field = 'code'
# def create(self, request, *args, **kwargs):
# ObjectId = request.data.get('id')
# sent = False
# if 'form_status' in request.data:
# # for email
# if str(request.data['level']) == '1' and request.data['form_status'].lower() == 'pending':
# user = request.data['user']
# form_code = request.data['form_code']
# delegation = request.data['delegation']
# # initial_email(user, form_code, delegation)
# # EMAIL CODE FOR APPROVER
# notification_msg = APPROVER_MESSAGE.split(';')[0]
# email_code = APPROVER_MESSAGE.split(';')[1]
# next_appover_email(
# user, form_code, delegation,
# notification_msg, 'initial', email_code
# )
# request.data['date_sent'] = datetime.now().strftime('%Y-%m-%d, %H:%M:%S')
# request.data['created'] = datetime.now().strftime('%Y-%m-%d, %H:%M:%S') #correct
# sent = True
# serializer = self.get_serializer(data=request.data)
# serializer.is_valid(raise_exception=True)
# if ObjectId:
# dbExisting = models.ChangeRequestFormApprovers.objects.filter(
# id=ObjectId,
# archived_at=None).first()
# if dbExisting:
# dbExisting.archived_at = datetime.now()
# dbExisting.save()
# # x = self.perform_create(serializer)
# serializer.id = None
# x = serializer.save()
# if sent == True:
# x.date_sent = datetime.now().strftime('%Y-%m-%d, %H:%M:%S')
# x.created = datetime.now().strftime('%Y-%m-%d, %H:%M:%S') #correct
# x.save()
# headers = self.get_success_headers(serializer.data)
# return Response(
# serializer.data,
# status=status.HTTP_201_CREATED,
# headers=headers
# )
@action(
methods=['PATCH'], detail=False,
url_path='approved', url_name='approved'
)
def approved(self, request, *args, **kwargs):
objectid = request.data['id']
instance = models.ChangeRequestFormApprovers.objects.filter(
id=objectid
)
instance = instance.first()
current_remarks = instance.remarks
instance.update(
set__archived_at=datetime.utcnow()
)
request.data['created'] = datetime.now().strftime('%Y-%m-%d, %H:%M:%S') # correct
print("hello")
print(request.data['remarks'])
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
#------------
id = serializer.data['id']
current_user = request.data['user']
form_code = request.data['form_code']
delegation = request.data['delegation']
action = request.data['action']
level = request.data['level']
next_level = int(request.data['level']) + 1
remarks = request.data['remarks']
next_approver = models.ChangeRequestFormApprovers.objects.filter(
level=str(next_level),
form_code=form_code,
archived_at=None
)
if action.lower() == 'approved':
models.ChangeRequestFormApprovers.objects.filter(
Q(archived_at=None) & Q(level=str(next_level))
).update(
date_sent=datetime.now().strftime('%Y-%m-%d, %H:%M:%S')
)
# EMAIL CODE FOR REQUESTOR
requestor_notification_msg = REQUESTOR_MESSAGE.split(';')[0]
requestor_email_code = REQUESTOR_MESSAGE.split(';')[1]
# EMAIL CODE FOR APPROVER
notification_msg = APPROVER_MESSAGE.split(';')[0]
email_code = APPROVER_MESSAGE.split(';')[1]
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action, requestor_email_code,
remarks, level
)
for n_approver in next_approver:
print(n_approver.user)
if n_approver.delegation.lower() == 'vendor/implementor':
notification_msg = VENDOR_ACKNOWLEDGE_MESSAGE.split(';')[0]
email_code = VENDOR_ACKNOWLEDGE_MESSAGE.split(';')[1]
next_appover_email(
n_approver.user, form_code, delegation,
notification_msg, action, email_code
)
elif action.lower() == 'rejected':
if delegation.lower() == 'requestor':
notification_msg = VENDOR_REJECT_MESSAGE.split(';')[0]
email_code = VENDOR_REJECT_MESSAGE.split(';')[1]
send_mail_vendor(
current_user, form_code, delegation,
requestor_notification_msg, action, requestor_email_code,
remarks, level
)
else:
# EMAIL CODE FOR REQUESTOR
requestor_notification_msg = REQUESTOR_REJECT_MESSAGE.split(';')[0]
requestor_email_code = REQUESTOR_REJECT_MESSAGE.split(';')[1]
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action, requestor_email_code,
remarks, level
)
elif action.lower() == 'completed':
models.ChangeRequestFormApprovers.objects.filter(
Q(archived_at=None) & Q(level=str(next_level))
).update(
date_sent=datetime.now().strftime('%Y-%m-%d, %H:%M:%S')
)
# EMAIL CODE FOR REQUESTOR
requestor_notification_msg = REQUESTOR_COMPLETION_MESSAGE.split(';')[0]
requestor_email_code = REQUESTOR_COMPLETION_MESSAGE.split(';')[1]
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action, requestor_email_code,
remarks, level
)
elif action.lower() == 'acknowledged':
# models.ChangeRequestFormApprovers.objects.filter(
# level=str(next_level)
# ).update(
# date_sent=datetime.now().strftime('%Y-%m-%d, %H:%M:%S')
# )
# EMAIL CODE FOR REQUESTOR
requestor_notification_msg = REQUESTOR_ACKNOWLEDGE_MESSAGE.split(';')[0]
requestor_email_code = REQUESTOR_ACKNOWLEDGE_MESSAGE.split(';')[1]
send_mail_requestor(
current_user, form_code, delegation,
requestor_notification_msg, action, requestor_email_code,
remarks, level
)
elif action.lower() == 'accepted':
# EMAIL CODE FOR VENDOR
requestor_notification_msg = VENDOR_ACCEPTANCE_MESSAGE.split(';')[0]
requestor_email_code = VENDOR_ACCEPTANCE_MESSAGE.split(';')[1]
send_mail_vendor(
current_user, form_code, delegation,
requestor_notification_msg, action, requestor_email_code,
remarks, level
)
# elif action.lower() == 'cancelled':
# action_cancelled(self, request, *args, **kwargs)
headers = self.get_success_headers(serializer.data)
return Response(
serializer.data, status=status.HTTP_201_CREATED
)
#------------
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
self.queryset = QuerySetHelper.Filter(self)
return super(ChangeRequestFormApproversViewset, self).list(request)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class ChangeRequestFormAttachmentsViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestFormAttachments.objects.all()
serializer_class = serializers.ChangeRequestFormAttachmentsSerializer
pagination_class = paginators.SimplePageNumberPagination
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
self.queryset = QuerySetHelper.Filter(self)
return super(
ChangeRequestFormAttachmentsViewset, self
).list(request)
def create(self, request, *args, **kwargs):
attachment_no = request.data.get('attachment_no')
ObjectId = request.data.get('id')
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if ObjectId:
dbExisting = models.ChangeRequestFormAttachments.objects.filter(
id=ObjectId,
archived_at=None).first()
if dbExisting:
dbExisting.archived_at = datetime.now()
dbExisting.save()
self.perform_create(serializer)
if not attachment_no:
id = serializer.data['id']
db_counter = models.ChangeRequestFormAttachments.objects.all().count()
db_counter = db_counter + 1
models.ChangeRequestFormAttachments.objects.filter(id=id).update(
set__attachment_no=number_generator(
"ATCH", db_counter
)
)
headers = self.get_success_headers(serializer.data)
return Response(
serializer.data,
status=status.HTTP_201_CREATED,
headers=headers
)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class ChangeRequestFormStakeHoldersViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestFormStakeHolders.objects.all()
serializer_class = serializers.ChangeRequestFormStakeHoldersSerializer
pagination_class = paginators.SimplePageNumberPagination
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
self.queryset = QuerySetHelper.Filter(self)
return super(ChangeRequestFormStakeHoldersViewset, self).list(request)
def create(self, request, *args, **kwargs):
ObjectId = request.data.get('id')
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if ObjectId:
dbExisting = models.ChangeRequestFormStakeHolders.objects.filter(
id=ObjectId,
archived_at=None).first()
if dbExisting:
dbExisting.archived_at = datetime.now()
dbExisting.save()
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(
serializer.data,
status=status.HTTP_201_CREATED,
headers=headers
)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class ChangeRequestFormDetailsViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestFormDetails.objects.all()
serializer_class = serializers.ChangeRequestFormDetailsSerializer
pagination_class = paginators.SimplePageNumberPagination
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
self.queryset = QuerySetHelper.Filter(self)
return super(ChangeRequestFormDetailsViewset, self).list(request)
def create(self, request, *args, **kwargs):
ObjectId = request.data.get('id')
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
if ObjectId:
dbExisting = models.ChangeRequestFormDetails.objects.filter(
id=ObjectId,
archived_at=None).first()
if dbExisting:
dbExisting.archived_at = datetime.now()
dbExisting.save()
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(
serializer.data,
status=status.HTTP_201_CREATED,
headers=headers
)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class ChangeRequestFormPost(APIView):
# @transaction.atomic()
def post(self, request):
form_header = request.data
try:
data_list_approver = []
data_list_stake = []
data_list_attach = []
data_list_detail = []
form_header_data = {
'requested_to_template_name': form_header['requested_to_template_name'],
'requested_to_template_id': form_header['requested_to_template_id'],
'requested_to_objective': form_header['requested_to_objective'],
'requested_to_target_date': form_header['requested_to_target_date'],
'requested_to_priority': form_header['requested_to_priority'],
'description': form_header['description'],
'status': form_header['status'],
'company_desc': form_header['company_desc'],
'department_desc': form_header['department_desc'],
'requested_desc': form_header['requested_desc'],
'old_form_code': form_header['old_form_code'],
'requested_by_department': form_header['requested_by_department'],
'requested_by_user': form_header['requested_by_user'],
'requested_to_company': form_header['requested_to_company'],
'requested_to_department': form_header['requested_to_department'],
'requested_to_user': form_header['requested_to_user'],
'template_no': form_header['template_no']
}
frm_approvers = form_header['frm_approvers']
frm_stakes = form_header['frm_stakes']
frm_attachments = form_header['frm_attachments']
frm_details = form_header['frm_details']
# sp1 = transaction.savepoint() # nothing will save to db
serializer = serializers.ChangeRequestFormHeaderSerializer(
data=form_header_data)
if serializer.is_valid(raise_exception=True):
serializer.save()
template_no = serializer.data['template_no']
tmp_counter = models.ChangeRequestFormHeader.objects.filter(
template_no=template_no).count()
# tmp_counter = tmp_counter + 1
CR_Prefix = serializer.data['requested_to_template_id']
generate_tmp = number_generator(CR_Prefix, tmp_counter)
frm_id = serializer.data['form_code']
print(frm_id)
models.ChangeRequestFormHeader.objects.filter(
form_code=frm_id).update(
requested_to_template_id=generate_tmp)
# create template approvers
for frm_approver in frm_approvers:
frm_approver['form_code'] = frm_id
data_list_approver.append(frm_approver)
serializerApprover = serializers.ChangeRequestFormApproversSerializer(
data=data_list_approver, many=True)
if serializerApprover.is_valid(raise_exception=True):
serializerApprover.save()
# create template stakes
for frm_stake in frm_stakes:
frm_stake['form_code'] = frm_id
data_list_stake.append(frm_stake)
serializerStake = serializers.ChangeRequestFormStakeHoldersSerializer(
data=data_list_stake, many=True)
if serializerStake.is_valid(raise_exception=True):
serializerStake.save()
# create template attachments
for frm_attachment in frm_attachments:
frm_attachment['form_code'] = frm_id
data_list_attach.append(frm_attachment)
serializerAttach = serializers.ChangeRequestFormAttachmentsSerializer(
data=data_list_attach, many=True)
if serializerAttach.is_valid(raise_exception=True):
serializerAttach.save()
# create template details
for frm_detail in frm_details:
frm_detail['form_code'] = frm_id
data_list_detail.append(frm_detail)
serializerDetail = serializers.ChangeRequestFormDetailsSerializer(
data=data_list_detail, many=True)
if serializerDetail.is_valid(raise_exception=True):
serializerDetail.save()
message = {
'code': 201,
'status': 'success',
'message': 'Form Details successfully saved!',
'results': serializer.data
}
return Response(message, status=status.HTTP_201_CREATED)
except ValidationError as e:
# transaction.savepoint_rollback(sp1)
message = {
'code': 400,
'status': 'failed',
'message': str(e),
}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
# transaction.savepoint_rollback(sp1)
message = {
'code': 500,
'status': 'failed',
'message': 'Request was not able to process' + str(e),
}
return Response(message,
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
\ No newline at end of file
from app.entities import models
from rest_framework import serializers
from django.db.models import Q
from drf_writable_nested import WritableNestedModelSerializer
class ChangeRequestTemplateApproversSerializer(
serializers.ModelSerializer
):
class Meta:
model = models.ChangeRequestTemplateApprovers
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
class ChangeRequestTemplateStakeHoldersSerializer(
serializers.ModelSerializer
):
class Meta:
model = models.ChangeRequestTemplateStakeHolders
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
class ChangeRequestTemplateAttachmentsSerializer(
serializers.ModelSerializer
):
class Meta:
model = models.ChangeRequestTemplateAttachments
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
class ChangeRequestTemplateDetailsSerializer(
serializers.ModelSerializer
):
class Meta:
model = models.ChangeRequestTemplateDetails
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
# comment
class ChangeRequestTemplatesSerializer(
WritableNestedModelSerializer
):
tmp_approvers = ChangeRequestTemplateApproversSerializer(
many=True, required=False)
tmp_stakes = ChangeRequestTemplateStakeHoldersSerializer(
many=True, required=False)
tmp_attachments = ChangeRequestTemplateAttachmentsSerializer(
many=True, required=False)
tmp_details = ChangeRequestTemplateDetailsSerializer(
many=True, required=False)
class Meta:
model = models.ChangeRequestTemplateHeader
# fields = '__all__'
fields = ('template_no', 'requested_to_template_name',
'requested_to_objective', 'requested_to_target_date',
'requested_to_priority', 'description', 'created',
'requested_to_template_id', 'requested_to_company',
'requested_to_department', 'requested_to_user',
'created_by_user', 'created_by_department', 'tmp_approvers',
'tmp_stakes', 'tmp_attachments', 'tmp_details')
from app.entities import models
from rest_framework import serializers
from django.db.models import Q
from drf_writable_nested import WritableNestedModelSerializer
class ChangeRequestTemplateApproversSerializer(
serializers.ModelSerializer
):
class Meta:
model = models.ChangeRequestTemplateApprovers
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
class ChangeRequestTemplateStakeHoldersSerializer(
serializers.ModelSerializer
):
class Meta:
model = models.ChangeRequestTemplateStakeHolders
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
class ChangeRequestTemplateAttachmentsSerializer(
serializers.ModelSerializer
):
class Meta:
model = models.ChangeRequestTemplateAttachments
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
class ChangeRequestTemplateDetailsSerializer(
serializers.ModelSerializer
):
class Meta:
model = models.ChangeRequestTemplateDetails
fields = '__all__'
read_only_fields = ['created', 'archived_at', 'code']
# comment
class ChangeRequestTemplatesSerializer(
WritableNestedModelSerializer
):
tmp_approvers = ChangeRequestTemplateApproversSerializer(
many=True, required=False)
tmp_stakes = ChangeRequestTemplateStakeHoldersSerializer(
many=True, required=False)
tmp_attachments = ChangeRequestTemplateAttachmentsSerializer(
many=True, required=False)
tmp_details = ChangeRequestTemplateDetailsSerializer(
many=True, required=False)
class Meta:
model = models.ChangeRequestTemplateHeader
# fields = '__all__'
fields = ('template_no', 'requested_to_template_name',
'requested_to_objective', 'requested_to_target_date',
'requested_to_priority', 'description', 'created',
'requested_to_template_id', 'requested_to_company',
'requested_to_department', 'requested_to_user',
'created_by_user', 'created_by_department', 'tmp_approvers',
'tmp_stakes', 'tmp_attachments', 'tmp_details')
read_only_fields = ['created', 'archived_at', 'template_no']
\ No newline at end of file
from django.shortcuts import render
from rest_framework import viewsets as meviewsets
from rest_framework.views import APIView
from app.applicationlayer.cms.template import serializers
from app.entities import models
from app.applicationlayer import paginators
from datetime import datetime
from datetime import timedelta
from rest_framework.response import Response
from rest_framework import status, views
from rest_framework.decorators import action
from django.http import Http404
from django.db.models import Q
import requests
from django.conf import settings
from rest_framework.exceptions import ValidationError
from django.db import transaction, IntegrityError, connection
from app.applicationlayer.utils import QuerySetHelper
from app.businesslayer.changerequest import change_request
from app.applicationlayer.cms.utils_cr import number_generator, crhistory_save
from django.shortcuts import get_object_or_404
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import UpdateModelMixin
from django.forms.models import model_to_dict
from app.entities import enums
class ChangeRequestTemplatesViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestTemplateHeader.objects.all()
lookup_field = 'template_no'
serializer_class = serializers.ChangeRequestTemplatesSerializer
pagination_class = paginators.SimplePageNumberPagination
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.order_by('-created')
self.queryset = QuerySetHelper.Sort(self)
return super(ChangeRequestTemplatesViewset, self).list(request)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(
template_no=str(self.kwargs.get('template_no'))
).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
def destroy(self, request, *args, **kwargs):
try:
template_no = self.kwargs['template_no']
instance = models.ChangeRequestTemplateHeader.objects.filter(
Q(template_no=template_no) &
Q(archived_at=None)
).update(archived_at=datetime.now())
return Response({"message": "Deleted"}, status=status.HTTP_200_OK)
except Exception as e:
return Response(e,
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@transaction.atomic
def partial_update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
instance = self.get_object()
template_no = kwargs['template_no']
tmp_no_exists = models.ChangeRequestFormHeader.objects.filter(
template_no=template_no)
if not tmp_no_exists:
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
old_instance = model_to_dict(instance)
self.perform_update(serializer)
new_instance = serializer.data
# print(new_instance)
crhistory_save(
enums.LogEnum.UPDATE.value,
enums.CREntitiesEnum.CR_TMP_HEADER.value,
new_instance['template_no'],
old_instance,
new_instance
)
return Response(serializer.data)
return Response(
"Unable to edit due to existing transaction",
status=status.HTTP_400_BAD_REQUEST
)
@action(
methods=['PATCH'], detail=True,
url_path='archived', url_name='archived'
)
def archived(self, request, *args, **kwargs):
template_no = kwargs['template_no']
tmp_no_exists = models.ChangeRequestFormHeader.objects.filter(
template_no=template_no)
if not tmp_no_exists:
models.ChangeRequestTemplateDetails.objects.filter(
template_no=template_no
).update(archived_at=datetime.now())
models.ChangeRequestTemplateAttachments.objects.filter(
template_no=template_no
).update(archived_at=datetime.now())
models.ChangeRequestTemplateHeader.objects.filter(
template_no=template_no
).update(archived_at=datetime.now())
models.ChangeRequestTemplateApprovers.objects.filter(
template_no=template_no
).update(archived_at=datetime.now())
models.ChangeRequestTemplateStakeHolders.objects.filter(
template_no=template_no
).update(archived_at=datetime.now())
return Response(
"Template successfully archived",
status=status.HTTP_200_OK
)
return Response(
"Unable to archive due to existing transaction",
status=status.HTTP_400_BAD_REQUEST
)
class ChangeRequestTemplatePost(APIView):
@transaction.atomic()
def post(self, request):
template_header = request.data
try:
data_list_approver = []
data_list_stake = []
data_list_attach = []
data_list_detail = []
template_header_data = {
'requested_to_template_name': template_header['requested_to_template_name'],
'requested_to_template_id': template_header['requested_to_template_id'],
'requested_to_objective': template_header['requested_to_objective'],
'requested_to_target_date': template_header['requested_to_target_date'],
'requested_to_priority': template_header['requested_to_priority'],
'description': template_header['description'],
'created_by_department': template_header['created_by_department'],
'created_by_user': template_header['created_by_user'],
'requested_to_company': template_header['requested_to_company'],
'requested_to_department': template_header['requested_to_department'],
'requested_to_user': template_header['requested_to_user']
}
tmp_approvers = template_header['tmp_approvers']
tmp_stakes = template_header['tmp_stakes']
tmp_attachments = template_header['tmp_attachments']
tmp_details = template_header['tmp_details']
sp1 = transaction.savepoint() # nothing will save to db
serializer = serializers.ChangeRequestTemplatesSerializer(
data=template_header_data)
if serializer.is_valid(raise_exception=True):
serializer.save()
tmp_id = serializer.data['template_no']
# create template approvers
for tmp_approver in tmp_approvers:
tmp_approver['template_no'] = tmp_id
data_list_approver.append(tmp_approver)
serializerApprover = serializers.ChangeRequestTemplateApproversSerializer(
data=data_list_approver, many=True)
if serializerApprover.is_valid(raise_exception=True):
serializerApprover.save()
# create template stakes
for tmp_stake in tmp_stakes:
tmp_stake['template_no'] = tmp_id
data_list_stake.append(tmp_stake)
serializerStake = serializers.ChangeRequestTemplateStakeHoldersSerializer(
data=data_list_stake, many=True)
if serializerStake.is_valid(raise_exception=True):
serializerStake.save()
# create template attachments
for tmp_attachment in tmp_attachments:
tmp_attachment['template_no'] = tmp_id
data_list_attach.append(tmp_attachment)
serializerAttach = serializers.ChangeRequestTemplateAttachmentsSerializer(
data=data_list_attach, many=True)
if serializerAttach.is_valid(raise_exception=True):
serializerAttach.save()
# create template details
for tmp_detail in tmp_details:
tmp_detail['template_no'] = tmp_id
data_list_detail.append(tmp_detail)
serializerDetail = serializers.ChangeRequestTemplateDetailsSerializer(
data=data_list_detail, many=True)
if serializerDetail.is_valid(raise_exception=True):
serializerDetail.save()
message = {
'code': 201,
'status': 'success',
'message': 'Template Details successfully saved!',
'results': serializer.data
}
return Response(message, status=status.HTTP_201_CREATED)
except ValidationError as e:
transaction.savepoint_rollback(sp1)
message = {
'code': 400,
'status': 'failed',
'message': str(e),
}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
transaction.savepoint_rollback(sp1)
message = {
'code': 500,
'status': 'failed',
'message': 'Request was not able to process' + str(e),
}
return Response(message,
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class ChangeRequestTemplateApproversViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestTemplateApprovers.objects.all()
serializer_class = serializers.ChangeRequestTemplateApproversSerializer
pagination_class = paginators.SimplePageNumberPagination
lookup_field = "code"
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
return super(ChangeRequestTemplateApproversViewset, self).list(request)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class ChangeRequestTemplateAttachmentsViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestTemplateAttachments.objects.all()
serializer_class = serializers.ChangeRequestTemplateAttachmentsSerializer
pagination_class = paginators.SimplePageNumberPagination
lookup_field = "code"
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
return super(
ChangeRequestTemplateAttachmentsViewset, self
).list(request)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class ChangeRequestTemplateStakeHoldersViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestTemplateStakeHolders.objects.all()
serializer_class = serializers.ChangeRequestTemplateStakeHoldersSerializer
pagination_class = paginators.SimplePageNumberPagination
lookup_field = "code"
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
return super(ChangeRequestTemplateStakeHoldersViewset, self).list(request)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class ChangeRequestTemplateDetailsViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestTemplateDetails.objects.all()
serializer_class = serializers.ChangeRequestTemplateDetailsSerializer
pagination_class = paginators.SimplePageNumberPagination
lookup_field = "code"
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
return super(ChangeRequestTemplateDetailsViewset, self).list(request)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
from django.shortcuts import render
from rest_framework import viewsets as meviewsets
from rest_framework.views import APIView
from app.applicationlayer.cms.template import serializers
from app.entities import models
from app.applicationlayer import paginators
from datetime import datetime
from datetime import timedelta
from rest_framework.response import Response
from rest_framework import status, views
from rest_framework.decorators import action
from django.http import Http404
from django.db.models import Q
import requests
from django.conf import settings
from rest_framework.exceptions import ValidationError
from django.db import transaction, IntegrityError, connection
from app.applicationlayer.utils import QuerySetHelper
from app.businesslayer.changerequest import change_request
from app.applicationlayer.cms.utils_cr import number_generator, crhistory_save
from django.shortcuts import get_object_or_404
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import UpdateModelMixin
from django.forms.models import model_to_dict
from app.entities import enums
class ChangeRequestTemplatesViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestTemplateHeader.objects.all()
lookup_field = 'template_no'
serializer_class = serializers.ChangeRequestTemplatesSerializer
pagination_class = paginators.SimplePageNumberPagination
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.order_by('-created')
self.queryset = QuerySetHelper.Sort(self)
return super(ChangeRequestTemplatesViewset, self).list(request)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(
template_no=str(self.kwargs.get('template_no'))
).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
def destroy(self, request, *args, **kwargs):
try:
template_no = self.kwargs['template_no']
instance = models.ChangeRequestTemplateHeader.objects.filter(
Q(template_no=template_no) &
Q(archived_at=None)
).update(archived_at=datetime.now())
return Response({"message": "Deleted"}, status=status.HTTP_200_OK)
except Exception as e:
return Response(e,
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@transaction.atomic
def partial_update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
instance = self.get_object()
template_no = kwargs['template_no']
tmp_no_exists = models.ChangeRequestFormHeader.objects.filter(
template_no=template_no)
if not tmp_no_exists:
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
old_instance = model_to_dict(instance)
self.perform_update(serializer)
new_instance = serializer.data
# print(new_instance)
crhistory_save(
enums.LogEnum.UPDATE.value,
enums.CREntitiesEnum.CR_TMP_HEADER.value,
new_instance['template_no'],
old_instance,
new_instance
)
return Response(serializer.data)
return Response(
"Unable to edit due to existing transaction",
status=status.HTTP_400_BAD_REQUEST
)
@action(
methods=['PATCH'], detail=True,
url_path='archived', url_name='archived'
)
def archived(self, request, *args, **kwargs):
template_no = kwargs['template_no']
tmp_no_exists = models.ChangeRequestFormHeader.objects.filter(
template_no=template_no)
if not tmp_no_exists:
models.ChangeRequestTemplateDetails.objects.filter(
template_no=template_no
).update(archived_at=datetime.now())
models.ChangeRequestTemplateAttachments.objects.filter(
template_no=template_no
).update(archived_at=datetime.now())
models.ChangeRequestTemplateHeader.objects.filter(
template_no=template_no
).update(archived_at=datetime.now())
models.ChangeRequestTemplateApprovers.objects.filter(
template_no=template_no
).update(archived_at=datetime.now())
models.ChangeRequestTemplateStakeHolders.objects.filter(
template_no=template_no
).update(archived_at=datetime.now())
return Response(
"Template successfully archived",
status=status.HTTP_200_OK
)
return Response(
"Unable to archive due to existing transaction",
status=status.HTTP_400_BAD_REQUEST
)
class ChangeRequestTemplatePost(APIView):
@transaction.atomic()
def post(self, request):
template_header = request.data
try:
data_list_approver = []
data_list_stake = []
data_list_attach = []
data_list_detail = []
template_header_data = {
'requested_to_template_name': template_header['requested_to_template_name'],
'requested_to_template_id': template_header['requested_to_template_id'],
'requested_to_objective': template_header['requested_to_objective'],
'requested_to_target_date': template_header['requested_to_target_date'],
'requested_to_priority': template_header['requested_to_priority'],
'description': template_header['description'],
'created_by_department': template_header['created_by_department'],
'created_by_user': template_header['created_by_user'],
'requested_to_company': template_header['requested_to_company'],
'requested_to_department': template_header['requested_to_department'],
'requested_to_user': template_header['requested_to_user']
}
tmp_approvers = template_header['tmp_approvers']
tmp_stakes = template_header['tmp_stakes']
tmp_attachments = template_header['tmp_attachments']
tmp_details = template_header['tmp_details']
sp1 = transaction.savepoint() # nothing will save to db
serializer = serializers.ChangeRequestTemplatesSerializer(
data=template_header_data)
if serializer.is_valid(raise_exception=True):
serializer.save()
tmp_id = serializer.data['template_no']
# create template approvers
for tmp_approver in tmp_approvers:
tmp_approver['template_no'] = tmp_id
data_list_approver.append(tmp_approver)
serializerApprover = serializers.ChangeRequestTemplateApproversSerializer(
data=data_list_approver, many=True)
if serializerApprover.is_valid(raise_exception=True):
serializerApprover.save()
# create template stakes
for tmp_stake in tmp_stakes:
tmp_stake['template_no'] = tmp_id
data_list_stake.append(tmp_stake)
serializerStake = serializers.ChangeRequestTemplateStakeHoldersSerializer(
data=data_list_stake, many=True)
if serializerStake.is_valid(raise_exception=True):
serializerStake.save()
# create template attachments
for tmp_attachment in tmp_attachments:
tmp_attachment['template_no'] = tmp_id
data_list_attach.append(tmp_attachment)
serializerAttach = serializers.ChangeRequestTemplateAttachmentsSerializer(
data=data_list_attach, many=True)
if serializerAttach.is_valid(raise_exception=True):
serializerAttach.save()
# create template details
for tmp_detail in tmp_details:
tmp_detail['template_no'] = tmp_id
data_list_detail.append(tmp_detail)
serializerDetail = serializers.ChangeRequestTemplateDetailsSerializer(
data=data_list_detail, many=True)
if serializerDetail.is_valid(raise_exception=True):
serializerDetail.save()
message = {
'code': 201,
'status': 'success',
'message': 'Template Details successfully saved!',
'results': serializer.data
}
return Response(message, status=status.HTTP_201_CREATED)
except ValidationError as e:
transaction.savepoint_rollback(sp1)
message = {
'code': 400,
'status': 'failed',
'message': str(e),
}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
transaction.savepoint_rollback(sp1)
message = {
'code': 500,
'status': 'failed',
'message': 'Request was not able to process' + str(e),
}
return Response(message,
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class ChangeRequestTemplateApproversViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestTemplateApprovers.objects.all()
serializer_class = serializers.ChangeRequestTemplateApproversSerializer
pagination_class = paginators.SimplePageNumberPagination
lookup_field = "code"
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
return super(ChangeRequestTemplateApproversViewset, self).list(request)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class ChangeRequestTemplateAttachmentsViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestTemplateAttachments.objects.all()
serializer_class = serializers.ChangeRequestTemplateAttachmentsSerializer
pagination_class = paginators.SimplePageNumberPagination
lookup_field = "code"
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
return super(
ChangeRequestTemplateAttachmentsViewset, self
).list(request)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class ChangeRequestTemplateStakeHoldersViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestTemplateStakeHolders.objects.all()
serializer_class = serializers.ChangeRequestTemplateStakeHoldersSerializer
pagination_class = paginators.SimplePageNumberPagination
lookup_field = "code"
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
return super(ChangeRequestTemplateStakeHoldersViewset, self).list(request)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
class ChangeRequestTemplateDetailsViewset(meviewsets.ModelViewSet):
queryset = models.ChangeRequestTemplateDetails.objects.all()
serializer_class = serializers.ChangeRequestTemplateDetailsSerializer
pagination_class = paginators.SimplePageNumberPagination
lookup_field = "code"
def list(self, request, *args, **kwargs):
self.queryset = self.queryset.filter(archived_at=None)
self.queryset = QuerySetHelper.Sort(self)
return super(ChangeRequestTemplateDetailsViewset, self).list(request)
def retrieve(self, request, *args, **kwargs):
instance = self.queryset.filter(archived_at=None).first()
serializer = self.get_serializer(instance)
return Response(serializer.data)
\ No newline at end of file
from datetime import datetime
from django.db.models.functions import Lower
from functools import wraps
from django.conf import settings
import requests
from app.entities import models
from datetime import timedelta
from django.db.models import Q
# from dateutil import parser
# EMAIL = settings.EMAIL
# ACCOUNTS = settings.ACCOUNTS
# GROUPS = settings.GROUPS
# COMPANIES = settings.COMPANIES
# ALLOWED_COMPANY = settings.ALLOWED_COMPANY
# CR_FRONT_LINK = settings.CR_FRONT_LINK
# NOTIFICATION = settings.NOTIFICATION
def get_group_details(group_no):
return requests.get(f'{GROUPS}?group_no={group_no}').json()['results'][0]
def get_companies_details(slug):
return requests.get(f'{COMPANIES}?slug={slug}').json()['results'][0]
def get_account_details(id_number):
return requests.get(f'{ACCOUNTS}?id_number={id_number}').json()['results'][0]
def get_allowed_company(id_number):
return requests.get(f'{ALLOWED_COMPANY}?id_number={id_number}')
class QuerySetHelper:
@staticmethod
def Sort(context):
sort_field = context.request.query_params.get('sort_field')
sort_order = context.request.query_params.get('sort_order')
if sort_field and sort_order:
if sort_order.lower() == 'asc':
context.queryset = context.queryset.order_by(sort_field)
else:
context.queryset = context.queryset.order_by(f"-{sort_field}")
return context.queryset
@staticmethod
def Search(context):
search_field = context.request.query_params.get('search-field')
search_key = context.request.query_params.get('search-key')
if search_field and search_key:
context.queryset = context.queryset(
__raw__={f"{search_field}" : {"$regex" : f".*{search_key.lower()}.*"}}
)
return context.queryset
@staticmethod
def SearchDynamic(base_queryset,
):
search_field = context.request.query_params.get('search-field')
search_key = context.request.query_params.get('search-key')
if search_field and search_key:
context.queryset = context.queryset(
__raw__={f"{search_field}" : {"$regex" : f".*{search_key.lower()}.*"}}
)
return context.queryset
# if self.request.query_params.get('search'):
# search_key = self.request.query_params.get('search')
# self.queryset = self.queryset.filter(
# Q(requested_to_template_name__icontains=search_key.lower()) |
# Q(requested_to_template_id__icontains=search_key.lower())
# )
# self.queryset = QuerySetHelper.Sort(self)
@staticmethod
def Filter(context):
if int(len(context.request.query_params)) > 0:
filtering_kwargs = {}
with_params = []
common_params = (
'page', 'page-size', 'page_size', 'sort_order', 'sort_field'
)
for field, value in context.request.GET.items():
filtering_kwargs = {}
if value and field.lower() not in common_params:
filtering_kwargs[field] = {"$regex" : f".*{value.lower()}.*"}
filtering_kwargs[field] = {"$regex" : f".*{value}.*"}
# filtering_kwargs[field] = {"$regex" : f".*{value.lower()}.*"}
with_params.append(filtering_kwargs)
raw_query = {"$or": with_params}
context.queryset = context.queryset(__raw__=raw_query)
return context.queryset
def ApproverStatus(status):
choices = ["pending", "rejected", "approved", "completed", "cancelled", 'acknowledged', 'accepted']
if status not in choices:
return False
else:
return True
def number_generator(prefix, id):
date = '{:%Y%m%d}'.format(datetime.now())
id_num = '{:07}'.format(id)
autogenerated_no = prefix + '-' + date + '-' + id_num
return autogenerated_no
def logged_user(self):
# return self.request.META.get('HTTP_ACCOUNT_NO')
return self.request.user
def receiver_body(
sender_account_no, receiver_account_no,
email_code, email_recipient,
app, sent, name, routing_level,
status, cr_number, cr_name,
company_requestedto,
department_requestedto,
priority_level, url
):
receiver_data = {
"sender_account_no": sender_account_no,
"receiver_account_no": receiver_account_no,
"email_code": email_code,
"email_recipient": email_recipient,
"app": app,
"sent": "False",
"name": name,
"routing_level": routing_level,
"status": status,
"cr_number": cr_number,
"cr_name": cr_name,
"company_requestedto": company_requestedto,
"department_requestedto": department_requestedto,
"priority_level": priority_level,
"url": url
}
return receiver_data
def get_template_instance(form_code):
template_instance = models.ChangeRequestFormHeader.objects.filter(
Q(form_code=form_code) &
Q(archived_at=None)
).first()
return template_instance
def send_notification(
form_code, cr_number, user_id_number,
user_name, message, app,
sender_id_number, sender_name
):
notification_data = {
"slug": form_code,
"change_request_template_code": cr_number,
# (OPENING TAG) receiver credential
"account_no": user_id_number,
"user": user_name,
# (CLOSING TAG) receiver credential
"notif_type": "ACTIVITY",
"message": message,
"is_read": False,
"app": app,
"sender_account_no": sender_id_number,
"createdby": sender_name
}
notification = requests.post(NOTIFICATION, data=notification_data)
# return notification.status
return notification
def send_mail_vendor(receiver,
form_code,
delegation,
msg,
action,
code,
remarks,
routing_level):
app = 'cms'
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
requested_to_department = template_instance.requested_to_department
requested_by_user = template_instance.requested_by_user
created = template_instance.created
requested_to_priority = template_instance.requested_to_priority
vendor_instance = models.ChangeRequestFormApprovers.objects.filter(
Q(delegation="Vendor/Implementor") &
Q(form_code=form_code)
).first()
# receiver details
vendor = get_account_details(vendor_instance.user)
requestor_name = vendor['name']
requestor_email = vendor['email']
requestor_account_id = vendor['id_number']
# sender details
sender_instance = get_account_details(receiver)
sender_account_username = sender_instance['username']
sender_account_id = sender_instance['id_number']
sender_name = sender_instance['name']
group = get_group_details(requested_to_department)
group_name = group['name']
company = get_companies_details(requested_to_company)
company_name = company['name']
container = receiver_body(
sender_account_id, requestor_account_id, code,
requestor_email, app, "False", requestor_name, routing_level,
action, cr_number, template_name, company_name, group_name,
requested_to_priority, cr_link
)
if action.lower() == 'rejected':
new_body = {"rejected_by": requestor_name,
"remarks": remarks}
elif action.lower() == 'accepted':
new_body = {"approved_by": requestor_name}
data = {**container, **new_body}
email_status = requests.post(EMAIL, data=data)
message = f"{sender_name} {msg} ({template_name})"
send_notification(
form_code, cr_number,
requestor_account_id, requestor_name,
message, app,
sender_account_id, sender_account_username
)
def send_mail_requestor(receiver,
form_code,
delegation,
msg,
action,
code,
remarks,
routing_level):
cr_link = f'{CR_FRONT_LINK}/{form_code}'
template_instance = get_template_instance(form_code)
app = 'cms'
cr_number = template_instance.requested_to_template_id
template_name = template_instance.requested_to_template_name
requested_to_company = template_instance.requested_to_company
requested_to_department = template_instance.requested_to_department
requested_by_user = template_instance.requested_by_user
created = template_instance.created
requested_to_priority = template_instance.requested_to_priority
# receiver details --------------------------------------------------
requestor_instance = get_account_details(requested_by_user)
requestor_name = requestor_instance['name']
requestor_email = requestor_instance['email']
requestor_account_id = requestor_instance['id_number']
# sender details --------------------------------------------------
sender_instance = get_account_details(receiver)
sender_account_username = sender_instance['username']
sender_account_id = sender_instance['id_number']
sender_name = sender_instance['name']
group = get_group_details(requested_to_department)
group_name = group['name']
company = get_companies_details(requested_to_company)
company_name = company['name']
data = receiver_body(
sender_account_id, requestor_account_id, code,
requestor_email, app, "False", requestor_name, routing_level,
action, cr_number, template_name, company_name, group_name,
requested_to_priority, cr_link
)
if action.lower() == 'approved':
new_body = {"approved_by": sender_name}
elif action.lower() == 'rejected':
new_body = {"rejected_by": sender_name,
"remarks": remarks}
elif action.lower() == 'completed':
new_body = {"completed_by": sender_name}
elif action.lower() == 'acknowledged':
new_body = {"acknowledge_by": sender_name}
data = {**data, **new_body}
email_status = requests.post(EMAIL, data=data)
message = f"{sender_name} {msg} ({template_name})"
notif = send_notification(
form_code, cr_number,
requestor_account_id, requestor_name,
message, app,
sender_account_id, sender_account_username
)
def next_appover_email(receiver, form_code, delegation, msg, action, code):
cr_link = f'{CR_FRONT_LINK}/{form_code}'
template_instance = get_template_instance(form_code)
app = 'cms'
cr_number = template_instance.requested_to_template_id
template_name = template_instance.requested_to_template_name
requested_to_company = template_instance.requested_to_company
requested_to_department = template_instance.requested_to_department
requested_by_user = template_instance.requested_by_user
created = template_instance.created
requested_to_priority = template_instance.requested_to_priority
# for rec in receiver:
# receiver details
# if action == 'initial':
receiver_instance = get_account_details(receiver)
# else:
# receiver_instance = get_account_details(receiver.user)
receiver_name = receiver_instance['name']
receiver_email = receiver_instance['email']
receiver_account_id = receiver_instance['id_number']
# sender details
sender_instance = get_account_details(requested_by_user)
sender_account_username = sender_instance['username']
sender_account_id = sender_instance['id_number']
sender_name = sender_instance['name']
group = get_group_details(requested_to_department)
group_name = group['name']
company = get_companies_details(requested_to_company)
company_name = company['name']
data = receiver_body(
sender_account_id, receiver_account_id, code,
receiver_email, app, "False", receiver_name, 1,
"Pending", cr_number, template_name, company_name, group_name,
requested_to_priority, cr_link
)
email_status = requests.post(EMAIL, data=data)
message = f"{sender_name} {msg} ({template_name})"
notif = send_notification(
form_code, cr_number,
receiver_account_id, receiver_name,
message, app,
sender_account_id, sender_account_username
)
return True
def cancel_overdue(request):
date_submitted = datetime.now()
requestor = request.data['requested_by_user']
requestor = requests.get(f'{ACCOUNTS}{requestor}/')
requestor = requestor.json()['results']
cancel_date = date_submitted + timedelta(days=30)
cancel_date = cancel_date.strftime('%Y-%m-%d 00:00:00.000')
request.data['date_submitted'] = date_submitted
request.data['cancel_date'] = cancel_date
email_content_cancel = {
"sender_account_no": requestor['id_number'],
"receiver_account_no": requestor['id_number'],
"email_code": "RMS-CRCANCELLED",
"email_recipient": requestor['email'],
"app": "CMS",
"sent": "False",
"name": requestor['name'],
"status": "Pending",
"auto_cancel_date": cancel_date,
"cr_number": request.data['requested_to_template_id'],
"cr_name": request.data['requested_to_template_name'],
"company_requestedto": request.data['requested_to_company'],
"department_requestedto": request.data['requested_to_department'],
"priority_level": request.data['requested_to_priority'],
"url": "http://devweb.rms.oneberrysystem.com/login"
}
exist_cancel_template = models.CancelDateCR.objects.filter(
cr_number=request.data['requested_to_template_id']
)
if exist_cancel_template:
exist_cancel_template.delete()
models.CancelDateCR.objects.create(
cr_number=request.data['requested_to_template_id'],
trigger_date=cancel_date,
email_content=email_content_cancel
)
requested_to_target_date = parser.parse(
request.data['requested_to_target_date']
)
email_content_cancel['email_code'] = "RMS-CROVERDUE"
email_content_cancel['target_date'] = requested_to_target_date
overdue = requested_to_target_date + timedelta(days=30)
overdue = overdue.strftime('%Y-%m-%d 00:00:00.000')
models.TargetDateOverdue.objects.create(
cr_number=form_code,
trigger_date=overdue,
email_content=email_content_cancel
)
return True
def crhistory_save(action, entity, form_code, fromValue, toValue):
models.ChangeRequestHistory.objects.create(
action=action,
entity=entity,
form_code=form_code,
fromValue=fromValue,
toValue=toValue
)
from datetime import datetime
from django.db.models.functions import Lower
from functools import wraps
from django.conf import settings
import requests
from app.entities import models
from datetime import timedelta
from django.db.models import Q
# from dateutil import parser
# EMAIL = settings.EMAIL
# ACCOUNTS = settings.ACCOUNTS
# GROUPS = settings.GROUPS
# COMPANIES = settings.COMPANIES
# ALLOWED_COMPANY = settings.ALLOWED_COMPANY
# CR_FRONT_LINK = settings.CR_FRONT_LINK
# NOTIFICATION = settings.NOTIFICATION
def get_group_details(group_no):
return requests.get(f'{GROUPS}?group_no={group_no}').json()['results'][0]
def get_companies_details(slug):
return requests.get(f'{COMPANIES}?slug={slug}').json()['results'][0]
def get_account_details(id_number):
return requests.get(f'{ACCOUNTS}?id_number={id_number}').json()['results'][0]
def get_allowed_company(id_number):
return requests.get(f'{ALLOWED_COMPANY}?id_number={id_number}')
class QuerySetHelper:
@staticmethod
def Sort(context):
sort_field = context.request.query_params.get('sort_field')
sort_order = context.request.query_params.get('sort_order')
if sort_field and sort_order:
if sort_order.lower() == 'asc':
context.queryset = context.queryset.order_by(sort_field)
else:
context.queryset = context.queryset.order_by(f"-{sort_field}")
return context.queryset
@staticmethod
def Search(context):
search_field = context.request.query_params.get('search-field')
search_key = context.request.query_params.get('search-key')
if search_field and search_key:
context.queryset = context.queryset(
__raw__={f"{search_field}" : {"$regex" : f".*{search_key.lower()}.*"}}
)
return context.queryset
@staticmethod
def SearchDynamic(base_queryset,
):
search_field = context.request.query_params.get('search-field')
search_key = context.request.query_params.get('search-key')
if search_field and search_key:
context.queryset = context.queryset(
__raw__={f"{search_field}" : {"$regex" : f".*{search_key.lower()}.*"}}
)
return context.queryset
# if self.request.query_params.get('search'):
# search_key = self.request.query_params.get('search')
# self.queryset = self.queryset.filter(
# Q(requested_to_template_name__icontains=search_key.lower()) |
# Q(requested_to_template_id__icontains=search_key.lower())
# )
# self.queryset = QuerySetHelper.Sort(self)
@staticmethod
def Filter(context):
if int(len(context.request.query_params)) > 0:
filtering_kwargs = {}
with_params = []
common_params = (
'page', 'page-size', 'page_size', 'sort_order', 'sort_field'
)
for field, value in context.request.GET.items():
filtering_kwargs = {}
if value and field.lower() not in common_params:
filtering_kwargs[field] = {"$regex" : f".*{value.lower()}.*"}
filtering_kwargs[field] = {"$regex" : f".*{value}.*"}
# filtering_kwargs[field] = {"$regex" : f".*{value.lower()}.*"}
with_params.append(filtering_kwargs)
raw_query = {"$or": with_params}
context.queryset = context.queryset(__raw__=raw_query)
return context.queryset
def ApproverStatus(status):
choices = ["pending", "rejected", "approved", "completed", "cancelled", 'acknowledged', 'accepted']
if status not in choices:
return False
else:
return True
def number_generator(prefix, id):
date = '{:%Y%m%d}'.format(datetime.now())
id_num = '{:07}'.format(id)
autogenerated_no = prefix + '-' + date + '-' + id_num
return autogenerated_no
def logged_user(self):
# return self.request.META.get('HTTP_ACCOUNT_NO')
return self.request.user
def receiver_body(
sender_account_no, receiver_account_no,
email_code, email_recipient,
app, sent, name, routing_level,
status, cr_number, cr_name,
company_requestedto,
department_requestedto,
priority_level, url
):
receiver_data = {
"sender_account_no": sender_account_no,
"receiver_account_no": receiver_account_no,
"email_code": email_code,
"email_recipient": email_recipient,
"app": app,
"sent": "False",
"name": name,
"routing_level": routing_level,
"status": status,
"cr_number": cr_number,
"cr_name": cr_name,
"company_requestedto": company_requestedto,
"department_requestedto": department_requestedto,
"priority_level": priority_level,
"url": url
}
return receiver_data
def get_template_instance(form_code):
template_instance = models.ChangeRequestFormHeader.objects.filter(
Q(form_code=form_code) &
Q(archived_at=None)
).first()
return template_instance
def send_notification(
form_code, cr_number, user_id_number,
user_name, message, app,
sender_id_number, sender_name
):
notification_data = {
"slug": form_code,
"change_request_template_code": cr_number,
# (OPENING TAG) receiver credential
"account_no": user_id_number,
"user": user_name,
# (CLOSING TAG) receiver credential
"notif_type": "ACTIVITY",
"message": message,
"is_read": False,
"app": app,
"sender_account_no": sender_id_number,
"createdby": sender_name
}
notification = requests.post(NOTIFICATION, data=notification_data)
# return notification.status
return notification
def send_mail_vendor(receiver,
form_code,
delegation,
msg,
action,
code,
remarks,
routing_level):
app = 'cms'
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
requested_to_department = template_instance.requested_to_department
requested_by_user = template_instance.requested_by_user
created = template_instance.created
requested_to_priority = template_instance.requested_to_priority
vendor_instance = models.ChangeRequestFormApprovers.objects.filter(
Q(delegation="Vendor/Implementor") &
Q(form_code=form_code)
).first()
# receiver details
vendor = get_account_details(vendor_instance.user)
requestor_name = vendor['name']
requestor_email = vendor['email']
requestor_account_id = vendor['id_number']
# sender details
sender_instance = get_account_details(receiver)
sender_account_username = sender_instance['username']
sender_account_id = sender_instance['id_number']
sender_name = sender_instance['name']
group = get_group_details(requested_to_department)
group_name = group['name']
company = get_companies_details(requested_to_company)
company_name = company['name']
container = receiver_body(
sender_account_id, requestor_account_id, code,
requestor_email, app, "False", requestor_name, routing_level,
action, cr_number, template_name, company_name, group_name,
requested_to_priority, cr_link
)
if action.lower() == 'rejected':
new_body = {"rejected_by": requestor_name,
"remarks": remarks}
elif action.lower() == 'accepted':
new_body = {"approved_by": requestor_name}
data = {**container, **new_body}
email_status = requests.post(EMAIL, data=data)
message = f"{sender_name} {msg} ({template_name})"
send_notification(
form_code, cr_number,
requestor_account_id, requestor_name,
message, app,
sender_account_id, sender_account_username
)
def send_mail_requestor(receiver,
form_code,
delegation,
msg,
action,
code,
remarks,
routing_level):
cr_link = f'{CR_FRONT_LINK}/{form_code}'
template_instance = get_template_instance(form_code)
app = 'cms'
cr_number = template_instance.requested_to_template_id
template_name = template_instance.requested_to_template_name
requested_to_company = template_instance.requested_to_company
requested_to_department = template_instance.requested_to_department
requested_by_user = template_instance.requested_by_user
created = template_instance.created
requested_to_priority = template_instance.requested_to_priority
# receiver details --------------------------------------------------
requestor_instance = get_account_details(requested_by_user)
requestor_name = requestor_instance['name']
requestor_email = requestor_instance['email']
requestor_account_id = requestor_instance['id_number']
# sender details --------------------------------------------------
sender_instance = get_account_details(receiver)
sender_account_username = sender_instance['username']
sender_account_id = sender_instance['id_number']
sender_name = sender_instance['name']
group = get_group_details(requested_to_department)
group_name = group['name']
company = get_companies_details(requested_to_company)
company_name = company['name']
data = receiver_body(
sender_account_id, requestor_account_id, code,
requestor_email, app, "False", requestor_name, routing_level,
action, cr_number, template_name, company_name, group_name,
requested_to_priority, cr_link
)
if action.lower() == 'approved':
new_body = {"approved_by": sender_name}
elif action.lower() == 'rejected':
new_body = {"rejected_by": sender_name,
"remarks": remarks}
elif action.lower() == 'completed':
new_body = {"completed_by": sender_name}
elif action.lower() == 'acknowledged':
new_body = {"acknowledge_by": sender_name}
data = {**data, **new_body}
email_status = requests.post(EMAIL, data=data)
message = f"{sender_name} {msg} ({template_name})"
notif = send_notification(
form_code, cr_number,
requestor_account_id, requestor_name,
message, app,
sender_account_id, sender_account_username
)
def next_appover_email(receiver, form_code, delegation, msg, action, code):
cr_link = f'{CR_FRONT_LINK}/{form_code}'
template_instance = get_template_instance(form_code)
app = 'cms'
cr_number = template_instance.requested_to_template_id
template_name = template_instance.requested_to_template_name
requested_to_company = template_instance.requested_to_company
requested_to_department = template_instance.requested_to_department
requested_by_user = template_instance.requested_by_user
created = template_instance.created
requested_to_priority = template_instance.requested_to_priority
# for rec in receiver:
# receiver details
# if action == 'initial':
receiver_instance = get_account_details(receiver)
# else:
# receiver_instance = get_account_details(receiver.user)
receiver_name = receiver_instance['name']
receiver_email = receiver_instance['email']
receiver_account_id = receiver_instance['id_number']
# sender details
sender_instance = get_account_details(requested_by_user)
sender_account_username = sender_instance['username']
sender_account_id = sender_instance['id_number']
sender_name = sender_instance['name']
group = get_group_details(requested_to_department)
group_name = group['name']
company = get_companies_details(requested_to_company)
company_name = company['name']
data = receiver_body(
sender_account_id, receiver_account_id, code,
receiver_email, app, "False", receiver_name, 1,
"Pending", cr_number, template_name, company_name, group_name,
requested_to_priority, cr_link
)
email_status = requests.post(EMAIL, data=data)
message = f"{sender_name} {msg} ({template_name})"
notif = send_notification(
form_code, cr_number,
receiver_account_id, receiver_name,
message, app,
sender_account_id, sender_account_username
)
return True
def cancel_overdue(request):
date_submitted = datetime.now()
requestor = request.data['requested_by_user']
requestor = requests.get(f'{ACCOUNTS}{requestor}/')
requestor = requestor.json()['results']
cancel_date = date_submitted + timedelta(days=30)
cancel_date = cancel_date.strftime('%Y-%m-%d 00:00:00.000')
request.data['date_submitted'] = date_submitted
request.data['cancel_date'] = cancel_date
email_content_cancel = {
"sender_account_no": requestor['id_number'],
"receiver_account_no": requestor['id_number'],
"email_code": "RMS-CRCANCELLED",
"email_recipient": requestor['email'],
"app": "CMS",
"sent": "False",
"name": requestor['name'],
"status": "Pending",
"auto_cancel_date": cancel_date,
"cr_number": request.data['requested_to_template_id'],
"cr_name": request.data['requested_to_template_name'],
"company_requestedto": request.data['requested_to_company'],
"department_requestedto": request.data['requested_to_department'],
"priority_level": request.data['requested_to_priority'],
"url": "http://devweb.rms.oneberrysystem.com/login"
}
exist_cancel_template = models.CancelDateCR.objects.filter(
cr_number=request.data['requested_to_template_id']
)
if exist_cancel_template:
exist_cancel_template.delete()
models.CancelDateCR.objects.create(
cr_number=request.data['requested_to_template_id'],
trigger_date=cancel_date,
email_content=email_content_cancel
)
requested_to_target_date = parser.parse(
request.data['requested_to_target_date']
)
email_content_cancel['email_code'] = "RMS-CROVERDUE"
email_content_cancel['target_date'] = requested_to_target_date
overdue = requested_to_target_date + timedelta(days=30)
overdue = overdue.strftime('%Y-%m-%d 00:00:00.000')
models.TargetDateOverdue.objects.create(
cr_number=form_code,
trigger_date=overdue,
email_content=email_content_cancel
)
return True
def crhistory_save(action, entity, form_code, fromValue, toValue):
models.ChangeRequestHistory.objects.create(
action=action,
entity=entity,
form_code=form_code,
fromValue=fromValue,
toValue=toValue
)
return True
\ No newline at end of file
......@@ -3,6 +3,7 @@ from app.entities.models import User
import ast
from django.contrib.auth.hashers import make_password, check_password
import re
from django.contrib.auth import authenticate
class UserSerializer(serializers.ModelSerializer):
......@@ -19,6 +20,7 @@ class UserSerializer(serializers.ModelSerializer):
# 'password',
)
read_only_fields = (
'created', 'createdby', 'modified', 'modifiedby', 'code',
)
......@@ -27,34 +29,45 @@ class UserSerializer(serializers.ModelSerializer):
class ChangePasswordSerializer(serializers.Serializer):
old_password = serializers.CharField(required=True)
new_password = serializers.CharField(required=True, min_length=6)
new_password_confirm = serializers.CharField(required=True, min_length=6)
def validate(self, data):
instance = self.context.get("instance")
instance = self.context.get('view').kwargs['pk']
old_password = data['old_password']
new_password = data['new_password']
instance_password = User.objects.filter(
id=instance
)
validated_password = check_password(
old_password,
instance_password.values().first()['password']
)
if validated_password:
password = re.match(
'([A-Za-z]+[0-9]|[0-9]+[A-Za-z])[A-Za-z0-9]*',
data['new_password']
)
if password:
new_password = make_password(data['new_password'])
instance_password.update(password=new_password)
instance = User.objects.get(id=instance)
return instance
elif len(new_password) <= 5:
raise serializers.ValidationError(
'Password must be minimum of 6 characters'
)
else:
raise serializers.ValidationError(
'password must be alpha numeric format'
)
......
import copy
import threading
from app.entities import enums
from django.db import transaction
from app.helper.decorators import rms, error_safe
from app.helper import decorators
from rest_framework.views import APIView
from app.helper.email_service import sender
from rest_framework import viewsets, status
from rest_framework.decorators import action
from django.contrib.auth import authenticate
from django.contrib.auth.hashers import check_password
from rest_framework.response import Response
from django.forms.models import model_to_dict
from rest_framework.filters import SearchFilter, OrderingFilter
from app.entities.models import User, EntityLog, PasswordReset
from app.helper.decorators import rms, error_safe
from django_filters import rest_framework as filters
from django.contrib.auth.hashers import make_password
from app.entities.models import User, EntityLog
from app.applicationlayer.utils import (
CustomPagination, status_message_response, log_save
)
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import SearchFilter, OrderingFilter
from app.applicationlayer.management.account import serializer
from app.applicationlayer.management.account.table_filters import UserFilterSet
from rest_framework.decorators import action
from app.helper import decorators
from django.contrib.auth import authenticate
from app.helper.email_service import sender
import threading
from app.applicationlayer.utils import (
CustomPagination, status_message_response, log_save,
main_threading
)
from rest_framework.exceptions import ParseError
class UserViewSet(viewsets.ModelViewSet):
......@@ -31,31 +35,41 @@ class UserViewSet(viewsets.ModelViewSet):
ordering_fields = '__all__'
search_fields = ('name',)
# @check.user_type
@rms.user_create
@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)
password = User.objects.make_random_password(length=10)
password_hash = make_password(password)
User.objects.filter(
id=serializer.data['id']
).update(password=password_hash)
message = status_message_response(
201, 'success',
'New Users created', serializer.data
)
args = [request.data['name'], request.data['username'], password, request.user.email]
t1 = threading.Thread(target=sender.account_created, args=(args,))
t1.start()
name = request.data['name']
username = request.data['username']
account_email = request.data['email']
admin_email = request.user.email
args = [name, username, password, account_email, admin_email]
main_threading(args, sender.account_created)
return Response(
message
message,
status=status.HTTP_201_CREATED
)
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
......@@ -68,12 +82,18 @@ class UserViewSet(viewsets.ModelViewSet):
'list of Users found',
serializer.data
)
return self.get_paginated_response(message)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
return Response(
serializer.data,
status=status.HTTP_200_OK
)
@rms.user_create
@error_safe
@transaction.atomic
def destroy(self, request, *args, **kwargs):
......@@ -92,6 +112,7 @@ class UserViewSet(viewsets.ModelViewSet):
return Response(status=status.HTTP_204_NO_CONTENT)
@rms.user_create
@transaction.atomic
def update(self, request, *args, **kwargs):
......@@ -112,63 +133,56 @@ class UserViewSet(viewsets.ModelViewSet):
new_instance
)
return Response(serializer.data)
# @action(detail=True,
# methods=['put'],
# url_path='upload-profile-picture',
# name="Uploads Profile Picture of User")
# @decorators.error_safe
# @transaction.atomic
# def UploadProfilePicture(self, request, pk=None):
# existingUser = models.User.objects.filter(id=pk).first()
# if existingUser:
# eximages = models.UserImage.objects.filter(user_id=pk)
# if (eximages):
# for item in eximages:
# item.delete()
# # DELETE FROM PHYSICAL
# FileHelper.DeleteFile(path=item.image.path)
# self.serializer_class = app_serializers.UserImageSerializer
# serializer = self.get_serializer(data=request.data)
# serializer.is_valid(raise_exception=True)
# self.perform_create(serializer)
# headers = self.get_success_headers(serializer.data)
# return Response(serializer.data,
# status=status.HTTP_201_CREATED,
# headers=headers)
# else:
# raise Exception('User not found')
# return Response(data={"detail": "Success"})
# @action(detail=True,
# methods=['put'],
# url_path='reset-password',
# name="Reset Password of User")
# @decorators.error_safe
# @transaction.atomic
# def ResetPassword(self, request, pk=None):
# existingUser = models.User.objects.filter(id=pk).first()
# if existingUser:
# existingUser.set_password(settings.USER_DEFAULT_PASSWORD)
# fromObj = copy.copy(existingUser)
# existingUser.save()
# toObj = copy.copy(existingUser)
# log_save.log_save(
# enums.LogEnum.UPDATE.value,
# enums.LogEntitiesEnum.ROBOT.value,
# model_to_dict(fromObj),
# model_to_dict(toObj))
# else:
# raise Exception('User not found')
# return Response(data={"detail": "Success"})
return Response(
serializer.data,
status=status.HTTP_200_OK
)
@action(detail=True,
methods=['put'],
url_path='reset-password',
name="Reset Password of User")
@decorators.error_safe
@rms.user_create
@transaction.atomic
def ResetPassword(self, request, pk=None):
existingUser = User.objects.filter(id=pk).first()
if existingUser:
password = User.objects.make_random_password(length=10)
existingUser.set_password(password)
fromObj = copy.copy(existingUser)
existingUser.save()
toObj = copy.copy(existingUser)
log_save(
enums.LogEnum.UPDATE.value,
enums.LogEntitiesEnum.USER.value,
pk,
model_to_dict(fromObj),
model_to_dict(toObj))
name = existingUser.name
username = existingUser.username
account_email = existingUser.email
admin_email = request.user.email
args = [name, username, password, account_email, admin_email]
main_threading(args, sender.admin_changepassword)
else:
raise Exception('User not found')
return Response(
{"detail": "Success"},
status=status.HTTP_200_OK
)
@action(detail=True,
methods=['put'],
......@@ -177,42 +191,45 @@ class UserViewSet(viewsets.ModelViewSet):
@decorators.error_safe
@transaction.atomic
def ChangePassword(self, request, pk=None):
self.serializer_class = serializer.ChangePasswordSerializer
serialized = self.get_serializer(data=request.data, context={'id': pk})
data = self.get_serializer(data=request.data)
if data.is_valid():
if serialized.is_valid():
form = copy.deepcopy(data.validated_data)
# form = copy.deepcopy(serialized.validated_data)
form = request.data
if form['new_password'] != form['new_password_confirm']:
raise Exception('Passwords must match')
existingUser = User.objects.filter(id=pk).first()
if existingUser:
user = authenticate(
username=existingUser.username,
password=form['old_password'])
if user:
existingUser.set_password(form['new_password_confirm'])
# password = make_password(request.data['password'])
fromObj = copy.copy(existingUser)
existingUser.save()
toObj = copy.copy(existingUser)
# log_save.log_save(
# enums.LogEnum.UPDATE.value,
# enums.LogEntitiesEnum.ROBOT.value,
# model_to_dict(fromObj),
# model_to_dict(toObj))
return Response(data={"detail": "Success"},
status=200)
else:
raise Exception("Invalid Old Password")
existingUser.set_password(form['new_password_confirm'])
fromObj = copy.copy(existingUser)
existingUser.save()
toObj = copy.copy(existingUser)
log_save(
enums.LogEnum.UPDATE.value,
enums.LogEntitiesEnum.USER.value,
pk,
model_to_dict(fromObj),
model_to_dict(toObj)
)
return Response(
{"message": "Password successfully changed"},
status=status.HTTP_200_OK
)
else:
raise Exception('User not found')
else:
serializer.is_valid(raise_exception=True)
serialized.is_valid(raise_exception=True)
return Response(data={"detail": "Error"}, status=500)
return Response(
data={"detail": "Error"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR
)
import threading
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from functools import wraps
......@@ -108,4 +109,13 @@ class QuerySetHelper:
with_params.append(filtering_kwargs)
raw_query = {"$or": with_params}
context.queryset = context.queryset(__raw__=raw_query)
return context.queryset
\ No newline at end of file
return context.queryset
def main_threading(args, func_name):
t1 = threading.Thread(
target=func_name, args=(args,),
daemon=False
)
t1.start()
return True
# Generated by Django 2.2 on 2019-09-11 10:26
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('entities', '0006_emaillogs_is_sent'),
]
operations = [
migrations.AlterModelTable(
name='emaillogs',
table='email_logs',
),
]
# Generated by Django 2.2 on 2019-09-11 11:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entities', '0006_emaillogs_is_sent'),
]
operations = [
migrations.AlterField(
model_name='changerequestformheader',
name='requested_to_template_id',
field=models.CharField(max_length=255),
),
]
# Generated by Django 2.2 on 2019-09-11 11:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entities', '0006_emaillogs_is_sent'),
]
operations = [
migrations.AlterField(
model_name='changerequestformheader',
name='requested_to_template_id',
field=models.CharField(max_length=255),
),
]
# Generated by Django 2.2 on 2019-09-11 17:15
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entities', '0007_auto_20190911_1102'),
]
operations = [
migrations.AlterField(
model_name='changerequesthistory',
name='form_code',
field=models.CharField(blank=True, max_length=255, null=True),
),
]
# Generated by Django 2.2 on 2019-09-11 17:15
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entities', '0007_auto_20190911_1102'),
]
operations = [
migrations.AlterField(
model_name='changerequesthistory',
name='form_code',
field=models.CharField(blank=True, max_length=255, null=True),
),
]
# Generated by Django 2.2 on 2019-09-11 11:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('entities', '0007_auto_20190911_1026'),
]
operations = [
migrations.CreateModel(
name='PasswordReset',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('email', models.EmailField(max_length=255)),
('token', models.CharField(max_length=255)),
('created_at', models.DateTimeField()),
('timeout_at', models.DateTimeField()),
('is_active', models.BooleanField(default=True)),
('code', models.CharField(max_length=50)),
],
options={
'db_table': 'password_resets',
},
),
]
# Generated by Django 2.2 on 2019-09-11 18:45
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('entities', '0008_auto_20190911_1715'),
]
operations = [
migrations.RenameField(
model_name='changerequestformapprovers',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequestformattachments',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequestformdetails',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequestformheader',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequestformstakeholders',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequesttemplateapprovers',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequesttemplateattachments',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequesttemplatedetails',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequesttemplateheader',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequesttemplatestakeholders',
old_name='deleted_at',
new_name='archived_at',
),
]
# Generated by Django 2.2 on 2019-09-11 18:45
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('entities', '0008_auto_20190911_1715'),
]
operations = [
migrations.RenameField(
model_name='changerequestformapprovers',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequestformattachments',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequestformdetails',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequestformheader',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequestformstakeholders',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequesttemplateapprovers',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequesttemplateattachments',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequesttemplatedetails',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequesttemplateheader',
old_name='deleted_at',
new_name='archived_at',
),
migrations.RenameField(
model_name='changerequesttemplatestakeholders',
old_name='deleted_at',
new_name='archived_at',
),
]
# Generated by Django 2.2 on 2019-09-13 11:43
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('entities', '0009_auto_20190911_1845'),
]
operations = [
migrations.RemoveField(
model_name='changerequestformapprovers',
name='archived_at',
),
migrations.RemoveField(
model_name='changerequestformattachments',
name='archived_at',
),
migrations.RemoveField(
model_name='changerequestformdetails',
name='archived_at',
),
migrations.RemoveField(
model_name='changerequestformheader',
name='archived_at',
),
migrations.RemoveField(
model_name='changerequestformstakeholders',
name='archived_at',
),
]
# Generated by Django 2.2 on 2019-09-13 11:43
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('entities', '0009_auto_20190911_1845'),
]
operations = [
migrations.RemoveField(
model_name='changerequestformapprovers',
name='archived_at',
),
migrations.RemoveField(
model_name='changerequestformattachments',
name='archived_at',
),
migrations.RemoveField(
model_name='changerequestformdetails',
name='archived_at',
),
migrations.RemoveField(
model_name='changerequestformheader',
name='archived_at',
),
migrations.RemoveField(
model_name='changerequestformstakeholders',
name='archived_at',
),
]
# Generated by Django 2.2 on 2019-09-13 15:45
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('entities', '0008_passwordreset'),
('entities', '0010_auto_20190913_1143'),
]
operations = [
]
......@@ -934,3 +934,28 @@ class EmailLogs(AuditClass):
recipients = models.CharField(max_length=255)
content = models.TextField()
is_sent = models.BooleanField(default=True)
class Meta:
db_table = 'email_logs'
class PasswordReset(models.Model):
email = models.EmailField(max_length=255)
token = models.CharField(max_length=255)
created_at = models.DateTimeField()
timeout_at = models.DateTimeField()
is_active = models.BooleanField(default=True)
code = models.CharField(max_length=50)
# def save(self, *args, **kwargs):
# super(PasswordReset, self).save(*args, **kwargs)
# timeout_at = created_at + datetime.timedelta(days=1)
# if self.timeout_at == '':
# self.timeout_at = timeout_at
# self.save()
def __str__(self):
return self.email
class Meta:
db_table = 'password_resets'
......@@ -59,6 +59,15 @@ class rms:
# return function(self, request, *args, **kwargs)
# return wrapper
@staticmethod
def admin_permission(function):
@wraps(function)
def wrapper(self, request, *args, **kwargs):
if rms.user_type(self) == rms.enums_user:
raise ParseError(access_error)
return function(self, request, *args, **kwargs)
return wrapper
@staticmethod
def user_create(function):
@wraps(function)
......
......@@ -7,111 +7,139 @@ from django.conf import settings
# def account_created(args, username, password, receiver) :
def account_created(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)
try:
send_mail(
subject='OB RMS: Welcome!',
message='',
from_email=settings.EMAIL_DEFAULT_SENDER,
recipient_list=(recipient,),
html_message=FC,
fail_silently=False
)
models.EmailLogs.objects.create(
template='RMS-NEWUSER.html',
recipients=recipient,
content=FC,
is_sent=True,
createdby=admin,
modifiedby=admin
)
except Exception as e:
models.EmailLogs.objects.create(
template='RMS-NEWUSER.html',
recipients=recipient,
content=FC,
is_sent=False,
createdby=admin,
modifiedby=admin
)
return True
def forgot_password(args):
reset_code = args[0]
url = args[1]
recipient = args[2]
admin = args[3]
F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, 'RMS-PASSWORD.html'), 'r')
FC = F.read()
FC = FC.replace('{code}', reset_code)
FC = FC.replace('{url}', url)
send_mail(
subject='OB RMS: Reset Password',
message='',
from_email=settings.EMAIL_DEFAULT_SENDER,
recipient_list=[recipient,],
html_message=FC
)
try:
send_mail(
subject='OB RMS: Welcome!',
message='',
from_email=settings.EMAIL_DEFAULT_SENDER,
recipient_list=recipient,
html_message=FC,
fail_silently=False
)
models.EmailLogs.objects.create(
template='RMS-PASSWORD.html',
recipients=recipient,
content=FC,
is_sent=True,
createdby=admin,
modifiedby=admin
)
except Exception as e:
models.EmailLogs.objects.create(
template='RMS-PASSWORD.html',
recipients=recipient,
content=FC,
is_sent=False,
createdby=admin,
modifiedby=admin
)
F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, 'RMS-NEWUSER.html'), 'r')
FC = F.read()
FC = FC.replace('{name}', args[0])
FC = FC.replace('{username}', args[1])
FC = FC.replace('{password}', args[2])
FC = FC.replace('[URL]', settings.FRONT_END_URL)
# send_mail(
# subject='OB IMS: Welcome!',
# message='',
# from_email=settings.EMAIL_DEFAULT_SENDER,
# recipient_list=[args[3],],
# html_message=FC,
# fail_silently=True
# )
try:
send_mail(
subject='OB IMS: Welcome!',
message='',
from_email=settings.EMAIL_DEFAULT_SENDER,
recipient_list=[args[3],],
html_message=FC,
fail_silently=False
)
models.EmailLogs.objects.create(
template='RMS-NEWUSER.html',
recipients=args[3],
content=FC,
is_sent=True,
createdby=args[3],
modifiedby=args[3]
)
except Exception as e:
models.EmailLogs.objects.create(
template='RMS-NEWUSER.html',
recipients=args[3],
content=FC,
is_sent=False,
createdby=args[3],
modifiedby=args[3]
)
# def account_created(name, username, password, receiver):
# 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)
# send_mail(
# subject='RMS: Welcome!',
# message='',
# from_email=settings.EMAIL_DEFAULT_SENDER,
# recipient_list=[receiver,],
# html_message=FC
# )
# def forgot_password(reset_code, url, receiver) :
# F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, 'forgot-password.html'), 'r')
# def password_changed(username, date, receiver) :
# F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, 'password-changed.html'), 'r')
# FC = F.read()
# FC = F.read()
# FC = FC.replace('[reset_code]', reset_code)
# FC = FC.replace('[URL]', url)
# FC = FC.replace('[Username]', username)
# FC = FC.replace('[Datetime]', date)
# FC = FC.replace('[URL]', settings.FRONT_END_URL)
# send_mail(
# subject='OB IMS: Reset Password',
# message='',
# from_email=settings.EMAIL_DEFAULT_SENDER,
# recipient_list=[receiver,],
# html_message=FC
# )
# send_mail(
# subject='OB RMS: Password Changed!',
# message='',
# from_email=settings.EMAIL_DEFAULT_SENDER,
# recipient_list=[receiver,],
# html_message=FC
# )
# def password_changed(username, date, receiver) :
def admin_changepassword(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, 'password-changed.html'), 'r')
F = open(os.path.join(settings.EMAIL_TEMPLATES_ROOT, 'RMS-ADMINRESET.html'), 'r')
# FC = F.read()
FC = F.read()
# FC = FC.replace('[Username]', username)
# FC = FC.replace('[Datetime]', date)
# FC = FC.replace('[URL]', settings.FRONT_END_URL)
FC = FC.replace('{name}', name)
FC = FC.replace('{username}', username)
FC = FC.replace('{password}', password)
FC = FC.replace('[URL]', settings.FRONT_END_URL)
# send_mail(
# subject='OB IMS: Password Changed!',
# message='',
# from_email=settings.EMAIL_DEFAULT_SENDER,
# recipient_list=[receiver,],
# html_message=FC
# )
send_mail(
subject='OB RMS: Password Changed!',
message='',
from_email=settings.EMAIL_DEFAULT_SENDER,
recipient_list=[recipient,],
html_message=FC
)
# def account_created(username, password, receiver) :
......
<!DOCTYPE html>
<html>
<head>
<title>RMS: Acknowledgement Notification</title>
</head>
<body style="font-family: arial;">
<img src="https://s18.directupload.net/images/190807/wjwrxx5i.jpg" width="100px" />
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Change Request Acknowledgement Notification</h3><br>
<p>Dear {name},</p><br>
<p>A change request has been submitted for your acknowledgement. Please see the details of the change request below.</p><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>Status</b><br>{status}<br><br>
<p>Please click <u><a href="{url}" style="text-decoration:underline;color:#007bff;" target="_blank">here</a></u> to access the change request.</p><br>
<p>Sincerely,</p>
<p>RMS Team</p><br><br>
<p>Powered by</p>
<img src="https://s18.directupload.net/images/190807/jaewp4nx.png" width="120px"/>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>RMS: Approval Notification</title>
</head>
<body style="font-family: arial;">
<img src="https://s18.directupload.net/images/190807/wjwrxx5i.jpg" width="100px" />
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Change Request Approval Notification</h3><br>
<p>Dear {name},</p><br>
<p>A change request has been submitted for your approval. Please see the details of the change request below.</p><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>Status</b><br>{status}<br><br>
<p>Please click <u><a href="{url}" style="text-decoration:underline;color:#007bff;" target="_blank">here</a></u> to access the change request.</p><br>
<p>Sincerely,</p>
<p>RMS Team</p><br><br>
<p>Powered by</p>
<img src="https://s18.directupload.net/images/190807/jaewp4nx.png" width="120px"/>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>RMS: New User Created</title>
</head>
<body style="font-family: arial;">
<div style="max-width:100px!important;">
<img src="https://s18.directupload.net/images/190807/wjwrxx5i.jpg"/>
</div>
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Reset Password</h3><br>
<p>Dear {name},</p><br>
<p>Your password have been reset by the admin. Please see details below.</p><br>
<b>Username</b><br>{username}<br><br>
<b>Password</b><br>{password}<br><br>
<p>You may change your password through the <u><a href="http://staging.rms.oneberrysystem.com/cms/profile/" style="text-decoration:underline;color:#007bff;" target="_blank">my profile</a></u> section of RMS any time.</p><br>
<p>Sincerely,</p>
<p>RMS Team</p><br><br>
<p>Powered by</p>
<img src="https://s18.directupload.net/images/190807/jaewp4nx.png" width="120px"/>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>RMS: Change Request Accepted</title>
</head>
<body style="font-family: arial;">
<img src="https://s18.directupload.net/images/190807/wjwrxx5i.jpg" width="100px"/>
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Change Request Accepted</h3><br>
<p>Dear {name},</p><br>
<p>A change request you have completed has been accepted by the requestor. Please see the details of your change request below.</p><br>
<b>Accepted By</b><br>{accepted_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://s18.directupload.net/images/190807/jaewp4nx.png" width="120px"/>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>RMS: Change Request Acknowledged</title>
</head>
<body style="font-family: arial;">
<img src="https://s18.directupload.net/images/190807/wjwrxx5i.jpg" width="100px"/>
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Change Request Acknowledged</h3><br>
<p>Dear {name},</p><br>
<p>Your change request has been acknowledged. Please see the details of your change request below.</p><br>
<b>Acknowledged By</b><br>{acknowledge_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 the change request.</p><br>
<p>Sincerely,</p>
<p>RMS Team</p><br><br>
<p>Powered by</p>
<img src="https://s18.directupload.net/images/190807/jaewp4nx.png" width="120px"/>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>RMS: Change Request Approved</title>
</head>
<body style="font-family: arial;">
<img src="https://s18.directupload.net/images/190807/wjwrxx5i.jpg" width="100px"/>
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Change Request Approved</h3><br>
<p>Dear {name},</p><br>
<p>Your change request has been approved. Please see the details of your change request below.</p><br>
<b>Approved By</b><br>{approved_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://s18.directupload.net/images/190807/jaewp4nx.png" width="120px"/>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>RMS: Change Request Cancelled</title>
</head>
<body style="font-family: arial;">
<img src="https://s18.directupload.net/images/190807/wjwrxx5i.jpg" width="100px"/>
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Change Request Cancelled</h3><br>
<p>Dear {name},</p><br>
<p>Your change request has been cancelled. Please see the details of your change request below.</p><br>
<b>Auto-Cancel Date</b><br>{auto_cancel_date}<br><br>
<b>Date Submitted to Last Approver</b><br>{date_submitted_last_approver}<br><br>
<b>Approver Pending Action</b><br>{approver_pending_action}<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>Status</b><br>{status}<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://s18.directupload.net/images/190807/jaewp4nx.png" width="120px"/>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>RMS: Change Request Completed</title>
</head>
<body style="font-family: arial;">
<img src="https://s18.directupload.net/images/190807/wjwrxx5i.jpg" width="100px"/>
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Change Request Completed</h3><br>
<p>Dear {name},</p><br>
<p>Your change request has been completed. Please see the details of your change request below.</p><br>
<b>Completed By</b><br>{completed_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://s18.directupload.net/images/190807/jaewp4nx.png" width="120px"/>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>RMS: Target Date Overdue</title>
</head>
<body style="font-family: arial;">
<img src="https://s18.directupload.net/images/190807/wjwrxx5i.jpg" width="100px"/>
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Change Request Target Date Overdue</h3><br>
<p>Dear {name},</p><br>
<p>Please be informed that the change request&apos;s target date is overdue. Please see the details of your change request below.</p><br>
<b>Target Date</b><br>{target_date}<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>Status</b><br>{status}<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://s18.directupload.net/images/190807/jaewp4nx.png" width="120px"/>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>RMS: Change Request Rejected</title>
</head>
<body style="font-family: arial;">
<img src="https://s18.directupload.net/images/190807/wjwrxx5i.jpg" width="100px"/>
<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 completed has been rejected by the requestor.Please see the details of your change request below.</p><br>
<b>Rejected By</b><br>{rejected_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://s18.directupload.net/images/190807/jaewp4nx.png" width="120px"/>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>RMS: Change Request Rejected</title>
</head>
<body style="font-family: arial;">
<img src="https://s18.directupload.net/images/190807/wjwrxx5i.jpg" width="100px"/>
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Change Request Rejected</h3><br>
<p>Dear {name},</p><br>
<p>Your change request has been rejected. Please see the details of your change request below.</p><br>
<b>Rejected By</b><br>{rejected_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://s18.directupload.net/images/190807/jaewp4nx.png" width="120px"/>
</body>
</html>
\ No newline at end of file
......@@ -16,7 +16,7 @@
<p>You have been created as a new user of RMS. Please see your default login details below.</p><br>
<b>Username</b><br>{username}<br><br>
<b>Password</b><br>{password}<br><br>
<b>Password</b><br>password123<br><br>
<p>You may change your password through the <u><a href="http://staging.rms.oneberrysystem.com/cms/profile/" style="text-decoration:underline;color:#007bff;" target="_blank">my profile</a></u> section of RMS any time.</p><br>
......
<!DOCTYPE html>
<html>
<head>
<title>RMS: Reset Password</title>
</head>
<body style="font-family: arial;">
<img src="https://s18.directupload.net/images/190807/wjwrxx5i.jpg" width="100px"/>
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Reset Password</h3><br>
<p>Dear {name},</p><br>
<p>To reset your password click this <u><a href="{url}" style="text-decoration:underline;color:#007bff;" target="_blank">link</a></u> and enter code <strong>{code}</strong>.</p><br>
<p>Sincerely,</p>
<p>RMS Team</p><br><br>
<p>Powered by</p>
<img src="https://s18.directupload.net/images/190807/jaewp4nx.png" width="120px"/>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>RMS: Approval Reminder</title>
</head>
<body style="font-family: arial;">
<img src="https://s18.directupload.net/images/190807/wjwrxx5i.jpg" width="100px"/>
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Change Request Approval Reminder</h3><br>
<p>Dear {name},</p><br>
<p>Please be reminded that a change request is pending your approval. Please note that it will automatically be cancelled by the system if no action is taken within 30 days from the date it was submitted for your approval.</p><br>
<b>Auto-Cancel Date</b><br>{auto_cancel_date}<br><br>
<b>Date Submitted to Last Approver</b><br>{date_submitted_last_approver}<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>Status</b><br>{status}<br><br>
<p>Please click <u><a href="{url}" style="text-decoration:underline;color:#007bff;" target="_blank">here</a></u> to access the change request.</p><br>
<p>Sincerely,</p>
<p>RMS Team</p><br><br>
<p>Powered by</p>
<img src="https://s18.directupload.net/images/190807/jaewp4nx.png" width="120px"/>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>RMS: Approval Reminder</title>
</head>
<body style="font-family: arial;">
<img src="https://s18.directupload.net/images/190807/wjwrxx5i.jpg" width="100px"/>
<h3>Resource Management System &#40;RMS&#41;</h3>
<h3 style="color:#888888;">Change Request Approval Reminder</h3><br>
<p>Dear {name},</p><br>
<p>Please be informed that a reminder has been sent to approve your change request. Please note that it will automatically be cancelled by the system if no action is taken within 30 days from the date it was submitted to the last approving officer.</p><br>
<b>Auto-Cancel Date</b><br>{auto_cancel_date}<br><br>
<b>Date Submitted to Last Approver</b><br>{date_submitted_last_approver}<br><br>
<b>Approver Pending Action</b><br>{approver_pending_action}<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>Status</b><br>{status}<br><br>
<p>Please click <u><a href="{url}" style="text-decoration:underline;color:#007bff;" target="_blank">here</a></u> to access the change request.</p><br>
<p>Sincerely,</p>
<p>RMS Team</p><br><br>
<p>Powered by</p>
<img src="https://s18.directupload.net/images/190807/jaewp4nx.png" width="120px"/>
</body>
</html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div style="background-color: rgba(255,255,255,0.7); padding: 10px; margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://s3-ap-southeast-1.amazonaws.com/oneberry/img/logo_oneberry.png" style="margin: 10px auto; max-width: 200px; height: auto;" />
<br><br>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<br/>
<p>Your account for the Inventory Management System have been successfully <br>created.</p>
<br/>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<table>
<tr><td> <br> URL:</td><td > <br> <span style="margin-left:65px;"> <a href="[URL]">[URL]</a> </span></td></tr>
<tr><td> <br> Username: </td><td> <br> <span style="margin-left:65px;">[Username]</span></td></tr>
<tr><td> <br> Password: </td><td> <br> <span style="margin-left:65px;">[Password]</span></td><td><span><small style="color:red;"><br>(Upon login, please change your password)</small> </span></tr>
</table>
<br>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>**This is a system generated email, do not reply to this email.**</small>
</td>
</tr>
</table>
</div>
</body>
</html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;" >
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7); padding: 10px; margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td width="100px">Subject:</td>
<td>Confirmed Order <span style="background-color: yellow;">[PO Number]</span>: Project Number, Supplier, Item</td>
</tr>
<tr bgcolor="#FFFFFF">
<td width="100px">Attachment:</td>
<td><span style="background-color: yellow;">[Authorised Purchase Order]</span></td>
</tr>
</table>
</div>
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7); padding: 10px; margin-bottom: 10px;">
<h3 style="text-align: center;">Email Template</h3>
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://inventory.tirapp.com/cds/image.ashx?id=CDS_IMAGE_39117a66-0738-40cb-9bf4-51a7d53abe50&v=20170125071840" style="margin: 10px auto;" />
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Dear [Supplier]</p>
<br/>
<p>We would like to confirm our order of the items, please see our PO as attached.</p>
<p>Kindly please deliver the items with the related invoice.</p>
<br/>
<p>Thank you,</p>
<p>[Purchasing] </p>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>Template Created by TIR Solutions</small>
</td>
</tr>
</table>
</div>
</body></html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7); padding: 10px; margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td width="100px">Subject:</td>
<td><span style="background-color: yellow;">[Stock Requisition No.]</span> Collection </td>
</tr>
</table>
</div>
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);" >
<h3 style="text-align: center;">Email Template</h3>
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://inventory.tirapp.com/cds/image.ashx?id=CDS_IMAGE_39117a66-0738-40cb-9bf4-51a7d53abe50&v=20170125071840" style="margin: 10px auto;" />
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Dear [Requestor]</p>
<br/>
<p>In regards to <span style="background-color: yellow;">[Stock Requisition No.]</span>, your order is ready for pick up at the following details: </p>
<table>
<tr><td>Location: </td><td><span style="background-color: yellow;">[Location]</span></td></tr>
<tr><td>Date: </td><td><span style="background-color: yellow;">[Date]</span></td></tr>
<tr><td>Time: </td><td><span style="background-color: yellow;">[Time]</span></td></tr>
</table>
<p><span style="background-color: yellow;">[Copy the items list from Stock Request Email and paste here]<span></p>
<br/>
<p>Thank you,</p>
<p>[Storekeeper] </p>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>Template Created by TIR Solutions</small>
</td>
</tr>
</table>
</div>
</body></html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td width="100px">Subject:</td>
<td>Order Query: <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">Project Number</span>, Supplier, Item</td>
</tr>
<tr bgcolor="#FFFFFF">
<td width="100px">Attachment:</td>
<td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Draft Purchase Order]</span></td>
</tr>
</table>
</div>
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<h3 style="text-align: center;">Email Template</h3>
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://inventory.tirapp.com/cds/image.ashx?id=CDS_IMAGE_39117a66-0738-40cb-9bf4-51a7d53abe50&v=20170125071840" style="margin: 10px auto;" />
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Dear [Supplier]</p>
<br/>
<p>We would like to purchase the following items, please see details attached. </p>
<p>Please confirm or complete the details on our attached request</p>
<p>On confirmation of the above, we will then issue an authorised purchase order. </p>
<br/>
<p>Thank you,</p>
<p>[Purchasing] </p>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>Template Created by TIR Solutions</small>
</td>
</tr>
</table>
</div>
</body></html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div style="background-color: rgba(255,255,255,0.7); padding: 10px; margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://s3-ap-southeast-1.amazonaws.com/oneberry/img/logo_oneberry.png" style="margin: 10px auto; max-width: 200px; height: auto;" />
<br><br>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align='center'>
<br/>
<p>You have requested to reset your password.</p>
<br/>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align='center'>
<br>
<h1>Reset Code</h1>
<h1>[reset_code]</h1>
<br><br>
<span> <a href="[URL]">[URL]</a> </span>
<br>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>**This is a system generated email, do not reply to this email.**</small>
</td>
</tr>
</table>
</div>
</body>
</html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td width="100px">Subject:</td>
<td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[PO Number]</span> Items Received</td>
</tr>
</table>
</div>
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<h3 style="text-align: center;">Email Template</h3>
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://inventory.tirapp.com/cds/image.ashx?id=CDS_IMAGE_39117a66-0738-40cb-9bf4-51a7d53abe50&v=20170125071840" style="margin: 10px auto;" />
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Dear [Purchasing/Janet & Finance/Suzanna]</p>
<br/>
<p>In regards to <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[PO number]</span>, items were well received at <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[location]</span> on <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[date]</span> and inventory has been recorded in the system</p>
<br/>
<p>Thank you,</p>
<p>[Storekeeper] </p>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>Template Created by TIR Solutions</small>
</td>
</tr>
</table>
</div>
</body></html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td width="100px">Subject:</td>
<td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[PO Number]</span> Items Delivered</td>
</tr>
</table>
</div>
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<h3 style="text-align: center;">Email Template</h3>
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://inventory.tirapp.com/cds/image.ashx?id=CDS_IMAGE_39117a66-0738-40cb-9bf4-51a7d53abe50&v=20170125071840" style="margin: 10px auto;" />
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Dear [Requestor]</p>
<br/>
<p>With regards to <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[PO number]</span>, items have been delivered to <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[location]</span> and recorded in the system.</p>
<p>Please login and apply the Stock Requisition.</p>
<br/>
<p>Thank you,</p>
<p>[Storekeeper] </p>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>Template Created by TIR Solutions</small>
</td>
</tr>
</table>
</div>
</body></html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td width="100px">Subject:</td>
<td>Order Request for <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Project Number]</span> NEW Items</td>
</tr>
</table>
</div>
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<h3 style="text-align: center;">Email Template</h3>
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://inventory.tirapp.com/cds/image.ashx?id=CDS_IMAGE_39117a66-0738-40cb-9bf4-51a7d53abe50&v=20170125071840" style="margin: 10px auto;" />
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Dear [Requestor]</p>
<br/>
<p>The items you have requested is now on the system.</p>
<table>
<tr><td>Project: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Project Number]</span></td></tr>
<tr><td>Required by Date: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Date]</span></td></tr>
</table>
<br/>
<p>Here are the <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">Product Details</span>, Brand, Model, <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">Specifications</span>, Estimated Cost, and Reference Photos:
<p><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Product 1]<span></p>
<p>[Product 2]</p>
<br/>
<p>Please login to do a formal request. </p>
<br/>
<p>Thank you,</p>
<p>[Purchasing] </p>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>Template Created by TIR Solutions</small>
</td>
</tr>
</table>
</div>
</body></html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td width="100px">To:</td>
<td>ims@oneberry.com</td>
</tr>
<tr bgcolor="#FFFFFF">
<td width="100px">Subject:</td>
<td>New Project, <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Project Number]</span></td>
</tr>
</table>
</div>
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<h3 style="text-align: center;">Email Template</h3>
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://inventory.tirapp.com/cds/image.ashx?id=CDS_IMAGE_39117a66-0738-40cb-9bf4-51a7d53abe50&v=20170125071840" style="margin: 10px auto;" />
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Dear System Admin,</p>
<p>I would like to create a project below:</p>
<table>
<tr><td>Client: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Client]</span></td></tr>
<tr><td>Contact Number: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Contact Number]</span></td></tr>
<tr><td>Email: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Email]</span></td></tr>
<tr><td>Contact Person: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Contact Person]</span></td></tr>
</table>
<br/>
<table>
<tr><td>Project: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Project Number]</span></td></tr>
<tr><td>Project Description: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Project Description]</span></td></tr>
<tr><td>Start Date: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Start Date]</span></td></tr>
<tr><td>End Date: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[End Date]</span></td></tr>
</table>
<p>Locations (Optional)</p>
<table width='100%' bgcolor="#EEEEEE" cellpadding='0' cellspacing='1'>
<tr bgcolor="#FFFFFF">
<th>Name</th>
<th>Address</th>
<th>Coordinate</th>
</tr>
<tr bgcolor="#FFFFFF">
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
<br/>
<p>Thank you,</p>
<p>[Requestor]</p>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>Template Created by TIR Solutions</small>
</td>
</tr>
</table>
</div>
</body></html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td width="100px">To:</td>
<td>ims@oneberry.com</td>
</tr>
<tr bgcolor="#FFFFFF">
<td width="100px">Subject:</td>
<td>New User Account</td>
</tr>
</table>
</div>
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<h3 style="text-align: center;">Email Template</h3>
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://inventory.tirapp.com/cds/image.ashx?id=CDS_IMAGE_39117a66-0738-40cb-9bf4-51a7d53abe50&v=20170125071840" style="margin: 10px auto;" />
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Dear System Admin,</p>
<p>I would like to create an account below:</p>
<table>
<tr><td>Username: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Username]</span></td></tr>
<tr><td>Contact Number: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Contact Number]</span></td></tr>
<tr><td>Email: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Email]</span></td></tr>
<tr><td>Position/Designation: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Position/Designation]</span></td></tr>
</table>
<br/>
<p>Thank you,</p>
<p>[Requestor]</p>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>Template Created by TIR Solutions</small>
</td>
</tr>
</table>
</div>
</body></html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div style="background-color: rgba(255,255,255,0.7); padding: 10px; margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://s3-ap-southeast-1.amazonaws.com/oneberry/img/logo_oneberry.png" style="margin: 10px auto; max-width: 200px; height: auto;" />
<br><br>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<br/>
<p>Hello [Username], Your password has been changed on [Datetime].</p>
<p>If you did not perform this action, Please contact the Administrator.</p>
<p>You may login in this url <a href="[URL]">[URL]</a> .</p>
<br/>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>**This is a system generated email, do not reply to this email.**</small>
</td>
</tr>
</table>
</div>
</body>
</html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td width="100px">Subject:</td>
<td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[PO number]</span> mismatch from DO/Invoice</td>
</tr>
</table>
</div>
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<h3 style="text-align: center;">Email Template</h3>
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://inventory.tirapp.com/cds/image.ashx?id=CDS_IMAGE_39117a66-0738-40cb-9bf4-51a7d53abe50&v=20170125071840" style="margin: 10px auto;" />
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Dear [Purchasing/Janet]</p>
<br/>
<p>We received these items at <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[location]</span> on <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[date]</span> where DO/Invoice is mismatch.</p>
<p><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Quantity in PO is more than DO/Invoice]<span></p>
<p><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Price in Invoice is lower than PO]<span></p>
<br/>
<p>Please update your records accordingly or contact supplier for any issues.</p>
<br/>
<p>Thank you,</p>
<p>[Storekeeper]</p>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>Template Created by TIR Solutions</small>
</td>
</tr>
</table>
</div>
</body></html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td width="100px">Subject:</td>
<td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[PO Number]</span>: Project Number, Supplier, Item </td>
</tr>
<tr bgcolor="#FFFFFF">
<td width="100px">Subject:</td>
<td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Authorised Purchase Order]</span></td>
</tr>
</table>
</div>
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<h3 style="text-align: center;">Email Template</h3>
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://inventory.tirapp.com/cds/image.ashx?id=CDS_IMAGE_39117a66-0738-40cb-9bf4-51a7d53abe50&v=20170125071840" style="margin: 10px auto;" />
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Dear [Authoriser]</p>
<br/>
<p>Please approve this PO as attached. </p>
<br/>
<p>Thank you,</p>
<p>[Purchasing] </p>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>Template Created by TIR Solutions</small>
</td>
</tr>
</table>
</div>
</body></html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td width="100px">Subject:</td>
<td>Order Request for <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Project Number]</span> – Not Approved </td>
</tr>
</table>
</div>
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<h3 style="text-align: center;">Email Template</h3>
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://inventory.tirapp.com/cds/image.ashx?id=CDS_IMAGE_39117a66-0738-40cb-9bf4-51a7d53abe50&v=20170125071840" style="margin: 10px auto;" />
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Dear [Requestor]</p>
<br/>
<p>Your order request for the below items are not approved by <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[John/Ken]</span> because of <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Reason]</span>. Please check with them directly on the next steps.</p>
<table>
<tr><td>Project: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Project Number]</span></td></tr>
<tr><td>Required by Date: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Date]</span></td></tr>
</table>
<br/>
<p>Here are the Product Details & Specifications:</p>
<p><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Product 1]<span></p>
<p>[Product 2]</p>
<br/>
<p>Thank you,</p>
<p>[Purchasing] </p>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>Template Created by TIR Solutions</small>
</td>
</tr>
</table>
</div>
</body></html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div style="background-color: rgba(255,255,255,0.7); padding: 10px; margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://s3-ap-southeast-1.amazonaws.com/oneberry/img/logo_oneberry.png" style="margin: 10px auto; max-width: 200px; height: auto;" />
<br><br>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<br/>
<p>Your password has been reset as of [Reset Datetime].</p>
<br/>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<table>
<tr><td> <br> Username: </td><td> <br> <span style="margin-left:65px;">[Username]</span></td></tr>
<tr><td> <br> Password: </td><td> <br> <span style="margin-left:65px;">[Password]</span></td><td><span><small style="color:red;"><br>(Upon login, please change your password)</small> </span></tr>
</table>
<br>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>**This is a system generated email, do not reply to this email.**</small>
</td>
</tr>
</table>
</div>
</body>
</html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div style="background-color: rgba(255,255,255,0.7); padding: 10px; margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://s3-ap-southeast-1.amazonaws.com/oneberry/img/logo_oneberry.png" style="margin: 10px auto; max-width: 200px; height: auto;" />
<h3 style="text-align: center;">Stock Requisition Approved <br> [SR No]</h3>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<table>
<tr><td>Stock Requisition No: </td><td><span>[SR No]</span></td></tr>
<tr><td>Requestor: </td><td><span>[Requestor]</span></td></tr>
<tr><td>Requested On: </td><td><span>[Requested On]</span></td></tr>
<tr><td>Project: </td><td><span>[Project]</span></td></tr>
<tr><td>Remarks: </td><td><span>[Remarks]</span></td></tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<table>
<tr><td>Approved By: </td><td><span >[Approved By]</span></td></tr>
<tr><td>Approved On: </td><td><span >[Approved On]</span></td></tr>
<tr><td>Partial Reject Reason: </td><td><span >[Partial Reject Reason]</span></td></tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Approved Stock Request Items:</p>
<table width='100%' bgcolor="#EEEEEE" cellpadding='0' cellspacing='1'>
<tr bgcolor="#EEEEEE" align="left">
<th>Product No.</th>
<th>Product Name</th>
<th>Brand</th>
<th>Qty</th>
<th>Unit</th>
</tr>
<tr bgcolor="#FFFFFF" id="sr">
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Partial Rejected Stock Request Items:</p>
<table width='100%' bgcolor="#EEEEEE" cellpadding='0' cellspacing='1'>
<tr bgcolor="#EEEEEE" align="left">
<th>Product No.</th>
<th>Product Name</th>
<th>Brand</th>
<th>Qty</th>
<th>Unit</th>
</tr>
<tr bgcolor="#FFFFFF" id="sr">
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Approved Purchase Request Items (Required by [Required Date]):</p>
<table width='100%' bgcolor="#EEEEEE" cellpadding='0' cellspacing='1'>
<tr bgcolor="#EEEEEE" align="left">
<th>Product No.</th>
<th>Product Name</th>
<th>Brand</th>
<th>Qty</th>
<th>Unit</th>
</tr>
<tr bgcolor="#FFFFFF" id="pr">
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Partial Rejected Purchase Request Items:</p>
<table width='100%' bgcolor="#EEEEEE" cellpadding='0' cellspacing='1'>
<tr bgcolor="#EEEEEE" align="left">
<th>Product No.</th>
<th>Product Name</th>
<th>Brand</th>
<th>Qty</th>
<th>Unit</th>
</tr>
<tr bgcolor="#FFFFFF" id="pr">
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Note: Please contact the <b>requestor</b> on the collection details.</p>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>**This is a system generated email, do not reply to this email.**</small>
</td>
</tr>
</table>
</div>
</body>
</html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div style="background-color: rgba(255,255,255,0.7); padding: 10px; margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://s3-ap-southeast-1.amazonaws.com/oneberry/img/logo_oneberry.png" style="margin: 10px auto; max-width: 200px; height: auto;" />
<h3 style="text-align: center;">Stock Requisition Approved <br> [SR No]</h3>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<table>
<tr><td>Stock Requisition No: </td><td><span>[SR No]</span></td></tr>
<tr><td>Requestor: </td><td><span>[Requestor]</span></td></tr>
<tr><td>Requested On: </td><td><span>[Requested On]</span></td></tr>
<tr><td>Project: </td><td><span>[Project]</span></td></tr>
<tr><td>Remarks: </td><td><span>[Remarks]</span></td></tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<table>
<tr><td>Approved By: </td><td><span style="margin-left:50px;">[Approved By]</span></td></tr>
<tr><td>Approved On: </td><td><span style="margin-left:50px;">[Approved On]</span></td></tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Approved Stock Request Items:</p>
<table width='100%' bgcolor="#EEEEEE" cellpadding='0' cellspacing='1'>
<tr bgcolor="#EEEEEE" align="left">
<th>Product No.</th>
<th>Product Name</th>
<th>Brand</th>
<th>Qty</th>
<th>Unit</th>
</tr>
<tr bgcolor="#FFFFFF" id="sr">
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Approved Purchase Request Items (Required by [Required Date]):</p>
<table width='100%' bgcolor="#EEEEEE" cellpadding='0' cellspacing='1'>
<tr bgcolor="#EEEEEE" align="left">
<th>Product No.</th>
<th>Product Name</th>
<th>Brand</th>
<th>Qty</th>
<th>Unit</th>
</tr>
<tr bgcolor="#FFFFFF" id="pr">
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Note: Please contact the <b>requestor</b> on the collection details.</p>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>**This is a system generated email, do not reply to this email.**</small>
</td>
</tr>
</table>
</div>
</body>
</html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td width="100px">Subject:</td>
<td>Order Request for <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Project Number]</span> NEW Items</td>
</tr>
<tr bgcolor="#FFFFFF">
<td width="100px">CC:</td>
<td>ken@oneberry.com, john@oneberry.com, jennifer@oneberry.com</td>
</tr>
</table>
</div>
<div class="ob_EmailTemplatePanel" style="background-color: rgba(255,255,255,0.7);
padding: 10px;
margin-bottom: 10px;">
<h3 style="text-align: center;">Email Template</h3>
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://inventory.tirapp.com/cds/image.ashx?id=CDS_IMAGE_39117a66-0738-40cb-9bf4-51a7d53abe50&v=20170125071840" style="margin: 10px auto;" />
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Dear [Purchasing/Janet]</p>
<br/>
<p>I would like to request to purchase the following items, please see below:</p>
<table>
<tr><td>Project: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Project Number]</span></td></tr>
<tr><td>Required by Date: </td><td><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Date]</span></td></tr>
</table>
<br/>
<p>Here are the <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">Product Details</span>, Brand, Model, <span class="ob_EmailTemplateHighlight" style="background-color: yellow;">Specifications</span>, Estimated Cost, and Reference Photos:
<p><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Product 1]<span></p>
<p>[Product 2]</p>
<br/>
<p>Intended use of these items:</p>
<p><span class="ob_EmailTemplateHighlight" style="background-color: yellow;">[Information on application]<span></p>
<br>
<p>Here are the suggested suppliers:</p>
<p>[List Suppliers]</p>
<br>
<p>[Any other information eg. Product of origin]</p>
<p>OR</p>
<p>Please help us source suppliers</p>
<br/>
<p>Thank you,</p>
<p>[Requestor]</p>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>Template Created by TIR Solutions</small>
</td>
</tr>
</table>
</div>
<div class="ob_EmailTemplatePanel">
<h3>Additional Template to paste to <span class="ob_EmailTemplateHighlight">[Product ?]</span></h3>
<table width="570px" bgcolor="#FFFFFF" style="border: 1px solid #999999;">
<tr>
<td width="100px">Product Details:</td>
<td><span class="ob_EmailTemplateHighlight">[Product Details]</span></td>
</tr>
<tr>
<td width="100px">Brand:</td>
<td>[Brand]</td>
</tr>
<tr>
<td width="100px">Model:</td>
<td>[Model]</td>
</tr>
<tr>
<td width="100px">Specifications:</td>
<td><span class="ob_EmailTemplateHighlight">[Specifications]</span></td>
</tr>
<tr>
<td width="100px">Estimated Cost:</td>
<td>[Estimated Cost]</td>
</tr>
<tr>
<td width="100px">Reference Photos:</td>
<td>[Reference Photos]</td>
</tr>
</table>
</div>
</body></html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div style="background-color: rgba(255,255,255,0.7); padding: 10px; margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://s3-ap-southeast-1.amazonaws.com/oneberry/img/logo_oneberry.png" style="margin: 10px auto; max-width: 200px; height: auto;" />
<h3 style="text-align: center;">Stock Requisition Rejected <br> [SR No]</h3>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<table>
<tr><td>Stock Requisition No: </td><td><span>[SR No]</span></td></tr>
<tr><td>Requestor: </td><td><span>[Requestor]</span></td></tr>
<tr><td>Requested On: </td><td><span>[Requested On]</span></td></tr>
<tr><td>Project: </td><td><span>[Project]</span></td></tr>
<tr><td>Remarks: </td><td><span>[Remarks]</span></td></tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<table>
<tr><td>Rejected By: </td><td><span style="margin-left:30px;">[Rejected By]</span></td></tr>
<tr><td>Rejected On: </td><td><span style="margin-left:30px;">[Rejected On]</span></td></tr>
<tr><td>Rejected Reason: </td><td><span style="margin-left:30px;">[Rejected On]</span></td></tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Rejected Stock Request Items:</p>
<table width='100%' bgcolor="#EEEEEE" cellpadding='0' cellspacing='1'>
<tr bgcolor="#EEEEEE" align="left">
<th>Product No.</th>
<th>Product Name</th>
<th>Brand</th>
<th>Qty</th>
<th>Unit</th>
</tr>
<tr bgcolor="#FFFFFF" id="sr">
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Rejected Purchase Request Items (Required by [Required Date]):</p>
<table width='100%' bgcolor="#EEEEEE" cellpadding='0' cellspacing='1'>
<tr bgcolor="#EEEEEE" align="left">
<th>Product No.</th>
<th>Product Name</th>
<th>Brand</th>
<th>Qty</th>
<th>Unit</th>
</tr>
<tr bgcolor="#FFFFFF" id="pr">
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>**This is a system generated email, do not reply to this email.**</small>
</td>
</tr>
</table>
</div>
</body>
</html>
\ No newline at end of file
<html>
<body style="background-color: #ccc;">
<div style="background-color: rgba(255,255,255,0.7); padding: 10px; margin-bottom: 10px;">
<table bgcolor="#EEEEEE" width="600px" cellpadding="10px" style="border: 1px solid #999999; margin: 0 auto;">
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<img src="https://s3-ap-southeast-1.amazonaws.com/oneberry/img/logo_oneberry.png" style="margin: 10px auto; max-width: 200px; height: auto;" />
<h3 style="text-align: center;">Stock Requisition</h3>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<table>
<tr><td>Stock Requisition No: </td><td><span>[SR No]</span></td></tr>
<tr><td>Requestor: </td><td><span>[Requestor]</span></td></tr>
<tr><td>Requested On: </td><td><span>[Requested On]</span></td></tr>
<tr><td>Project: </td><td><span>[Project]</span></td></tr>
<tr><td>Remarks: </td><td><span>[Remarks]</span></td></tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Stock Request Items:</p>
<table width='100%' bgcolor="#EEEEEE" cellpadding='0' cellspacing='1'>
<tr bgcolor="#EEEEEE" align="left">
<th>Product No.</th>
<th>Product Name</th>
<th>Brand</th>
<th>Qty</th>
<th>Unit</th>
</tr>
<tr bgcolor="#FFFFFF" id="sr">
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2">
<p>Purchase Request Items (Required by [Required Date]):</p>
<table width='100%' bgcolor="#EEEEEE" cellpadding='0' cellspacing='1'>
<tr bgcolor="#EEEEEE" align="left">
<th>Product No.</th>
<th>Product Name</th>
<th>Brand</th>
<th>Qty</th>
<th>Unit</th>
</tr>
<tr bgcolor="#FFFFFF" id="pr">
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<span>
<button style="cursor: pointer; font-weight: bold; background-color:#E52129; border-color:#E52129; padding: 15px 25px 15px 25px; border-radius: 8px; font-size: 15px;" ><a href="RejectToken" style="color: white; text-decoration: none;">REJECT</a></button>
&nbsp;
&nbsp;
<button style="cursor: pointer; font-weight: bold; background-color:#008000; border-color:#008000; padding: 15px 95px 15px 95px; border-radius: 8px; font-size: 15px;"><a href="ApproveToken" style="color: white; text-decoration: none;">APPROVE</a></button>
</span>
</td>
</tr>
<tr bgcolor="#FFFFFF">
<td colspan="2" align="center">
<small>**This is a system generated email, do not reply to this email.**</small>
</td>
</tr>
</table>
</div>
</body>
</html>
\ No newline at end of file
......@@ -37,4 +37,7 @@ VENDOR_ACKNOWLEDGE_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_ACKNOWLEDGE_ME
REQUESTOR_ACKNOWLEDGE_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_ACKNOWLEDGE_MESSAGE']
REQUESTOR_COMPLETION_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_COMPLETION_MESSAGE']
VENDOR_ACCEPTANCE_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_ACCEPTANCE_MESSAGE']
VENDOR_REJECT_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_REJECT_MESSAGE']
\ No newline at end of file
VENDOR_REJECT_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_REJECT_MESSAGE']
#ADMIN PROFILE
CATCH_EMAIL = config['ADMIN']['CATCH_EMAIL']
......@@ -36,3 +36,6 @@ REQUESTOR_ACKNOWLEDGE_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_ACKNOWLE
REQUESTOR_COMPLETION_MESSAGE = config['NOTIFICATION_EMAIL']['REQUESTOR_COMPLETION_MESSAGE']
VENDOR_ACCEPTANCE_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_ACCEPTANCE_MESSAGE']
VENDOR_REJECT_MESSAGE = config['NOTIFICATION_EMAIL']['VENDOR_REJECT_MESSAGE']
#ADMIN PROFILE
CATCH_EMAIL = config['ADMIN']['CATCH_EMAIL']
......@@ -60,4 +60,7 @@ VENDOR_ACKNOWLEDGE_MESSAGE = has sent you an ACKNOWLEDGEMENT REQUEST for change
REQUESTOR_ACKNOWLEDGE_MESSAGE = has ACKNOWLEDGED the change request;RMS-CRACKNOWLEDGE
REQUESTOR_COMPLETION_MESSAGE = has COMPLETED the change request;RMS-CRCOMPLETED
VENDOR_ACCEPTANCE_MESSAGE = has ACCEPTED the change request;RMS-CRACCEPTED
VENDOR_REJECT_MESSAGE = has REJECTED the change request;RMS-CRREJECTED-VENDOR
\ No newline at end of file
VENDOR_REJECT_MESSAGE = has REJECTED the change request;RMS-CRREJECTED-VENDOR
[ADMIN]
CATCH_EMAIL = 'red@tirsolutions.com'
{
"info": {
"_postman_id": "7f6dea46-d192-44b8-a9f8-be778705ae36",
"name": "RMSv2",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Access Token",
"item": [
{
"name": "current-user",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "e53b51ddf459852812a56435aaea934d107cde82",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:8000/api/v1/auth/current-user/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"auth",
"current-user",
""
]
}
},
"response": []
},
{
"name": "Login",
"request": {
"auth": {
"type": "noauth"
},
"method": "POST",
"header": [
{
"key": "Authorization",
"value": "JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNTU2OTM5MDI4LCJlbWFpbCI6IiJ9.eAA6vSTOhrto5yfy3IQsCdR7iaZxfApNcvdJsFdFmsc",
"type": "text",
"disabled": true
}
],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "username",
"value": "superuser",
"type": "text"
},
{
"key": "password",
"value": "password123",
"type": "text"
}
]
},
"url": {
"raw": "http://localhost:8000/api/v1/auth/login/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"auth",
"login",
""
]
}
},
"response": []
},
{
"name": "Forgot Password",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"email\": \"johnredsmedrano@gmail.com\"\n}"
},
"url": {
"raw": "http://localhost:8000/api/v1/auth/forgot-password/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"auth",
"forgot-password",
""
]
}
},
"response": []
},
{
"name": "Validate Token",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"token\": \"31290f51d6ea2d476b02942d1d53b7200ed13a89\"\n}"
},
"url": {
"raw": "http://localhost:8000/api/v1/auth/reset-password-link/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"auth",
"reset-password-link",
""
]
}
},
"response": []
},
{
"name": "Forgot Password Reset",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"username\": \"213\",\n \"password\": \"password123\",\n \"password_confirm\": \"password123\",\n \"passcode\": \"9676\",\n \"token\": \"c90b0833d83b97cdbfd181f8685e06c2ab646e35\"\n}"
},
"url": {
"raw": "http://localhost:8000/api/v1/auth/forgot-password-reset/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"auth",
"forgot-password-reset",
""
]
}
},
"response": []
}
]
},
{
"name": "Management",
"item": [
{
"name": "Application Management",
"item": [
{
"name": "List of Applications",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "ee0a1398b999f2ab1953447e2c733734d0cb0413",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:8000/api/v1/management/applications/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"applications",
""
]
}
},
"response": []
},
{
"name": "View Application",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "46fcda76895239b0fdfa998165780fd451fe049d",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:8000/api/v1/management/applications/1/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"applications",
"1",
""
]
}
},
"response": []
},
{
"name": "Create Application",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "ee0a1398b999f2ab1953447e2c733734d0cb0413",
"type": "string"
}
]
},
"method": "POST",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"type": "text",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"name\": \"Assets Management System\",\n\t\"app_code\": \"AMS\"\n}"
},
"url": {
"raw": "http://localhost:8000/api/v1/management/applications/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"applications",
""
]
}
},
"response": []
},
{
"name": "Edit Application",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "4bf6b1bed4066b3712bd3ca6d6e0466c14767cf0",
"type": "string"
}
]
},
"method": "PUT",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"name\": \"rms2\",\n\t\"app_code\": \"rms\"\n}"
},
"url": {
"raw": "http://localhost:8000/api/v1/management/applications/1/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"applications",
"1",
""
]
}
},
"response": []
},
{
"name": "Delete Application",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "46fcda76895239b0fdfa998165780fd451fe049d",
"type": "string"
}
]
},
"method": "DELETE",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"type": "text",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"name\": \"rms2\"\n}"
},
"url": {
"raw": "http://localhost:8000/api/v1/management/applications/3/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"applications",
"3",
""
]
}
},
"response": []
}
],
"_postman_isSubFolder": true
},
{
"name": "Companies Management",
"item": [
{
"name": "List of Companies",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "ee0a1398b999f2ab1953447e2c733734d0cb0413",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:8000/api/v1/management/companies/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"companies",
""
]
}
},
"response": []
},
{
"name": "View Company",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "46fcda76895239b0fdfa998165780fd451fe049d",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:8000/api/v1/management/companies/1/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"companies",
"1",
""
]
}
},
"response": []
},
{
"name": "Create Company",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "ee0a1398b999f2ab1953447e2c733734d0cb0413",
"type": "string"
}
]
},
"method": "POST",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"name\": \"Oneberry\",\n\t\"contact_details\": \"2152509\"\n}"
},
"url": {
"raw": "http://localhost:8000/api/v1/management/companies/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"companies",
""
]
}
},
"response": []
},
{
"name": "Edit Company",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "46fcda76895239b0fdfa998165780fd451fe049d",
"type": "string"
}
]
},
"method": "PUT",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"name\": \"TIR2\",\n\t\"contact_details\": \"2152509\"\n}"
},
"url": {
"raw": "http://localhost:8000/api/v1/management/companies/4/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"companies",
"4",
""
]
}
},
"response": []
},
{
"name": "Delete Company",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "46fcda76895239b0fdfa998165780fd451fe049d",
"type": "string"
}
]
},
"method": "DELETE",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"type": "text",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"name\": \"TIR2\",\n\t\"contact_details\": \"2152509\"\n}"
},
"url": {
"raw": "http://localhost:8000/api/v1/management/companies/4/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"companies",
"4",
""
]
}
},
"response": []
}
],
"_postman_isSubFolder": true
},
{
"name": "Department Management",
"item": [
{
"name": "List of Department",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "ee0a1398b999f2ab1953447e2c733734d0cb0413",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:8000/api/v1/management/departments/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"departments",
""
]
}
},
"response": []
},
{
"name": "View Department",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "46fcda76895239b0fdfa998165780fd451fe049d",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:8000/api/v1/management/departments/1/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"departments",
"1",
""
]
}
},
"response": []
},
{
"name": "Create Department",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "ee0a1398b999f2ab1953447e2c733734d0cb0413",
"type": "string"
}
]
},
"method": "POST",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"name\": \"Super User\",\n \"company\": 2\n}"
},
"url": {
"raw": "http://localhost:8000/api/v1/management/departments/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"departments",
""
]
}
},
"response": []
},
{
"name": "Edit Department",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "46fcda76895239b0fdfa998165780fd451fe049d",
"type": "string"
}
]
},
"method": "PUT",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"type": "text",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"name\": \"Business Developments\",\n \"company\": 2\n}"
},
"url": {
"raw": "http://localhost:8000/api/v1/management/departments/2/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"departments",
"2",
""
]
}
},
"response": []
},
{
"name": "Delete Department",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "46fcda76895239b0fdfa998165780fd451fe049d",
"type": "string"
}
]
},
"method": "DELETE",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"type": "text",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"name\": \"Business Developments\",\n \"company\": 2\n}"
},
"url": {
"raw": "http://localhost:8000/api/v1/management/departments/2/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"departments",
"2",
""
]
}
},
"response": []
}
],
"_postman_isSubFolder": true
},
{
"name": "Module Management",
"item": [
{
"name": "List of Module",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "ee0a1398b999f2ab1953447e2c733734d0cb0413",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:8000/api/v1/management/modules/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"modules",
""
]
}
},
"response": []
},
{
"name": "View Module",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "46fcda76895239b0fdfa998165780fd451fe049d",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:8000/api/v1/management/modules/5/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"modules",
"5",
""
]
}
},
"response": []
},
{
"name": "Create Module",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "ee0a1398b999f2ab1953447e2c733734d0cb0413",
"type": "string"
}
]
},
"method": "POST",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"name\": \"User Management\",\n \"parent\": 0,\n \"sort_id\": 6,\n \"application\": 1\n}"
},
"url": {
"raw": "http://localhost:8000/api/v1/management/modules/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"modules",
""
]
}
},
"response": []
},
{
"name": "Edit Module",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "46fcda76895239b0fdfa998165780fd451fe049d",
"type": "string"
}
]
},
"method": "PUT",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"type": "text",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"name\": \"Assets NVM\",\n \"parent\": 10,\n \"sort_id\": 1,\n \"application\": 2\n}"
},
"url": {
"raw": "http://localhost:8000/api/v1/management/modules/12/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"modules",
"12",
""
]
}
},
"response": []
},
{
"name": "Edit Module Copy",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "46fcda76895239b0fdfa998165780fd451fe049d",
"type": "string"
}
]
},
"method": "DELETE",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"type": "text",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"name\": \"Assets NVM\",\n \"parent\": 10,\n \"sort_id\": 1,\n \"application\": 2\n}"
},
"url": {
"raw": "http://localhost:8000/api/v1/management/modules/12/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"modules",
"12",
""
]
}
},
"response": []
}
],
"_postman_isSubFolder": true
},
{
"name": "User",
"item": [
{
"name": "List of Users",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "4bf6b1bed4066b3712bd3ca6d6e0466c14767cf0",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:8000/api/v1/management/users/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"users",
""
]
}
},
"response": []
},
{
"name": "View Users",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "4bf6b1bed4066b3712bd3ca6d6e0466c14767cf0",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:8000/api/v1/users/3/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"users",
"3",
""
]
}
},
"response": []
},
{
"name": "Create User",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "e53b51ddf459852812a56435aaea934d107cde82",
"type": "string"
}
]
},
"method": "POST",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\r\n\t\"application\":[1,3],\r\n\t\"department\": 1,\r\n\t\"user_type\": \"OUA\",\r\n\t\"name\": \"Rita\",\r\n\t\"username\": \"badbad11\",\r\n\t\"doa\":\"\",\r\n\t\"default_app\": \"RMS\",\r\n\t\"contact_no\": \"1312313\",\r\n\t\"email\": \"test@gmail.com\"\r\n}\r\n"
},
"url": {
"raw": "http://localhost:8000/api/v1/management/users/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"management",
"users",
""
]
}
},
"response": []
},
{
"name": "Edit User",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "4bf6b1bed4066b3712bd3ca6d6e0466c14767cf0",
"type": "string"
}
]
},
"method": "PUT",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\r\n\t\"application\":[1,3],\r\n\t\"department\": 1,\r\n\t\"user_type\": \"OUA\",\r\n\t\"name\": \"Ritas\",\r\n\t\"username\": \"OBRITA\",\r\n\t\"password\": \"password123\",\r\n\t\"doa\":\"\",\r\n\t\"default_app\": \"RMS\",\r\n\t\"contact_no\": \"1312313\",\r\n\t\"email\": \"test@gmail.com\"\r\n}\r\n"
},
"url": {
"raw": "http://localhost:8000/api/v1/users/3/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"users",
"3",
""
]
}
},
"response": []
},
{
"name": "Change Password",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "4bf6b1bed4066b3712bd3ca6d6e0466c14767cf0",
"type": "string"
}
]
},
"method": "PUT",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\r\n\t\"application\":[1,3],\r\n\t\"department\": 1,\r\n\t\"user_type\": \"OUA\",\r\n\t\"name\": \"Ritas\",\r\n\t\"username\": \"OBRITA\",\r\n\t\"password\": \"password123\",\r\n\t\"doa\":\"\",\r\n\t\"default_app\": \"RMS\",\r\n\t\"contact_no\": \"1312313\",\r\n\t\"email\": \"test@gmail.com\"\r\n}\r\n"
},
"url": {
"raw": "http://localhost:8000/api/v1/users/3/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"users",
"3",
""
]
}
},
"response": []
},
{
"name": "Delete User",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "4bf6b1bed4066b3712bd3ca6d6e0466c14767cf0",
"type": "string"
}
]
},
"method": "DELETE",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:8000/api/v1/users/3/",
"protocol": "http",
"host": [
"localhost"
],
"port": "8000",
"path": [
"api",
"v1",
"users",
"3",
""
]
}
},
"response": []
}
],
"_postman_isSubFolder": true
}
]
}
]
}
\ No newline at end of file
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