Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
5e539ef
fix(migrations): merge leaf nodes 0005 w importer_publikacji
mpasternak Apr 20, 2026
640197f
feat(pbn_api): narzędzie pbn_test_wysylka_interaktywna do audytu PBN
mpasternak Apr 20, 2026
b24dd0b
ci(docker): buduj obrazy tylko z pull_request (nie z push do feature/**)
mpasternak Apr 21, 2026
7dc56c7
docs(pbn): rozszerzona instrukcja testowania pbn_test_wysylka_interak…
mpasternak Apr 21, 2026
ac077e5
fix(pbn-test-narzedzie): porównuj intencję BPP (live) zamiast cache i…
mpasternak Apr 21, 2026
df6c5c6
fix(tests): naprawa 2 pre-existing failing testów na dev
mpasternak Apr 21, 2026
a0824fb
fix(pbn-test-narzedzie): popraw klucze porównania w KROK 6/8
mpasternak Apr 21, 2026
ed54c26
Merge remote-tracking branch 'origin/dev' into feature/pbn-test-wysyl…
mpasternak Apr 21, 2026
16ebdfa
fix(migrations): 0007_merge — łączy 0006 z branch i 0006 z dev
mpasternak Apr 21, 2026
daa66f4
feat(pbn): StatementsResendFailedException + Uczelnia.pbn_kasuj_dyscy…
mpasternak Apr 21, 2026
3092d1b
refactor(pbn): upload_publication zawsze przez endpoint repo + dead c…
mpasternak Apr 21, 2026
0c52b99
feat(pbn): helpery split-flow synchronizacji oświadczeń
mpasternak Apr 21, 2026
200cb6e
feat(pbn): sync_publication nowy split flow (POST repo + osobna synch…
mpasternak Apr 21, 2026
678e1c4
refactor(pbn_integrator): usuń delete_statements_before_upload
mpasternak Apr 21, 2026
02d13dc
test(pbn): zaktualizuj testy sync_publication dla nowego split-flow
mpasternak Apr 21, 2026
a7186d9
feat(pbn_export_queue): RETRY_LATER handling dla StatementsResendFail…
mpasternak Apr 21, 2026
3067b60
docs(pbn): changelog + update pbn-wysylka-plan.md dla Fazy 2
mpasternak Apr 21, 2026
d42c70a
fix(pbn): NameError releaseDateYear + priorytet openaccess_data_opubl…
mpasternak Apr 22, 2026
0a9f607
Merge remote-tracking branch 'origin/dev' into feature/pbn-test-wysyl…
mpasternak Apr 22, 2026
8d7d52f
fix(pbn): POST sync statements wysyła tylko brakujące w PBN (selectiv…
mpasternak Apr 23, 2026
42a9f8e
Merge remote-tracking branch 'origin/dev' into feature/pbn-test-wysyl…
mpasternak Apr 27, 2026
77959ef
Merge remote-tracking branch 'origin/dev' into feature/pbn-test-wysyl…
mpasternak Apr 27, 2026
6988a16
Merge remote-tracking branch 'origin/dev' into feature/pbn-test-wysyl…
mpasternak Apr 27, 2026
c8d91a0
feat(docker): branch alias również w stopce dev buildów
mpasternak Apr 27, 2026
70dc6a5
feat(pbn): popraw wysylke do repo + audit URL endpointu w SentData
mpasternak Apr 27, 2026
da820b9
Merge remote-tracking branch 'origin/dev' into feature/pbn-test-wysyl…
mpasternak Apr 27, 2026
37ffe2c
ci(docker): wez dev'owa wersje build-docker workflow + usun .docker-b…
mpasternak Apr 27, 2026
01cc538
ci(docker): wywal mechanizm .docker-build z workflow
mpasternak Apr 27, 2026
eaa396b
fix(pbn): migracja 0069 musi byc atomic=False
mpasternak Apr 27, 2026
386ecde
ci(docker): buduj PR/feature push tylko gdy actor=mpasternak
mpasternak Apr 27, 2026
0a4dfee
fix(html-minify): zabezpiecz frontend przed regresjami minifikacji HTML
mpasternak Apr 27, 2026
29cc284
Merge branch 'dev' into feature/pbn-test-wysylka-interaktywna
mpasternak Apr 27, 2026
1e31818
feat(pbn_export_queue): wskazuj OpenAPI v3 spec w AI prompt
mpasternak Apr 27, 2026
0c5cba1
Merge remote-tracking branch 'origin/dev' into feature/pbn-test-wysyl…
mpasternak Apr 27, 2026
c525c79
feat(pbn_api): loguj headers i raw body przy 5xx z PBN
mpasternak Apr 27, 2026
28a33ee
feat(pbn): przywróć warunkowy wybór endpointu wysyłki publikacji
mpasternak Apr 27, 2026
7ecc7e0
feat(pbn_api): rollbar + console logger dla diagnostyki API >=400
mpasternak Apr 27, 2026
006a714
feat(pbn): kasuj oświadczenia z PBN PRZED POST do /v1/repositorium
mpasternak Apr 27, 2026
e848366
Merge branch 'dev' into feature/pbn-test-wysylka-interaktywna
mpasternak May 2, 2026
e0640f9
Merge branch 'dev' into feature/pbn-test-wysylka-interaktywna
mpasternak May 3, 2026
f5301c2
Merge branch 'dev' into feature/pbn-test-wysylka-interaktywna
mpasternak May 4, 2026
55c7cf2
Merge branch 'feature/nowe-zglos-publikacje' into feature/pbn-test-wy…
mpasternak May 4, 2026
23fe7ef
Merge branch 'dev' into feature/pbn-test-wysylka-interaktywna
mpasternak May 4, 2026
3902364
Merge
mpasternak May 4, 2026
c352c20
Dodano exponential backoff dla pobierania PublikacjaInstytucji_V2
mpasternak May 4, 2026
5b7d9e3
Merge branch 'dev' into feature/pbn-test-wysylka-interaktywna
mpasternak May 4, 2026
e9219f5
Fix workflows
mpasternak May 4, 2026
4c7d208
Merge branch 'dev' into feature/pbn-test-wysylka-interaktywna
mpasternak May 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .github/workflows/build-docker-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,19 @@ jobs:
echo "::notice::Docker build — znaleziono flage [docker-build] w commit message"
else
echo "should_build=false" >> "$GITHUB_OUTPUT"
# Dla pull_request event github.ref_name to "<PR#>/merge"
# (wewnetrzny merge-ref GH, nie branch). `gh workflow run --ref`
# wymaga nazwy brancha — dla PR pobieramy ja z `gh pr view`,
# dla push event'u uzywamy REF_NAME.
if [ "$EVENT_NAME" = "pull_request" ]; then
PR_NUM="${REF_NAME%/merge}"
DISPATCH_REF=$(gh pr view "$PR_NUM" --repo "$REPO" \
--json headRefName --jq '.headRefName')
else
DISPATCH_REF="$REF_NAME"
fi
echo "::notice::Pomijam Docker build — brak flagi [docker-build] w commit message"
echo "::notice::Aby wymusic build, dodaj [docker-build] do commit message lub uruchom: gh workflow run build-docker-images.yml --ref ${REF_NAME}"
echo "::notice::Aby wymusic build, dodaj [docker-build] do commit message lub uruchom recznie: gh workflow run build-docker-images.yml --ref ${DISPATCH_REF}"
fi

docker:
Expand Down
362 changes: 362 additions & 0 deletions docs/pbn-wysylka-plan.md

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions src/bpp/admin/helpers/pbn_api/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def sprawdz_wysylke_do_pbn_w_parametrach_uczelni(uczelnia):
return uczelnia


def sprobuj_wyslac_do_pbn(
def sprobuj_wyslac_do_pbn( # noqa: C901
obj, pbn_client, uczelnia, notificator, force_upload=False, raise_exceptions=False
):
# Sprawdź, czy wydawnictwo nadrzędne ma odpowoednik PBN:
Expand Down Expand Up @@ -156,7 +156,6 @@ def sprobuj_wyslac_do_pbn(
obj,
notificator=notificator,
force_upload=force_upload,
delete_statements_before_upload=uczelnia.pbn_api_kasuj_przed_wysylka,
export_pk_zero=not uczelnia.pbn_api_nie_wysylaj_prac_bez_pk,
always_affiliate_to_uid=(
uczelnia.pbn_uid_id
Expand Down Expand Up @@ -247,8 +246,8 @@ def sprobuj_wyslac_do_pbn(
extra = ""
if link_do_wyslanych:
extra = (
'<a target=_blank href="%s">Kliknij, aby otworzyć widok wysłanych danych</a>.'
% link_do_wyslanych
f'<a target=_blank href="{link_do_wyslanych}">'
f"Kliknij, aby otworzyć widok wysłanych danych</a>."
)

notificator.warning(
Expand Down
2 changes: 1 addition & 1 deletion src/bpp/admin/uczelnia.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class UczelniaAdmin(
"pbn_app_name",
"pbn_app_token",
"pbn_api_user",
"pbn_api_kasuj_przed_wysylka",
"pbn_kasuj_dyscypliny_selektywnie",
"pbn_api_nie_wysylaj_prac_bez_pk",
"pbn_api_afiliacja_zawsze_na_uczelnie",
"pbn_wysylaj_bez_oswiadczen",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("bpp", "0413_bppuser_autor_onetoone"),
]

operations = [
migrations.RemoveField(
model_name="uczelnia",
name="pbn_api_kasuj_przed_wysylka",
),
migrations.AddField(
model_name="uczelnia",
name="pbn_kasuj_dyscypliny_selektywnie",
field=models.BooleanField(
default=True,
help_text=(
"Gdy zaznaczone: ``sync_publication`` usuwa oświadczenia "
"selektywnie per-osoba (DELETE ``/publications/{id}`` z "
"``{personId, role}``) i wysyła tylko brakujące. Gdy "
"odznaczone: usuwa wszystkie oświadczenia publikacji jednym "
"DELETE (``{all: True}``), a następnie wysyła wszystkie "
"lokalne jako batch. Wariant selektywny zachowuje metadata "
"PBN (``addedTimestamp`` itd.) dla identycznych rekordów."
),
verbose_name="Kasuj oświadczenia selektywnie (per osoba)",
),
),
]
13 changes: 13 additions & 0 deletions src/bpp/migrations/0416_merge_20260504_1024.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Generated by Django 5.2.13 on 2026-05-04 08:24

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("bpp", "0414_uczelnia_pbn_kasuj_dyscypliny_selektywnie"),
("bpp", "0415_merge_20260504_0907"),
]

operations = []
14 changes: 12 additions & 2 deletions src/bpp/models/uczelnia.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,18 @@ class Uczelnia(ModelZAdnotacjami, ModelZPBN_ID, NazwaISkrot, NazwaWDopelniaczu):
pbn_app_token = models.CharField(
"Token aplikacji w PBN", blank=True, default="", max_length=128
)
pbn_api_kasuj_przed_wysylka = models.BooleanField(
"Kasuj oświadczenia rekordu przed wysłaniem do PBN", default=False
pbn_kasuj_dyscypliny_selektywnie = models.BooleanField(
"Kasuj oświadczenia selektywnie (per osoba)",
default=True,
help_text=(
"Gdy zaznaczone: ``sync_publication`` usuwa oświadczenia "
"selektywnie per-osoba (DELETE ``/publications/{id}`` z "
"``{personId, role}``) i wysyła tylko brakujące. Gdy "
"odznaczone: usuwa wszystkie oświadczenia publikacji jednym "
"DELETE (``{all: True}``), a następnie wysyła wszystkie "
"lokalne jako batch. Wariant selektywny zachowuje metadata "
"PBN (``addedTimestamp`` itd.) dla identycznych rekordów."
),
)
pbn_api_nie_wysylaj_prac_bez_pk = models.BooleanField(
"Nie wysyłaj do PBN prac z PK=0", default=False
Expand Down
17 changes: 17 additions & 0 deletions src/bpp/newsfragments/+pbn-post-statements-subset.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Poprawka w ``sync_publication``: POST oświadczeń publikacji w trybie
selektywnym (``Uczelnia.pbn_kasuj_dyscypliny_selektywnie=True``, default)
wysyła teraz TYLKO oświadczenia brakujące w PBN (``only_in_intended``),
nie pełen zestaw lokalnych. Wcześniej kod wywoływał
``WydawnictwoPBNAdapter.pbn_get_api_statements()`` zwracające wszystkie
lokalne statements i POST-ował kompletny zestaw — także te oświadczenia,
które już były w PBN. Przy założeniu że API PBN może nie być
idempotentne (odrzucić duplikaty, utworzyć zduplikowane rekordy albo
zachowywać się nieprzewidywalnie), wysyłanie tylko brakujących jest
bezpieczniejsze — nie dublujemy żądań dla już istniejących oświadczeń,
co zachowuje ich metadata w PBN (``addedTimestamp`` itp.).

Krok 3 algorytmu (PBN puste + BPP ma) nadal wysyła wszystkie oświadczenia
publikacji, bo w tym scenariuszu ``only_in_intended`` = wszystkie klucze
lokalne. Krok 5 (tryb batch, ``pbn_kasuj_dyscypliny_selektywnie=False``)
pozostaje bez zmian — po ``delete_all`` PBN jest puste, więc POST wysyła
pełen zestaw BPP (wipe+rewrite).
28 changes: 28 additions & 0 deletions src/bpp/newsfragments/+pbn-sync-publication-split-flow.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Refaktoryzacja wysyłki publikacji do PBN (``sync_publication``): publikacja
jest zawsze wysyłana przez endpoint repozytoryjny
``POST /api/v1/repositorium/publications`` (bez oświadczeń w body), a
dyscypliny/oświadczenia synchronizowane są w osobnym kroku przez
``/api/v2/institution-profile/statements`` dopiero po potwierdzeniu
wysyłki publikacji. Dzięki temu nieudana wysyłka publikacji (np. HTTP
423 Locked albo inna przejściowa awaria PBN) nie kasuje już istniejących
oświadczeń w profilu instytucji — wcześniej kasowanie działo się przed
POST i tracono dane przy każdym niepowodzeniu.

Algorytm synchronizacji oświadczeń: GET aktualnego stanu PBN, porównanie
z intencją BPP (``WydawnictwoPBNAdapter.pbn_get_json_statements()``)
przez klucz ``(personId, disciplineId)``, selektywne DELETE (per-osoba
przez ``delete_publication_statement(personId, role)``) brakujących w
BPP + POST dodatkowych. Tryb kasowania sterowany nową flagą
``Uczelnia.pbn_kasuj_dyscypliny_selektywnie`` (domyślnie ``True``;
``False`` używa ``delete_all`` + POST batch).

Nowy wyjątek ``StatementsResendFailedException`` (w
``pbn_api.exceptions``) jest podnoszony gdy retry x3 z exponential
backoff (2s/4s/8s) na GET/DELETE/POST /v2/statements się wyczerpie.
Klasyfikowany w ``pbn_export_queue`` jako ``RETRY_LATER`` — kolejka
ponowi wysyłkę za kilka minut.

Usunięto pole ``Uczelnia.pbn_api_kasuj_przed_wysylka`` (obsolete —
stary pre-upload DELETE zastąpiony nowym algorytmem diff po wysyłce).
Flaga ``Uczelnia.pbn_wysylaj_bez_oswiadczen`` pozostaje z dotychczasową
semantyką (odmawia wysyłki publikacji bez oświadczeń).
20 changes: 20 additions & 0 deletions src/bpp/newsfragments/+pbn-test-narzedzie-fix-compare.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Poprawka w narzędziu CLI ``pbn_test_wysylka_interaktywna``:

- krok porównania oświadczeń (KROK 6/8) używał lokalnego cache'a
``OswiadczenieInstytucji`` (snapshot z poprzedniej synchronizacji
PBN) jako reprezentanta „stanu BPP", co powodowało fałszywą
identyczność po zmianach w rekordzie — skasowaniu autora,
zmianie/wypięciu dyscypliny lub innej edycji ``Wydawnictwo_*_Autor``
(cache nie był re-synchronizowany, pokazywał stare 3 oświadczenia
nawet po faktycznym zmniejszeniu intencji BPP do 2). Narzędzie
teraz porównuje **intencję BPP na żywo** — to co by wygenerował
``WydawnictwoPBNAdapter.pbn_get_api_statements()`` gdyby wysyłać
teraz — z aktualnym stanem PBN. Dodatkowo KROK 1/8 pokazuje zarówno
cache jak i intencję żywą, żeby od razu widać było rozjazd.
- narzędzie zawsze pyta osobno o DELETE oświadczeń i osobno o POST
oświadczeń, także gdy porównanie zwróciło identyczność —
użytkownik może wymusić operację np. dla empirycznego sprawdzenia
reakcji PBN (wcześniej flow kończył się wczesnym ``return`` po
identyczności bez opcji kontynuacji). Domyślna wartość pytania
zależy od wyniku porównania: „identyczne" → default ``n``,
„różnice" → default ``t``.
13 changes: 13 additions & 0 deletions src/bpp/newsfragments/+pbn-test-wysylka-interaktywna.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Dodano interaktywne narzędzie CLI
``pbn_test_wysylka_interaktywna`` (Django management command) do
eksperymentalnego testowania flow wysyłki publikacji i oświadczeń do PBN
krok po kroku. Narzędzie prowadzi użytkownika przez kolejne fazy —
generowanie JSON publikacji, wybór endpointa (``/api/v1/publications``
all-in-one albo ``/api/v1/repositorium/publications`` bez oświadczeń),
POST publikacji, GET i porównanie oświadczeń lokalnych z tym co jest w
PBN, DELETE oświadczeń i POST przez ``/api/v2/institution-profile/statements``
— pokazując dla każdego kroku metodę HTTP, URL, body i odpowiedź
serwera. Narzędzie nie modyfikuje lokalnej bazy BPP i posiada tryb
``--dry-run``. Służy jako baza do audytu zachowania PBN API i
projektowania bezpieczniejszej kolejności operacji wysyłki (scenariusz:
nieudana wysyłka publikacji kasowała wcześniej istniejące oświadczenia).
13 changes: 13 additions & 0 deletions src/bpp/newsfragments/+pbn-v2-retry.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Dodano exponential backoff (5 prób, max ~30 sekund) przy pobieraniu
``PublikacjaInstytucji_V2`` (UUID publikacji z PBN API v2). Poprzednio
jedna próba kończyła się warningiem "nie jest błędem", co myliło użytkowników
— brak V2 oznacza brak możliwości generowania linków do PBN Interfejs
i wysyłki oświadczeń (wymagany UUID). Teraz system automatycznie ponawia
z rosnącym czasem oczekiwania (2s, 4s, 8s, 16s, 32s).

Jeśli po wszystkich próbach nadal nie ma V2 — wyświetlany jest BŁĄD (czerwony)
z sugestią użycia wysyłki w tle (PBN Export Queue) zamiast interaktywnej.

**Ważne dla deploymentu**: przy interaktywnej wysyłce z admina może być potrzebne
zwiększenie timeoutu nginx/gunicorn dla ścieżek ``/admin/`` do minimum 90-120 sekund
(domyślne 30-60s może być za mało przy 5 próbach z opóźnieniami).
4 changes: 2 additions & 2 deletions src/bpp_setup_wizard/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ def save(self, commit=True):
uczelnia = super().save(commit=False)

# Set the fields that should always be True
uczelnia.pbn_api_kasuj_przed_wysylka = (
True # Kasuj oświadczenia przed wysłaniem do PBN
uczelnia.pbn_kasuj_dyscypliny_selektywnie = (
True # Selektywny DELETE oświadczeń per-osoba (nowy flow)
)
uczelnia.pbn_api_nie_wysylaj_prac_bez_pk = (
True # Nie wysyłaj do PBN prac z PK=0
Expand Down
2 changes: 1 addition & 1 deletion src/bpp_setup_wizard/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ def test_uczelnia_setup_create_uczelnia(admin_user):
assert uczelnia.uzywaj_wydzialow is True

# Verify the automatically set fields
assert uczelnia.pbn_api_kasuj_przed_wysylka is True
assert uczelnia.pbn_kasuj_dyscypliny_selektywnie is True
assert uczelnia.pbn_api_nie_wysylaj_prac_bez_pk is True
assert uczelnia.pbn_api_afiliacja_zawsze_na_uczelnie is True
assert uczelnia.pbn_wysylaj_bez_oswiadczen is True
Expand Down
9 changes: 9 additions & 0 deletions src/django_bpp/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1380,6 +1380,15 @@ def iter_namespace(ns_pkg):
"level": "INFO",
"propagate": False,
},
# Logger dla pbn_api - WARNING+ na konsolę. W szczególności
# `_check_error_response` w transport.py loguje pełne body
# i headers przy odpowiedziach >= 400, co jest kluczowe przy
# diagnostyce błędów typu „400 Bad Request" bez czytelnego body.
"pbn_api": {
"handlers": ["console"],
"level": "WARNING",
"propagate": False,
},
},
}

Expand Down
13 changes: 13 additions & 0 deletions src/importer_publikacji/migrations/0006_merge_20260420_2212.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Generated by Django 5.2.13 on 2026-04-20 20:12

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("importer_publikacji", "0005_alter_importsession_created_by"),
("importer_publikacji", "0005_importsession_wydawnictwo_nadrzedne"),
]

operations = []
13 changes: 13 additions & 0 deletions src/importer_publikacji/migrations/0007_merge_20260421_1248.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Generated by Django 5.2.13 on 2026-04-21 10:48

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("importer_publikacji", "0006_merge_20260420_2212"),
("importer_publikacji", "0006_merge_20260421_1100"),
]

operations = []
31 changes: 25 additions & 6 deletions src/pbn_api/adapters/wydawnictwo.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,16 +237,35 @@ def _build_open_access_base_fields(self) -> dict:
return oa

def _build_open_access_release_date(self, oa: dict) -> None:
"""Add release date fields to OpenAccess dict."""
if self.original.public_dostep_dnia is not None:
"""Ustawia pola daty udostępnienia OpenAccess.

Priorytet źródeł (od najbardziej dedykowanego):

1. ``openaccess_data_opublikowania`` — pole dedykowane OpenAccess
(``ModelZOpenAccess``), ustawiane przez importer z PBN i przez
redakcję ręcznie. To powinno być podstawowe źródło.
2. ``public_dostep_dnia`` — data wolnego dostępu do strony WWW
(``ModelZWWW``). Fallback dla starszych rekordów bez dedykowanej
daty OpenAccess.
3. ``dostep_dnia`` — data płatnego dostępu. Ostatni fallback.

Gdy żadna z dat nie jest wypełniona, pola ``releaseDate``,
``releaseDateMonth``, ``releaseDateYear`` NIE są ustawiane.
Wcześniejsza implementacja wstawiała hardcoded
``{"releaseDateMonth": "JANUARY", "releaseDateYear": str(rok)}``,
co wysyłało do PBN nieprawdziwe dane (styczeń niezależnie od
faktycznego miesiąca publikacji). Lepiej pominąć pola i zmusić
PBN do zwrócenia validation error (lub zaakceptowania, jeśli
spec pozwala), niż wysyłać kłamliwy miesiąc.
"""
data_oa = getattr(self.original, "openaccess_data_opublikowania", None)
if data_oa is not None:
oa["releaseDate"] = str(data_oa)
elif self.original.public_dostep_dnia is not None:
oa["releaseDate"] = str(self.original.public_dostep_dnia)
elif self.original.dostep_dnia is not None:
oa["releaseDate"] = str(self.original.dostep_dnia)

if oa.get("releaseDate") is None:
oa["releaseDateMonth"] = "JANUARY"
oa["releaseDateYear"] = str(self.original.rok)

def _build_open_access(self, pub_type: str) -> dict | None:
"""Build OpenAccess data structure if all required fields are present."""
oa = self._build_open_access_base_fields()
Expand Down
Loading
Loading