Skip to content

Commit

Permalink
Usprawnione odpinanie miejsc pracy (#1229)
Browse files Browse the repository at this point in the history
  • Loading branch information
mpasternak committed Jun 22, 2022
1 parent 8944e42 commit e43231c
Show file tree
Hide file tree
Showing 12 changed files with 377 additions and 115 deletions.
2 changes: 2 additions & 0 deletions HISTORY.rst
Expand Up @@ -27,6 +27,8 @@ dev
* pole bazodanowe "aktualny" znika z modelu Autor (b/n),
* pola "aktualna jednostka" oraz "aktualna funkcja" dla modelu Autor mogą mieć
wartość pustą (null) (b/n),
* poprawiony skrypt odpinający miejsca pracy podczas importu danych
kadrowych (#1229)

202205.1086
-----------
Expand Down
16 changes: 16 additions & 0 deletions conftest.py
@@ -1 +1,17 @@
from datetime import timedelta

import pytest

from fixtures import * # noqa


@pytest.fixture(scope="session")
def today():
from django.utils import timezone

return timezone.now().date()


@pytest.fixture(scope="session")
def yesterday(today):
return today - timedelta(days=1)
34 changes: 22 additions & 12 deletions src/bpp/models/autor.py
@@ -1,6 +1,8 @@
"""
Autorzy
"""
from __future__ import annotations

from datetime import date, datetime, timedelta

from autoslug import AutoSlugField
Expand Down Expand Up @@ -197,34 +199,42 @@ def __str__(self):

return buf

def dodaj_jednostke(self, jednostka, rok=None, funkcja=None):
if rok is None:
rok = datetime.now().date().year - 1
def dodaj_jednostke(
self, jednostka, rok=None, funkcja=None
) -> Autor_Jednostka | None:

start_pracy = date(rok, 1, 1)
koniec_pracy = date(rok, 12, 31)
start_pracy = None
koniec_pracy = None

if Autor_Jednostka.objects.filter(
if rok is not None:
start_pracy = date(rok, 1, 1)
koniec_pracy = date(rok, 12, 31)

czy_juz_istnieje = Autor_Jednostka.objects.filter(
autor=self,
jednostka=jednostka,
rozpoczal_prace__lte=start_pracy,
zakonczyl_prace__gte=koniec_pracy,
):
rozpoczal_prace__lte=start_pracy or date(1, 1, 1),
zakonczyl_prace__gte=koniec_pracy or date(999, 12, 31),
)

if czy_juz_istnieje.exists():
# Ten czas jest już pokryty
return
return czy_juz_istnieje.first()

try:
Autor_Jednostka.objects.create(
ret = Autor_Jednostka.objects.create(
autor=self,
rozpoczal_prace=start_pracy,
jednostka=jednostka,
funkcja=funkcja,
rozpoczal_prace=start_pracy,
zakonczyl_prace=koniec_pracy,
)
except IntegrityError:
return
self.defragmentuj_jednostke(jednostka)

return ret

def defragmentuj_jednostke(self, jednostka):
Autor_Jednostka.objects.defragmentuj(autor=self, jednostka=jednostka)

Expand Down
26 changes: 18 additions & 8 deletions src/bpp/tests/util.py
@@ -1,13 +1,15 @@
# -*- encoding: utf-8 -*-

"""Ten moduł zawiera 'normalne', dla ludzi funkcje, które mogą być używane
do ustawiania testów."""
from __future__ import annotations

import cgi
import random
import re
import time
import warnings
from datetime import datetime

from django.http import HttpResponse
from django.urls import reverse
from model_mommy import mommy
from selenium.webdriver.common.keys import Keys
Expand Down Expand Up @@ -130,10 +132,10 @@ def any_wydawnictwo(klass, rok=None, **kw):
kl = str(klass).split(".")[-1].replace("'>", "")

kw_wyd = dict(
tytul="Tytul %s %s" % (kl, c),
tytul_oryginalny="Tytul oryginalny %s %s" % (kl, c),
uwagi="Uwagi %s %s" % (kl, c),
szczegoly="Szczegóły %s %s" % (kl, c),
tytul=f"Tytul {kl} {c}",
tytul_oryginalny=f"Tytul oryginalny {kl} {c}",
uwagi=f"Uwagi {kl} {c}",
szczegoly=f"Szczegóły {kl} {c}",
)

if klass == Patent:
Expand Down Expand Up @@ -374,7 +376,7 @@ def assertPopupContains(browser, text, accept=True):
"""
alert = browser.driver.switch_to.alert
if text not in alert.text:
raise AssertionError("%r not found in %r" % (text, alert.text))
raise AssertionError(f"{text!r} not found in {alert.text!r}")
if accept:
alert.accept()

Expand Down Expand Up @@ -527,11 +529,19 @@ def browse_praca_url(model):
) # ContentType.objects.get_for_model(model).pk, model.pk)


def normalize_html(s):
def normalize_html(s: bytes | str, default_encoding="utf-8"):
if isinstance(s, bytes):
s = s.decode(default_encoding)
s = s.replace("\r\n", " ").replace("\n", " ")
return re.sub(r"\s\s+", " ", s)


def normalize_response_content(res: HttpResponse):
return normalize_html(
res.content, cgi.parse_header(res["content-type"])[1]["charset"]
)


def rozwin_ekstra_informacje_na_stronie_edycji_wydawnictwa(admin_browser):
for elem in admin_browser.find_by_tag("h2")[:3]:
show_element(admin_browser, elem) # ._element)
Expand Down
7 changes: 7 additions & 0 deletions src/fixtures/conftest.py
Expand Up @@ -197,6 +197,13 @@ def uczelnia(db):
)[0]


@pytest.fixture
def uczelnia_z_obca_jednostka(uczelnia, obca_jednostka):
uczelnia.obca_jednostka = obca_jednostka
uczelnia.save()
return uczelnia


@pytest.mark.django_db
def _wydzial_maker(nazwa, skrot, uczelnia, **kwargs):
return Wydzial.objects.get_or_create(
Expand Down
42 changes: 41 additions & 1 deletion src/import_pracownikow/models.py
@@ -1,6 +1,6 @@
# Create your models here.
from copy import copy
from datetime import date
from datetime import date, timedelta

from django import forms
from django.core.serializers.json import DjangoJSONEncoder
Expand Down Expand Up @@ -34,6 +34,8 @@

from django.contrib.postgres.fields import JSONField

from django.utils import timezone

from bpp.models import (
Autor,
Autor_Jednostka,
Expand Down Expand Up @@ -264,6 +266,44 @@ def get_details_set(self):
"wymiar_etatu",
)

def autorzy_spoza_pliku_set(self, uczelnia=None):
"""
Zwraca wszystkie połączenia Autor + Jednostka, gdzie:
1) połączenie autor + jednostka nie występuje w imporcie danych (self)
2) jednostka nie jest obca,
3) jednostka ma pole "zarzadzaj_automatycznie" zaznaczone jako True
"""

autorzy_jednostki_z_pliku = self.importpracownikowrow_set.values_list(
"autor_jednostka"
).distinct()

qry = (
Autor_Jednostka.objects.exclude(pk__in=autorzy_jednostki_z_pliku)
.exclude(autor__aktualna_jednostka=None)
.exclude(jednostka__zarzadzaj_automatycznie=False)
)

if uczelnia is not None and uczelnia.obca_jednostka_id is not None:
qry = qry.exclude(autor__aktualna_jednostka_id=uczelnia.obca_jednostka_id)

return qry

@transaction.atomic
def odepnij_autorow_spoza_pliku(self, uczelnia=None, today=None, yesterday=None):
if today is None:
today = timezone.now().date()

if yesterday is None:
yesterday = today - timedelta(days=1)

for elem in self.autorzy_spoza_pliku_set(uczelnia=uczelnia):
elem.zakonczyl_prace = yesterday
elem.podstawowe_miejsce_pracy = False
elem.save()

elem.refresh_from_db()

def on_finished(self):
self.send_processing_finished()

Expand Down
82 changes: 82 additions & 0 deletions src/import_pracownikow/tests/conftest.py
@@ -0,0 +1,82 @@
import os

import pytest
from django.core.files.uploadedfile import SimpleUploadedFile
from model_mommy import mommy

from import_pracownikow.models import ImportPracownikow

from bpp.models import Autor, Jednostka


def testdata_xls_path_factory(suffix=""):
return os.path.join(os.path.dirname(__file__), "", f"testdata{suffix}.xlsx")


def import_pracownikow_factory(user, path):
i = ImportPracownikow(owner=user)
i.plik_xls = SimpleUploadedFile(
"import_dyscyplin_zrodel_przyklad.xlsx", open(path, "rb").read()
)
i.save()
return i


@pytest.fixture
def testdata_xlsx_path():
return testdata_xls_path_factory()


@pytest.fixture
def testdata_brak_naglowka_xlsx_path():
return testdata_xls_path_factory("_brak_naglowka")


@pytest.fixture
def autor_z_pliku():
return mommy.make(Autor, nazwisko="Kowalski", imiona="Jan", pk=50)


@pytest.fixture
def jednostka_z_pliku():
return mommy.make(
Jednostka,
nazwa="Katedra i Klinika Dermatologii, Wenerologii i Dermatologii Dziecięcej",
skrot="Kat. i Klin. Derm., Wen. i Derm. Dz.",
)


@pytest.fixture
def baza_importu_pracownikow(autor_z_pliku, jednostka_z_pliku):
pass


@pytest.fixture
def autor_spoza_pliku():
return mommy.make(Autor, nazwisko="Nowak", imiona="Marian", pk=100)


@pytest.fixture
def jednostka_spoza_pliku() -> Jednostka:
return mommy.make(
Jednostka,
nazwa="Jednostka Spozaplikowa",
skrot="Jedn. Spoz.",
zarzadzaj_automatycznie=True,
)


@pytest.fixture
def import_pracownikow(admin_user, baza_importu_pracownikow, testdata_xlsx_path):
return import_pracownikow_factory(admin_user, testdata_xlsx_path)


@pytest.fixture
def import_pracownikow_performed(import_pracownikow) -> ImportPracownikow:
import_pracownikow.perform()
return import_pracownikow


@pytest.fixture
def import_pracownikow_brak_naglowka(admin_user, testdata_brak_naglowka_xlsx_path):
return import_pracownikow_factory(admin_user, testdata_brak_naglowka_xlsx_path)
59 changes: 5 additions & 54 deletions src/import_pracownikow/tests/test_models/test_models.py
@@ -1,55 +1,11 @@
import os

import pytest
from django.core.files.uploadedfile import SimpleUploadedFile
from model_mommy import mommy

from import_pracownikow.models import ImportPracownikow

from bpp.models import Autor, Autor_Jednostka, Jednostka


def testdata_xls_path_factory(suffix=""):
return os.path.join(os.path.dirname(__file__), "..", f"testdata{suffix}.xlsx")


@pytest.fixture
def testdata_xlsx_path():
return testdata_xls_path_factory()


@pytest.fixture
def testdata_brak_naglowka_xlsx_path():
return testdata_xls_path_factory("_brak_naglowka")


def import_pracownikow_factory(user, path):
i = ImportPracownikow(owner=user)
i.plik_xls = SimpleUploadedFile(
"import_dyscyplin_zrodel_przyklad.xlsx", open(path, "rb").read()
)
i.save()
return i


@pytest.fixture
def baza_importu_pracownikow():
mommy.make(
Jednostka,
nazwa="Katedra i Klinika Dermatologii, Wenerologii i Dermatologii Dziecięcej",
)
mommy.make(Autor, nazwisko="Kowalski", imiona="Jan", pk=50)

from import_pracownikow.tests.conftest import (
import_pracownikow_factory,
testdata_xls_path_factory,
)

@pytest.fixture
def import_pracownikow(admin_user, baza_importu_pracownikow, testdata_xlsx_path):
return import_pracownikow_factory(admin_user, testdata_xlsx_path)


@pytest.fixture
def import_pracownikow_performed(import_pracownikow):
import_pracownikow.perform()
return import_pracownikow
from bpp.models import Autor, Autor_Jednostka


def test_ImportPracownikow_perform(import_pracownikow):
Expand Down Expand Up @@ -82,11 +38,6 @@ def test_ImportPracownikow_perform_aktualizacja_tytulu_brakujacy_tytul(
assert Autor.objects.get(pk=50).tytul is None


@pytest.fixture
def import_pracownikow_brak_naglowka(admin_user, testdata_brak_naglowka_xlsx_path):
return import_pracownikow_factory(admin_user, testdata_brak_naglowka_xlsx_path)


def test_ImportPracownikow_brak_naglowka(import_pracownikow_brak_naglowka):
import_pracownikow_brak_naglowka.perform()
assert import_pracownikow_brak_naglowka.importpracownikowrow_set.count() == 0

0 comments on commit e43231c

Please sign in to comment.