Przejdź do treści

AttendanceRecord (zdarzenie czasu pracy)

AttendanceRecord to zasób reprezentujący atomowe zdarzenie rejestracji czasu pracy: jedno przyłożenie karty, jedno wejście lub wyjście. Nie modeluje pary przyjście–wyjście ani rozliczonego interwału obecności – te powstają w warstwie rozliczeniowej KS-ZZL. Atomowość pozwala przyjmować zdarzenia w trybie real-time, bez czekania na domknięcie dnia pracy. Rozszerza DomainResource.


1. Zakres i zastosowanie

AttendanceRecord = jedno odbicie: eventDate, type (rodzaj zdarzenia), terminal (rejestrator), employee lub credential (identyfikacja pracownika), status (wynik przetworzenia), opcjonalnie note i statusReason.

  • Import zdarzeń – jedno żądanie POST = jedno zdarzenie. API nie przyjmuje paczek zdarzeń.
  • Identyfikacja pracownika – kolejność: employee (jeśli podany i istnieje) → credential (aktywna AttendanceCredential o podanym numerze wskazuje pracownika; numer jest unikalny wśród kart aktywnych, karty zablokowane są pomijane) → brak identyfikacji, zdarzenie odrzucone.
  • Idempotencja – identyfikator vendora w przestrzeni AttendanceRecord.ExternalId; ponowne wysłanie tego samego zdarzenia daje status duplicate i nie tworzy nowego rekordu. Bez identyfikatora vendora duplikat rozpoznaje krotka (terminal, credential, eventDate, type) w obrębie instalacji.
  • Reconciliation – porównanie zdarzeń przyjętych przez API z zapisami po stronie vendora (GET).

Poza zakresem: grafiki pracy, absencje, timesheet, naliczenia płacowe oraz korekta lub usuwanie zdarzeń przez API.


2. Zawartość (struktura)

Oprócz elementów DomainResource (id, resourceType, meta, owner, comment, category, status, type, contained, attribute):

Nazwa Kard. Typ Opis
identifier 0..* Identifier Id zdarzenia w KS-ZZL (w odpowiedzi) i id zdarzenia u vendora (idempotencja) – przestrzenie w §2b
eventDate 1..1 string Moment zdarzenia, ISO 8601 – zob. „Czas zdarzenia” poniżej
employee 0..1 Reference(PartyRole) Pracownik – PartyRole (role=employee), employee-{id} w przestrzeni PartyRole.Id; jeśli znany po stronie vendora
credential 0..1 Reference(AttendanceCredential) Karta użyta do identyfikacji – w przestrzeni AttendanceCredential.RcpId (numer karty; rozstrzygany wśród kart aktywnych) albo AttendanceCredential.Id
terminal 1..1 Reference(AttendanceTerminal) Rejestrator, na którym nastąpiło odbicie – w zapisie w przestrzeni AttendanceTerminal.ExternalId
note 0..1 string Komentarz do zdarzenia
statusReason 0..1 string Powód odrzucenia; przy odrzuceniu trafia do detail odpowiedzi błędu

Uwaga: type i status pochodzą z DomainResource – słowniki w §3. type jest przy zapisie wymagany; status wypełnia strona przyjmująca.

Uwaga: pole id nie jest wypełniane – id zdarzenia w KS-ZZL zwracane jest w identifier (przestrzeń AttendanceRecord.Id). Dopóki zasób nie jest uzgodniony między systemami, meta.warning zawiera kod unreconciled (resource-warning).

Czas zdarzenia. Zapis przyjmuje eventDate z offsetem, z Z, bez offsetu i z milisekundami; zapisywany jest czas zegarowy z żądania – offset nie powoduje przeliczenia strefy. Odczyt zwraca czas w UTC (…Z), przeliczony z czasu polskiego (Europe/Warsaw): zdarzenie wysłane jako 2026-10-05T08:00:00+02:00 wraca jako 2026-10-05T06:00:00Z. Nadawca powinien wysyłać czas lokalny rejestratora.


2a. Operacje

Metoda Ścieżka Opis
POST /v1/attendance-records Import jednego zdarzenia
GET /v1/attendance-records Odczyt zdarzeń (reconciliation)

Wynik POST:

Wynik HTTP Treść
accepted 200 { "items": [ <AttendanceRecord> ] } – zdarzenie z id KS-ZZL i status = accepted
rejected, duplicate 422 Problem details; detail = powód (np. "nie znaleziono terminalu")
Błąd walidacji 400 Brak eventDate lub type, kod spoza słownika, zły format employee – nic nie trafia do bazy

W odpowiedzi 200:

  • credential jest uzupełniany kartą pracownika, nawet gdy nadawca go nie podał,
  • terminal wraca w przestrzeni AttendanceTerminal.Id (id KS-ZZL), a nie w przestrzeni AttendanceTerminal.ExternalId podanej w żądaniu.
GET /v1/attendance-records?employee=<przestrzeń PartyRole.Id>|employee-1001&type=https://api-erp.kamsoft.pl/vs/hr/attendance-record-type|clock-in&count=20&offset=0
Parametr Opis
identifier Jedna para system\|wartość w przestrzeni AttendanceRecord.Id albo AttendanceRecord.ExternalId
employee Pracownik – para system\|wartość w przestrzeni PartyRole.Id albo PartyRole\|<wartość>
terminal Rejestrator – para system\|wartość w przestrzeni AttendanceTerminal.Id
type system\|kod ze słownika hr/attendance-record-type
count, offset Paginacja (domyślnie 20 / 0)

Odczyt nie ma filtrów po dacie zdarzenia ani po dacie zmiany. Odpowiedź: { "items": [...], "nextToken": null }.


2b. Identyfikatory

Przestrzenie wdrożeniowe urn:oid:1.2.616.1.113769.4.<instalacja>.<klucz> publikowane jako NamingSystem – zob. Identyfikacja i parametry wdrożenia.

Przestrzeń (klucz) Znaczenie Klucz referencyjny Skąd system
AttendanceRecord.Id Id zdarzenia w KS-ZZL; nadaje system prowadzący, zwracany w odpowiedzi tak NamingSystem
AttendanceRecord.ExternalId Id zdarzenia u vendora RCP – podstawa idempotencji tak NamingSystem

3. Systemy kodowania (value sety)

Pole Słownik Kody
type hr/attendance-record-type clock-in, clock-out, business-clock-in, business-clock-out, private-clock-in, private-clock-out, break-start, break-end, meal-start, meal-end, unknown
status hr/attendance-record-status accepted, rejected, duplicate

Kody przy zapisie są porównywane bez rozróżniania wielkości liter (CLOCK-IN = clock-in); dopuszczalny jest też kod podany wyłącznie w text. Kod unknown występuje w odczycie, ale zdarzenie z unknown jest przy imporcie odrzucane (422).

Wiązania type i status nie są zapisane w JSON Schema (pola pochodzą z DomainResource) – tabela powyżej jest jedynym miejscem, gdzie są udokumentowane; walidacja należy do warstwy API.


4. Odniesienia