Esempio n. 1
0
def test_absence_fill_worktime_reported_time_to_long(auth_client):
    """
    Verify absence fill worktime is zero when reported time is too long.

    Too long is defined when reported time is longer than worktime per day.
    """
    date = datetime.date(2017, 5, 10)
    user = auth_client.user
    EmploymentFactory.create(
        user=user, start_date=date, worktime_per_day=datetime.timedelta(hours=8)
    )
    type = AbsenceTypeFactory.create(fill_worktime=True)

    ReportFactory.create(
        user=user, date=date, duration=datetime.timedelta(hours=8, minutes=30)
    )

    data = {
        "data": {
            "type": "absences",
            "id": None,
            "attributes": {"date": date.strftime("%Y-%m-%d")},
            "relationships": {
                "type": {"data": {"type": "absence-types", "id": type.id}}
            },
        }
    }

    url = reverse("absence-list")

    response = auth_client.post(url, data)
    assert response.status_code == status.HTTP_201_CREATED

    json = response.json()
    assert json["data"]["attributes"]["duration"] == "00:00:00"
Esempio n. 2
0
def test_absence_fill_worktime(auth_client):
    """Should create an absence which fills the worktime."""
    date = datetime.date(2017, 5, 10)
    user = auth_client.user
    EmploymentFactory.create(
        user=user, start_date=date, worktime_per_day=datetime.timedelta(hours=8)
    )
    type = AbsenceTypeFactory.create(fill_worktime=True)

    ReportFactory.create(user=user, date=date, duration=datetime.timedelta(hours=5))

    data = {
        "data": {
            "type": "absences",
            "id": None,
            "attributes": {"date": date.strftime("%Y-%m-%d")},
            "relationships": {
                "type": {"data": {"type": "absence-types", "id": type.id}}
            },
        }
    }

    url = reverse("absence-list")

    response = auth_client.post(url, data)
    assert response.status_code == status.HTTP_201_CREATED

    json = response.json()
    assert json["data"]["attributes"]["duration"] == "03:00:00"
Esempio n. 3
0
def test_worktime_balance_with_employments(auth_client,
                                           django_assert_num_queries):
    # Calculate over one week
    start_date = date(2017, 3, 19)
    end_date = date(2017, 3, 26)

    employment = EmploymentFactory.create(user=auth_client.user,
                                          start_date=start_date,
                                          worktime_per_day=timedelta(
                                              hours=8, minutes=30),
                                          end_date=date(2017, 3, 23))
    EmploymentFactory.create(user=auth_client.user,
                             start_date=date(2017, 3, 24),
                             worktime_per_day=timedelta(hours=8),
                             end_date=None)

    # Overtime credit of 10 hours
    OvertimeCreditFactory.create(user=auth_client.user,
                                 date=start_date,
                                 duration=timedelta(hours=10, minutes=30))

    # One public holiday during workdays
    PublicHolidayFactory.create(date=start_date, location=employment.location)
    # One public holiday on weekend
    PublicHolidayFactory.create(date=start_date + timedelta(days=1),
                                location=employment.location)

    # 2x 10 hour reported worktime
    ReportFactory.create(user=auth_client.user,
                         date=start_date + timedelta(days=3),
                         duration=timedelta(hours=10))

    ReportFactory.create(user=auth_client.user,
                         date=start_date + timedelta(days=4),
                         duration=timedelta(hours=10))

    # one absence
    AbsenceFactory.create(user=auth_client.user,
                          date=start_date + timedelta(days=5))

    url = reverse('worktime-balance-detail',
                  args=[
                      '{0}_{1}'.format(auth_client.user.id,
                                       end_date.strftime('%Y-%m-%d'))
                  ])

    with django_assert_num_queries(12):
        result = auth_client.get(url)
    assert result.status_code == status.HTTP_200_OK

    # 4 workdays 8.5 hours, 1 workday 8 hours, minus one holiday 8.5
    # minutes 10.5 hours overtime credit
    expected_worktime = timedelta(hours=23)

    # 2 x 10 reports hours + 1 absence of 8 hours
    expected_reported = timedelta(hours=28)

    json = result.json()
    assert json['data']['attributes']['balance'] == (
        duration_string(expected_reported - expected_worktime))
