def send_mail(cls, email=None, name=None, phone=None, personal_email=None, send_email=False): if send_email: token = TokenUtil.verification_encode(name, email, phone, personal_email) # TODO: Look at the link again link = f'http://{settings.UI_HOST}/verify?token={token}' content = render_to_string('../templates/invitation_email.html', { 'name': name, 'email': email, 'link': link, 'token': token }) SendMail.start([email, personal_email], 'Welcome to Company Management', content) if phone == "": phone = None email = email with transaction.atomic(): user = User.objects.create_user(email=email, password='******') profile = Profile.objects.create(user=user, name=name, phone=phone, personal_email=personal_email, join_date=datetime.datetime.now()) RemainLeaveService.create_annual_leave( year=datetime.datetime.now().year, profile=profile)
def list(self, request, *args, **kwargs): year = RemainLeaveService.get_next_year() if RemainLeave.objects.filter(year=kwargs.get('year') | year).exists(): return Response( RemainLeaveService.get_annual_leave_by_year( year=kwargs.get('year') | year)) else: return Response({'status': 'Year has been used'}, status=status.HTTP_400_BAD_REQUEST)
def test_method_handle_annual_leave_next_year(self): expected_results = { "annual_leave": 12, "current_days_off": 9, } RemainLeaveService.handle_annual_leave_next_year(self.profile1, 3) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile1.id, year=2021).annual_leave, expected_results.get('annual_leave')) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile1.id, year=2021).current_days_off, expected_results.get('current_days_off'))
def test_method_handle_annual_leave_last_year(self): expected_results = { "current_days_off": 2, "annual_leave_last_year": 2, } RemainLeaveService.handle_annual_leave_last_year(self.profile1, 3) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile1.id, year=2019).current_days_off, expected_results.get('current_days_off')) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile1.id, year=2020).annual_leave_last_year, expected_results.get('annual_leave_last_year'))
def test_method_create_annual_leave(self): expected_results = { "annual_leave": 3, "current_days_off": 3, } RemainLeaveService.create_annual_leave(year=2020, profile=self.profile2) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile2.id, year=2020).annual_leave, expected_results.get('annual_leave')) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile2.id, year=2020).current_days_off, expected_results.get('current_days_off'))
def test_method_update_annual_leave(self): join_date = "2019-10-15" expected_results = { "annual_leave": 12, "current_days_off": 12, } RemainLeaveService.update_annual_leave(join_date, self.profile1) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile1.id, year=2020).annual_leave, expected_results.get('annual_leave')) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile1.id, year=2020).current_days_off, expected_results.get('current_days_off'))
def test_method_handle_annual_leave_sub_annual_last_year_with_day_leave_greater_annual_leave_last_year(self): expected_results = { "annual_leave": 3, "current_days_off": 2, "annual_leave_last_year": 0 } RemainLeaveService.handle_annual_leave(self.profile1, 6, True) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile1.id, year=2020).annual_leave, expected_results.get('annual_leave')) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile1.id, year=2020).current_days_off, expected_results.get('current_days_off')) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile1.id, year=2020).annual_leave_last_year, expected_results.get('annual_leave_last_year'))
def test_method_add_annual_leave_last_year_for_next_year(self): expected_results = { "annual_leave": 12, "current_days_off": 12, "annual_leave_last_year": 3 } RemainLeaveService.add_annual_leave_last_year_for_next_year() self.assertEqual(RemainLeave.objects.get(profile_id=self.profile1.id, year=2021).annual_leave, expected_results.get('annual_leave')) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile1.id, year=2021).annual_leave_last_year, expected_results.get('annual_leave_last_year')) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile1.id, year=2021).current_days_off, expected_results.get('current_days_off'))
def create(self, request, *args, **kwargs): next_year = RemainLeaveService.get_next_year() if next_year == datetime.datetime.now( ).year + 1 and not RemainLeave.objects.filter(year=next_year).exists(): with transaction.atomic(): for profile in Profile.objects.all(): RemainLeaveService.create_annual_leave(year=next_year, profile=profile) return Response( RemainLeaveService.get_annual_leave_by_year(next_year), status=status.HTTP_201_CREATED) else: return Response({'status': 'Year has been used'}, status=status.HTTP_400_BAD_REQUEST)
def test_method_handle_annual_leave_last_year_with_day_leave_greater_leave_days(self): expected_results = { "current_days_off": 5, "annual_leave_last_year": 5, } with self.assertRaises(ValidationError) as cm: RemainLeaveService.handle_annual_leave_last_year(self.profile1, 6) the_exception = cm.exception self.assertEqual(the_exception.detail, {'status': ErrorDetail(string='The number of days off is not enough', code='invalid')}) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile1.id, year=2019).current_days_off, expected_results.get('current_days_off')) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile1.id, year=2020).annual_leave_last_year, expected_results.get('annual_leave_last_year'))
def handle_cancel_request_with_another_year(cls, remain_leave_last_year, request_off): present_year = datetime.now().year list_date = DateOff.objects.filter(request_off_id=request_off.id) list_date_present_year = list( filter(lambda date_off: date_off.date.year == present_year, list_date)) list_date_off_all = list(list_date) + list_date_present_year list_date_another_year = list( filter(lambda date_off: list_date_off_all.count(date_off) == 1, list_date_off_all)) if list_date_another_year[0].date.year == datetime.now().year - 1: RemainLeaveService.handle_annual_leave( request_off.profile, -DateOffService.get_num_days_off_by_list_date( list_date_present_year), True) RemainLeaveService.handle_annual_leave_last_year( request_off.profile, -DateOffService.get_num_days_off_by_list_date( list_date_another_year)) else: RemainLeaveService.handle_annual_leave( request_off.profile, -DateOffService.get_num_days_off_by_list_date( list_date_present_year)) RemainLeaveService.handle_annual_leave_next_year( request_off.profile, -DateOffService.get_num_days_off_by_list_date( list_date_another_year))
def update(self, request, *args, **kwargs): partial = kwargs.pop('partial', False) instance = self.get_object() serializer = self.get_serializer(instance, data=request.data, partial=partial, context={'request': request}) serializer.is_valid(raise_exception=True) profile = Profile.objects.filter(user__id=request.data.get('user')).first() with transaction.atomic(): RemainLeaveService.update_annual_leave(request.data.get('join_date'), profile) self.perform_update(serializer) if getattr(instance, '_prefetched_objects_cache', None): # If 'prefetch_related' has been applied to a queryset, we need to # forcibly invalidate the prefetch cache on the instance. instance._prefetched_objects_cache = {} return Response(serializer.data)
def post(self, request, format=None): profile = Profile.objects.get_profile_by_id(id=request.data.get('profile_id')) try: bonus = float(request.data.get("bonus")) return Response(RemainLeaveService.add_bonus(profile, bonus).data) except: return Response({'status': 'Invalid data'}, status=status.HTTP_400_BAD_REQUEST)
def retrieve(self, request, *args, **kwargs): company_setting = Company.objects.all().first() if company_setting is None: return Response({'status': 'Company setting not found'}, status=status.HTTP_400_BAD_REQUEST) profile = request.user.profile remain_leave = RemainLeave.objects.get_remain_leave_by_profile_id( id=profile.id) request_off_unconfirmed = RequestOff.objects.filter( status__in=[Workday.STATUS_FORWARDED, Workday.STATUS_PENDING], profile_id=profile.id) serializer = RemainLeaveSerializer(remain_leave) sub_leave_last_year, sub_annual_leave = RemainLeaveService.get_unconfirmed_days( request_off_unconfirmed) current_days_off = serializer.data.get( 'current_days_off') - sub_annual_leave annual_leave_last_year = serializer.data.get( 'annual_leave_last_year') - sub_leave_last_year if annual_leave_last_year < 0: current_days_off += current_days_off annual_leave_last_year = 0 response = { 'current_days_off': current_days_off, 'annual_leave_last_year': annual_leave_last_year, 'profile': serializer.data.get('profile'), 'month': company_setting.expired_annual_leave_last_year } return Response(response)
def test_method_add_annual_leave_last_year_has_date_off_next_year(self): expected_results = { "annual_leave": 13, "current_days_off": 11, "annual_leave_last_year": 0 } RemainLeaveFactory(profile=self.profile2, year=2021, annual_leave=13, current_days_off=10, annual_leave_last_year=5) RemainLeaveFactory(profile=self.profile2, year=2020, annual_leave=12, current_days_off=1) RemainLeaveService.add_annual_leave_last_year_for_next_year() self.assertEqual(RemainLeave.objects.get(profile_id=self.profile2.id, year=2021).annual_leave, expected_results.get('annual_leave')) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile2.id, year=2021).annual_leave_last_year, expected_results.get('annual_leave_last_year')) self.assertEqual(RemainLeave.objects.get(profile_id=self.profile2.id, year=2021).current_days_off, expected_results.get('current_days_off'))
def test_method_add_bonus(self): expected_results = { "profile_id": str(self.profile1.id), "bonus": 3, "current_days_off": 6 } response = RemainLeaveService.add_bonus(self.profile1, 3) self.assertEqual(response.data.get('profile').get('id'), expected_results.get('profile_id')) self.assertEqual(response.data.get('bonus'), expected_results.get('bonus')) self.assertEqual(response.data.get('current_days_off'), expected_results.get('current_days_off'))
def action_cancel(cls, request_off_id, profile): if profile.user.is_staff: request_off = RequestOff.objects.filter(id=request_off_id).first() else: request_off = RequestOff.objects.filter(id=request_off_id, profile=profile).first() if request_off.status == Workday.STATUS_CANCEL: raise APIException('The request was canceled earlier') date_offs = request_off.date_off.order_by('date') if not cls.allow_or_not_cancel(date_offs.first(), profile): raise APIException( 'Cancellation can only be made 1 hour in advance') if request_off.status == Workday.STATUS_APPROVED and DateOffService.get_num_days_off( request_off) > 0: remain_leave_last_year = RemainLeave.objects.filter( year=datetime.now().year - 1, profile_id=request_off.profile.id).first() if remain_leave_last_year is not None: if len(set([date_off.date.year for date_off in date_offs])) > 1: cls.handle_cancel_request_with_another_year( remain_leave_last_year, request_off) elif date_offs.first().date.year == datetime.now().year - 1: RemainLeaveService.handle_annual_leave_last_year( request_off.profile, -DateOffService.get_num_days_off(request_off)) else: cls.handle_cancel_request(remain_leave_last_year, request_off) else: RemainLeaveService.handle_annual_leave( request_off.profile, -DateOffService.get_num_days_off(request_off)) request_off.status = Workday.STATUS_CANCEL request_off.save() request_detail = RequestDetail.objects.filter( request_off_id=request_off_id) list_email_admin = [item.approve.user.email for item in request_detail] SendMailRequestOff.send_cancel_request(request_off.type_off, profile.name, list_email_admin, date_offs) return request_off
def action_approve(cls, request_off_id, user, comment): company_setting = Company.objects.all().first() month_annual_leave_last_year = company_setting.expired_annual_leave_last_year user_action = RequestDetail.objects.filter( request_off_id=request_off_id) request_off, request_detail, list_email_manage, list_date_off = cls.get_request_helper( request_off_id, user) if request_detail.status or request_off.status == Workday.STATUS_CANCEL: return request_detail level = request_off.profile.maximum_level_approved with transaction.atomic(): if request_off.status != Workday.STATUS_CANCEL: condition = user_action.count() < level and user.line_manager is not None \ and request_off.type_off.type != 1 if condition: request_off.status = Workday.STATUS_FORWARDED request_off.save() cls.create_action_user(request_off, user.line_manager) email = { 'user': [request_off.profile.user.email], 'admin': [user.line_manager.user.email] } SendMailRequestOff.send_forward_request( type_off=request_off.type_off, name_admin=user.name, name_admin_manage=user.line_manager.name, name_user=request_off.profile.name, email=email, date_off=request_off.date_off.all()) else: request_off.status = Workday.STATUS_APPROVED if request_off.type_off.add_sub_day_off == Workday.ANNUAL_LEAVE: if len( set([ date_off.date.year for date_off in list_date_off ])) > 1: cls.handle_approve_with_another_year( list_date_off, request_off) elif list_date_off.first( ).date.year == datetime.now().year - 1: RemainLeaveService.handle_annual_leave_last_year( request_off.profile, DateOffService.get_num_days_off(request_off)) elif list_date_off.first().date.year == datetime.now( ).year: # day off have July and June if len( set([ date_off.date.month for date_off in list_date_off ])) > 1 and list_date_off.first( ).date.month == ( month_annual_leave_last_year or month_annual_leave_last_year - 1): list_date_present_month = list( filter( lambda date_off: date_off.date.month == month_annual_leave_last_year - 1, list_date_off)) list_date_next_month = list( filter( lambda date_off: date_off.date.month == month_annual_leave_last_year, list_date_off)) RemainLeaveService.handle_annual_leave( request_off.profile, DateOffService. get_num_days_off_by_list_date( list_date_present_month), True) RemainLeaveService.handle_annual_leave( request_off.profile, DateOffService. get_num_days_off_by_list_date( list_date_next_month)) # day off of month in [7, 12] elif list_date_off.first( ).date.month > month_annual_leave_last_year - 1: RemainLeaveService.handle_annual_leave( request_off.profile, DateOffService.get_num_days_off( request_off)) # day off of month in [1, 6] else: RemainLeaveService.handle_annual_leave( request_off.profile, DateOffService.get_num_days_off( request_off), True) else: RemainLeaveService.handle_annual_leave_next_year( request_off.profile, DateOffService.get_num_days_off(request_off)) request_off.save() cls.change_lunch(list_date_off, request_off) SendMailRequestOff.send_approve_request_to_user( type_off=request_off.type_off, name_admin=user.name, name_user=request_off.profile.name, list_email=[request_off.profile.user.email], date_off=request_off.date_off.all()) SendMailRequestOff.send_approve_request_to_manage( type_off=request_off.type_off, name_user=request_off.profile.name, email_user=request_off.profile.user.email, list_email=list_email_manage, date_off=request_off.date_off.all()) request_detail.status = Workday.STATUS_APPROVED request_detail.comment = comment request_detail.save() return request_detail
def handle_cancel_request(cls, remain_leave_last_year, request_off): num_days_off_on_sub_month_not_request_off, \ num_days_off_on_sub_month_by_request_off, \ list_date_out_sub_month = cls.get_request_canceled(request_off) if num_days_off_on_sub_month_not_request_off >= remain_leave_last_year.current_days_off: RemainLeaveService.handle_annual_leave( request_off.profile, -num_days_off_on_sub_month_by_request_off) else: if num_days_off_on_sub_month_not_request_off == 0: if num_days_off_on_sub_month_by_request_off - remain_leave_last_year.current_days_off > 0: RemainLeaveService.handle_annual_leave( request_off.profile, -remain_leave_last_year.current_days_off, True) RemainLeaveService.handle_annual_leave( request_off.profile, remain_leave_last_year.current_days_off - num_days_off_on_sub_month_by_request_off) else: RemainLeaveService.handle_annual_leave( request_off.profile, -num_days_off_on_sub_month_by_request_off, True) elif num_days_off_on_sub_month_not_request_off > remain_leave_last_year. \ current_days_off: RemainLeaveService.handle_annual_leave( request_off.profile, -num_days_off_on_sub_month_by_request_off) else: if num_days_off_on_sub_month_by_request_off + num_days_off_on_sub_month_not_request_off - \ remain_leave_last_year.current_days_off > 0: RemainLeaveService.handle_annual_leave( request_off.profile, num_days_off_on_sub_month_not_request_off - remain_leave_last_year.current_days_off, True) RemainLeaveService.handle_annual_leave( request_off.profile, remain_leave_last_year.current_days_off - num_days_off_on_sub_month_by_request_off - num_days_off_on_sub_month_not_request_off) else: RemainLeaveService.handle_annual_leave( request_off.profile, -num_days_off_on_sub_month_by_request_off, True) RemainLeaveService.handle_annual_leave( request_off.profile, -DateOffService.get_num_days_off_by_list_date( list_date_out_sub_month))
def test_method_get_annual_leave_by_year(self): response = RemainLeaveService.get_annual_leave_by_year(2020) self.assertEqual(len(response), len(RemainLeave.objects.filter(year=2020)))