Esempio n. 4
0
def test_absence_update_owner(auth_client):
    user = auth_client.user
    date = datetime.date(2017, 5, 3)
    absence = AbsenceFactory.create(
        user=auth_client.user, date=datetime.date(2016, 5, 3)
    )
    EmploymentFactory.create(
        user=user, start_date=date, worktime_per_day=datetime.timedelta(hours=8)
    )

    data = {
        "data": {
            "type": "absences",
            "id": absence.id,
            "attributes": {"date": date.strftime("%Y-%m-%d")},
        }
    }

    url = reverse("absence-detail", args=[absence.id])

    response = auth_client.patch(url, data)

    assert response.status_code == status.HTTP_200_OK
    json = response.json()
    assert json["data"]["attributes"]["date"] == "2017-05-03"
def test_notify_supervisors(db, mailoutbox):
    """Test time range 2017-7-17 till 2017-7-23."""
    start = date(2017, 7, 14)
    # supervisee with short time
    supervisee = UserFactory.create()
    supervisor = UserFactory.create()
    supervisee.supervisors.add(supervisor)

    EmploymentFactory.create(user=supervisee,
                             start_date=start,
                             percentage=100)
    workdays = rrule(DAILY, dtstart=start, until=date.today(),
                     # range is excluding last
                     byweekday=range(MO.weekday, FR.weekday + 1))
    for dt in workdays:
        ReportFactory.create(user=supervisee, date=dt,
                             duration=timedelta(hours=7))

    call_command('notify_supervisors_shorttime')

    # checks
    assert len(mailoutbox) == 1
    mail = mailoutbox[0]
    assert mail.to == [supervisor.email]
    body = mail.body
    assert 'Time range: 17.07.2017 - 23.07.2017\nRatio: 0.9' in body
    expected = (
        '{0} 35.0/42.5 (Ratio 0.82 Delta -7.5 Balance -9.0)'
    ).format(
        supervisee.get_full_name()
    )
    assert expected in body
    def test_absence_credit_balance(self):
        """Should calculate an absence credit balance."""
        absence_credit = AbsenceCreditFactory.create(
            user=self.user, duration=timedelta(hours=30))

        EmploymentFactory.create(user=self.user,
                                 start_date=absence_credit.date -
                                 timedelta(days=1),
                                 worktime_per_day=timedelta(hours=8))

        AbsenceFactory.create(user=self.user,
                              type=absence_credit.absence_type,
                              date=absence_credit.date + timedelta(days=1))

        AbsenceFactory.create(user=self.user,
                              type=absence_credit.absence_type,
                              date=absence_credit.date - timedelta(days=1),
                              duration=timedelta(hours=8))

        url = reverse('absence-credit-detail', args=[absence_credit.id])

        res = self.client.get(url)
        result = self.result(res)

        assert result['data']['attributes']['duration'] == '1 06:00:00'
        assert result['data']['attributes']['used'] == '08:00:00'
        assert result['data']['attributes']['balance'] == '22:00:00'
Esempio n. 7
0
def test_user_transfer(superadmin_client):
    user = UserFactory.create()
    EmploymentFactory.create(user=user,
                             start_date=date(2017, 12, 28),
                             percentage=100)
    AbsenceTypeFactory.create(fill_worktime=True)
    AbsenceTypeFactory.create(fill_worktime=False)
    absence_type = AbsenceTypeFactory.create(fill_worktime=False)
    AbsenceFactory.create(user=user,
                          type=absence_type,
                          date=date(2017, 12, 29))

    url = reverse('user-transfer', args=[user.id])
    response = superadmin_client.post(url)
    assert response.status_code == status.HTTP_204_NO_CONTENT

    # running transfer twice should lead to same result
    response = superadmin_client.post(url)
    assert response.status_code == status.HTTP_204_NO_CONTENT

    assert user.overtime_credits.count() == 1
    overtime_credit = user.overtime_credits.first()
    assert overtime_credit.transfer
    assert overtime_credit.date == date(2018, 1, 1)
    assert overtime_credit.duration == timedelta(hours=-8, minutes=-30)
    assert overtime_credit.comment == 'Transfer 2017'

    assert user.absence_credits.count() == 1
    absence_credit = user.absence_credits.first()
    assert absence_credit.transfer
    assert absence_credit.date == date(2018, 1, 1)
    assert absence_credit.days == -1
    assert absence_credit.comment == 'Transfer 2017'
Esempio n. 8
0
def test_worktime_balance_list_last_reported_date(auth_client,
                                                  django_assert_num_queries):

    EmploymentFactory.create(
        user=auth_client.user,
        start_date=date(2017, 2, 1),
        end_date=date(2017, 2, 2),
        worktime_per_day=timedelta(hours=8),
    )

    ReportFactory.create(user=auth_client.user,
                         date=date(2017, 2, 1),
                         duration=timedelta(hours=10))

    # reports today and in the future should be ignored
    ReportFactory.create(user=auth_client.user,
                         date=date(2017, 2, 2),
                         duration=timedelta(hours=10))
    ReportFactory.create(user=auth_client.user,
                         date=date(2017, 2, 3),
                         duration=timedelta(hours=10))

    url = reverse('worktime-balance-list')

    with django_assert_num_queries(10):
        result = auth_client.get(url, data={'last_reported_date': 1})

    assert result.status_code == status.HTTP_200_OK

    json = result.json()
    assert len(json['data']) == 1
    entry = json['data'][0]
    assert entry['attributes']['date'] == '2017-02-01'
    assert entry['attributes']['balance'] == '02:00:00'
Esempio n. 9
0
    def setUp(self):
        """Set the environment for the tests up."""
        super().setUp()

        user = self.user

        other_user = User.objects.create_user(username='******',
                                              password='******')

        EmploymentFactory.create(user=user,
                                 start_date=datetime.date(2017, 5, 1),
                                 end_date=None)

        EmploymentFactory.create(user=other_user,
                                 start_date=datetime.date(2017, 5, 1),
                                 end_date=None)

        self.absences = [
            AbsenceFactory.create(user=user, date=datetime.date(2017, 5, 1)),
            AbsenceFactory.create(user=user, date=datetime.date(2017, 5, 2)),
            AbsenceFactory.create(user=user, date=datetime.date(2017, 5, 3))
        ]

        AbsenceFactory.create(user=other_user, date=datetime.date(2017, 5, 1))
        AbsenceFactory.create(user=other_user, date=datetime.date(2017, 5, 2))
        AbsenceFactory.create(user=other_user, date=datetime.date(2017, 5, 3))
Esempio n. 10
0
def test_absence_create(auth_client):
    user = auth_client.user
    date = datetime.date(2017, 5, 4)
    EmploymentFactory.create(
        user=user, start_date=date, worktime_per_day=datetime.timedelta(hours=8)
    )
    type = AbsenceTypeFactory.create()

    data = {
        "data": {
            "type": "absences",
            "id": None,
            "attributes": {"date": date.strftime("%Y-%m-%d")},
            "relationships": {
                "type": {"data": {"type": "absence-types", "id": type.id}}
            },
        }
    }

    url = reverse("absence-list")

    response = auth_client.post(url, data)

    assert response.status_code == status.HTTP_201_CREATED

    json = response.json()
    assert json["data"]["relationships"]["user"]["data"]["id"] == (
        str(auth_client.user.id)
    )
Esempio n. 11
0
    def setUp(self):
        """Set the environment for the tests up."""
        super().setUp()

        self.users = UserFactory.create_batch(3)

        for user in self.users + [self.user]:
            EmploymentFactory.create(user=user)
Esempio n. 12
0
def test_employment_unique_active(db):
    """Should only be able to have one active employment per user."""
    user = UserFactory.create()
    EmploymentFactory.create(user=user, end_date=None)
    employment = EmploymentFactory.create(user=user)
    form = EmploymentForm({"end_date": None}, instance=employment)

    with pytest.raises(ValueError):
        form.save()
Esempio n. 13
0
def test_employment_list_superuser(superadmin_client):
    EmploymentFactory.create_batch(2)
    EmploymentFactory.create(user=superadmin_client.user)

    url = reverse('employment-list')

    result = superadmin_client.get(url)
    assert result.status_code == status.HTTP_200_OK
    json = result.json()
    assert len(json['data']) == 3
Esempio n. 14
0
def test_employment_list_authenticated(auth_client):
    EmploymentFactory.create_batch(2)
    employment = EmploymentFactory.create(user=auth_client.user)

    url = reverse('employment-list')

    result = auth_client.get(url)
    assert result.status_code == status.HTTP_200_OK
    json = result.json()
    assert len(json['data']) == 1
    assert json['data'][0]['id'] == str(employment.id)
Esempio n. 15
0
    def setUp(self):
        """Set the environment for the tests up."""
        super().setUp()

        self.employments = [
            EmploymentFactory.create(user=self.user,
                                     start_date=datetime.date(2010, 1, 1),
                                     end_date=datetime.date(2015, 1, 1)),
            EmploymentFactory.create(user=self.user,
                                     start_date=datetime.date(2015, 1, 2))
        ]

        EmploymentFactory.create_batch(10)
Esempio n. 16
0
def test_employment_list_filter_date(auth_client):
    EmploymentFactory.create(user=auth_client.user,
                             start_date=date(2017, 1, 1),
                             end_date=date(2017, 4, 1))
    employment = EmploymentFactory.create(user=auth_client.user,
                                          start_date=date(2017, 4, 2),
                                          end_date=None)

    url = reverse("employment-list")

    result = auth_client.get(url, data={"date": "2017-04-05"})
    assert result.status_code == status.HTTP_200_OK
    json = result.json()
    assert len(json["data"]) == 1
    assert json["data"][0]["id"] == str(employment.id)
Esempio n. 17
0
def test_absence_public_holiday(auth_client):
    """Should not be able to create an absence on a public holiday."""
    date = datetime.date(2017, 5, 16)
    user = auth_client.user
    type = AbsenceTypeFactory.create()
    employment = EmploymentFactory.create(
        user=user, start_date=date, worktime_per_day=datetime.timedelta(hours=8)
    )
    PublicHolidayFactory.create(location=employment.location, date=date)

    data = {
        "data": {
            "type": "absences",
            "id": None,
            "attributes": {"date": date.strftime("%Y-%m-%d")},
            "relationships": {
                "type": {"data": {"type": "absence-types", "id": type.id}}
            },
        }
    }

    url = reverse("absence-list")

    response = auth_client.post(url, data)
    assert response.status_code == status.HTTP_400_BAD_REQUEST
Esempio n. 18
0
def test_employment_update_overlapping(superadmin_client):
    user = superadmin_client.user
    EmploymentFactory.create(user=user, end_date=None)
    employment = EmploymentFactory.create(user=user)

    data = {
        "data": {
            "type": "employments",
            "id": employment.id,
            "attributes": {
                "end_date": None
            },
        }
    }

    url = reverse("employment-detail", args=[employment.id])
    result = superadmin_client.patch(url, data)
    assert result.status_code == status.HTTP_400_BAD_REQUEST
Esempio n. 19
0
def test_employment_start_before_end(db):
    employment = EmploymentFactory.create()
    form = EmploymentForm({
        'start_date': date(2009, 1, 1),
        'end_date':   date(2016, 1, 1)
    }, instance=employment)

    with pytest.raises(ValueError):
        form.save()
Esempio n. 20
0
def test_employment_update_overlapping(superadmin_client):
    user = superadmin_client.user
    EmploymentFactory.create(user=user, end_date=None)
    employment = EmploymentFactory.create(user=user)

    data = {
        'data': {
            'type': 'employments',
            'id': employment.id,
            'attributes': {
                'end_date': None,
            }
        }
    }

    url = reverse('employment-detail', args=[employment.id])
    result = superadmin_client.patch(url, data)
    assert result.status_code == status.HTTP_400_BAD_REQUEST
Esempio n. 21
0
def test_absence_balance_full_day(auth_client, django_assert_num_queries):
    day = date(2017, 2, 28)

    user = auth_client.user
    EmploymentFactory.create(user=user, start_date=day)
    absence_type = AbsenceTypeFactory.create()

    AbsenceCreditFactory.create(date=day,
                                user=user,
                                days=5,
                                absence_type=absence_type)

    # credit on different user, may not show up
    AbsenceCreditFactory.create(date=date.today(), absence_type=absence_type)

    AbsenceFactory.create(date=day, user=user, type=absence_type)

    AbsenceFactory.create(date=day - timedelta(days=1),
                          user=user,
                          type=absence_type)

    url = reverse('absence-balance-list')

    with django_assert_num_queries(7):
        result = auth_client.get(url,
                                 data={
                                     'date': '2017-03-01',
                                     'user': user.id,
                                     'include': 'absence_credits,absence_type'
                                 })

    assert result.status_code == status.HTTP_200_OK
    json = result.json()
    assert len(json['data']) == 1
    entry = json['data'][0]

    assert (entry['id'] == '{0}_{1}_2017-03-01'.format(user.id,
                                                       absence_type.id))
    assert entry['attributes']['credit'] == 5
    assert entry['attributes']['used-days'] == 2
    assert entry['attributes']['used-duration'] is None
    assert entry['attributes']['balance'] == 3

    assert len(json['included']) == 2
Esempio n. 22
0
def test_absence_balance_fill_worktime(auth_client, django_assert_num_queries):
    day = date(2017, 2, 28)

    user = UserFactory.create()
    user.supervisors.add(auth_client.user)
    EmploymentFactory.create(user=user,
                             start_date=day,
                             worktime_per_day=timedelta(hours=5))
    absence_type = AbsenceTypeFactory.create(fill_worktime=True)

    ReportFactory.create(user=user,
                         date=day + timedelta(days=1),
                         duration=timedelta(hours=4))

    AbsenceFactory.create(date=day + timedelta(days=1),
                          user=user,
                          type=absence_type)

    AbsenceFactory.create(date=day, user=user, type=absence_type)

    url = reverse('absence-balance-list')
    with django_assert_num_queries(12):
        result = auth_client.get(url,
                                 data={
                                     'date': '2017-03-01',
                                     'user': user.id,
                                     'include': 'absence_credits,absence_type'
                                 })
    assert result.status_code == status.HTTP_200_OK

    json = result.json()
    assert len(json['data']) == 1
    entry = json['data'][0]

    assert (entry['id'] == '{0}_{1}_2017-03-01'.format(user.id,
                                                       absence_type.id))

    assert entry['attributes']['credit'] is None
    assert entry['attributes']['balance'] is None
    assert entry['attributes']['used-days'] is None
    assert entry['attributes']['used-duration'] == '06:00:00'
Esempio n. 23
0
def test_absence_update_superadmin_date(superadmin_client):
    """Test that superadmin may not change date of absence."""
    user = UserFactory.create()
    date = datetime.date(2017, 5, 3)
    absence = AbsenceFactory.create(user=user, date=datetime.date(2016, 5, 3))
    EmploymentFactory.create(
        user=user, start_date=date, worktime_per_day=datetime.timedelta(hours=8)
    )

    data = {
        "data": {
            "type": "absences",
            "id": absence.id,
            "attributes": {"date": date.strftime("%Y-%m-%d")},
        }
    }

    url = reverse("absence-detail", args=[absence.id])

    response = superadmin_client.patch(url, data)
    assert response.status_code == status.HTTP_400_BAD_REQUEST
Esempio n. 24
0
def test_employment_list_filter_date(auth_client):
    EmploymentFactory.create(
        user=auth_client.user,
        start_date=date(2017, 1, 1,),
        end_date=date(2017, 4, 1,)
    )
    employment = EmploymentFactory.create(
        user=auth_client.user,
        start_date=date(2017, 4, 2,),
        end_date=None
    )

    url = reverse('employment-list')

    result = auth_client.get(url, data={
        'date': '2017-04-05'
    })
    assert result.status_code == status.HTTP_200_OK
    json = result.json()
    assert len(json['data']) == 1
    assert json['data'][0]['id'] == str(employment.id)
def test_absence_balance_full_day(auth_client, django_assert_num_queries):
    day = date(2017, 2, 28)

    user = auth_client.user
    EmploymentFactory.create(user=user, start_date=day)
    absence_type = AbsenceTypeFactory.create()

    AbsenceCreditFactory.create(date=day, user=user, days=5, absence_type=absence_type)

    # credit on different user, may not show up
    AbsenceCreditFactory.create(date=date.today(), absence_type=absence_type)

    AbsenceFactory.create(date=day, user=user, type=absence_type)

    AbsenceFactory.create(date=day - timedelta(days=1), user=user, type=absence_type)

    url = reverse("absence-balance-list")

    with django_assert_num_queries(6):
        result = auth_client.get(
            url,
            data={
                "date": "2017-03-01",
                "user": user.id,
                "include": "absence_credits,absence_type",
            },
        )

    assert result.status_code == status.HTTP_200_OK
    json = result.json()
    assert len(json["data"]) == 1
    entry = json["data"][0]

    assert entry["id"] == "{0}_{1}_2017-03-01".format(user.id, absence_type.id)
    assert entry["attributes"]["credit"] == 5
    assert entry["attributes"]["used-days"] == 2
    assert entry["attributes"]["used-duration"] is None
    assert entry["attributes"]["balance"] == 3

    assert len(json["included"]) == 2
def test_absence_balance_fill_worktime(auth_client, django_assert_num_queries):
    day = date(2017, 2, 28)

    user = UserFactory.create()
    user.supervisors.add(auth_client.user)
    EmploymentFactory.create(
        user=user, start_date=day, worktime_per_day=timedelta(hours=5)
    )
    absence_type = AbsenceTypeFactory.create(fill_worktime=True)

    ReportFactory.create(
        user=user, date=day + timedelta(days=1), duration=timedelta(hours=4)
    )

    AbsenceFactory.create(date=day + timedelta(days=1), user=user, type=absence_type)

    AbsenceFactory.create(date=day, user=user, type=absence_type)

    url = reverse("absence-balance-list")
    with django_assert_num_queries(11):
        result = auth_client.get(
            url,
            data={
                "date": "2017-03-01",
                "user": user.id,
                "include": "absence_credits,absence_type",
            },
        )
    assert result.status_code == status.HTTP_200_OK

    json = result.json()
    assert len(json["data"]) == 1
    entry = json["data"][0]

    assert entry["id"] == "{0}_{1}_2017-03-01".format(user.id, absence_type.id)

    assert entry["attributes"]["credit"] is None
    assert entry["attributes"]["balance"] is None
    assert entry["attributes"]["used-days"] is None
    assert entry["attributes"]["used-duration"] == "06:00:00"
Esempio n. 27
0
def test_employment_get_at(db):
    """Should return the right employment on a date."""
    user = UserFactory.create()
    employment = EmploymentFactory.create(user=user)

    assert Employment.objects.get_at(user, employment.start_date) == employment

    employment.end_date = employment.start_date + timedelta(days=20)

    employment.save()

    with pytest.raises(Employment.DoesNotExist):
        Employment.objects.get_at(user,
                                  employment.start_date + timedelta(days=21))
def test_notify_changed_employments(db, mailoutbox, freezer):
    email = "*****@*****.**"

    # employments changed too far in the past
    freezer.move_to("2017-08-27")
    EmploymentFactory.create_batch(2)

    # employments which should show up in report
    freezer.move_to("2017-09-03")
    finished = EmploymentFactory.create(end_date=date(2017, 10, 10),
                                        percentage=80)
    new = EmploymentFactory.create(percentage=100)

    freezer.move_to("2017-09-04")
    call_command("notify_changed_employments", email=email)

    # checks
    assert len(mailoutbox) == 1
    mail = mailoutbox[0]
    assert mail.to == [email]
    print(mail.body)
    assert "80% {0}".format(finished.user.get_full_name()) in mail.body
    assert "None       100% {0}".format(new.user.get_full_name()) in mail.body
Esempio n. 29
0
def test_employment_update_end_before_start(superadmin_client):
    employment = EmploymentFactory.create(user=superadmin_client.user)

    data = {
        "data": {
            "type": "employments",
            "id": employment.id,
            "attributes": {
                "start_date": "2017-03-01",
                "end_date": "2017-01-01"
            },
        }
    }

    url = reverse("employment-detail", args=[employment.id])
    result = superadmin_client.patch(url, data)
    assert result.status_code == status.HTTP_400_BAD_REQUEST
Esempio n. 30
0
def test_employment_update_end_before_start(superadmin_client):
    employment = EmploymentFactory.create(user=superadmin_client.user)

    data = {
        'data': {
            'type': 'employments',
            'id': employment.id,
            'attributes': {
                'start_date': '2017-03-01',
                'end_date': '2017-01-01',
            }
        }
    }

    url = reverse('employment-detail', args=[employment.id])
    result = superadmin_client.patch(url, data)
    assert result.status_code == status.HTTP_400_BAD_REQUEST