Przejdź do treści

Time & Attendance (RCP) - Przykłady

Przykłady pokazują integrację systemu RCP vendora z API.ERP: karty RCP (AttendanceCredential), rejestratory (AttendanceTerminal) i atomowe zdarzenia czasu (AttendanceRecord). Jedno żądanie zapisu = jeden obiekt; odpowiedź zapisu i odczytu to koperta { "items": [...] }.

Słowniki: https://api-erp.kamsoft.pl/vs/hr/<slug> – attendance-credential-technology, attendance-credential-role, attendance-credential-status, attendance-terminal-status, attendance-terminal-capability, attendance-record-type, attendance-record-status (code-systems).

Legenda placeholderów urn:oid:2.999.<n>

Realne przestrzenie mają postać urn:oid:1.2.616.1.113769.4.<instalacja>.<klucz> i wynikają z NamingSystem – zob. Przykłady requestów i odpowiedzi. Numeracja jest lokalna dla tej strony.

Placeholder Przestrzeń (klucz)
urn:oid:2.999.1 AttendanceCredential.Id – id karty w KS-ZZL
urn:oid:2.999.2 AttendanceCredential.RcpId – numer karty (ID_RCP)
urn:oid:2.999.3 AttendanceCredential.Barcode – kod kreskowy karty
urn:oid:2.999.4 PartyRole.Id – pracownik (employee-{id})
urn:oid:2.999.5 AttendanceTerminal.Id – id rejestratora w KS-ZZL
urn:oid:2.999.6 AttendanceTerminal.ExternalId – id rejestratora u vendora
urn:oid:2.999.7 AttendanceRecord.Id – id zdarzenia w KS-ZZL
urn:oid:2.999.8 AttendanceRecord.ExternalId – id zdarzenia u vendora
urn:oid:2.999.9 Party.RcpId – ID_RCP pracownika na Party

1. Synchronizacja pracowników

Pracownicy i ich ID_RCP pochodzą z istniejących zasobów – API nie ma osobnej trasy pracowników RCP:

GET /v1/party-roles?role=https://api-erp.kamsoft.pl/vs/party-role|employee&count=100
GET /v1/parties?identifier=urn:oid:2.999.9|A1B2C3D4

PartyRole daje identyfikator pracownika (employee-{id}, przestrzeń PartyRole.Id), którego używają pola employee kart i zdarzeń. Party niesie ID_RCP (numer karty głównej) w przestrzeni Party.RcpId.


2. AttendanceCredential – wydanie karty głównej

2.1 Żądanie

Numer karty (AttendanceCredential.RcpId), employee i role są wymagane. Kod kreskowy – opcjonalny, tylko razem z numerem karty.

POST /v1/attendance-credentials
Content-Type: application/json
{
  "resourceType": "AttendanceCredential",
  "identifier": [
    { "system": "urn:oid:2.999.2", "value": "A1B2C3D4" },
    { "system": "urn:oid:2.999.3", "value": "5901234123457" }
  ],
  "employee": {
    "type": "PartyRole",
    "identifier": { "system": "urn:oid:2.999.4", "value": "employee-1001" }
  },
  "technology": { "coding": [{ "system": "https://api-erp.kamsoft.pl/vs/hr/attendance-credential-technology", "code": "mifare" }] },
  "role": { "coding": [{ "system": "https://api-erp.kamsoft.pl/vs/hr/attendance-credential-role", "code": "primary" }] },
  "status": { "coding": [{ "system": "https://api-erp.kamsoft.pl/vs/hr/attendance-credential-status", "code": "active" }] },
  "validPeriod": { "start": "2026-01-01", "end": "2026-12-31" },
  "issueDate": "2026-01-02"
}

2.2 Odpowiedź 200

Id karty nadane przez KS-ZZL wraca w identifier (przestrzeń AttendanceCredential.Id); pole id nie jest wypełniane.

{
  "items": [
    {
      "resourceType": "AttendanceCredential",
      "meta": {
        "lastModified": "2026-01-02T09:14:00Z",
        "warning": [
          { "system": "https://api-erp.kamsoft.pl/vs/resource-warning", "code": "unreconciled", "display": "Zasób nieuzgodniony między systemami" }
        ]
      },
      "identifier": [
        { "system": "urn:oid:2.999.1", "value": "9001" },
        { "system": "urn:oid:2.999.2", "value": "A1B2C3D4" },
        { "system": "urn:oid:2.999.3", "value": "5901234123457" }
      ],
      "employee": {
        "type": "PartyRole",
        "identifier": { "system": "urn:oid:2.999.4", "value": "employee-1001" }
      },
      "technology": { "coding": [{ "system": "https://api-erp.kamsoft.pl/vs/hr/attendance-credential-technology", "code": "mifare", "display": "MIFARE" }] },
      "role": { "coding": [{ "system": "https://api-erp.kamsoft.pl/vs/hr/attendance-credential-role", "code": "primary", "display": "Karta główna (ID_RCP)" }] },
      "status": { "coding": [{ "system": "https://api-erp.kamsoft.pl/vs/hr/attendance-credential-status", "code": "active", "display": "Aktywna" }] },
      "validPeriod": { "start": "2026-01-01", "end": "2026-12-31" },
      "issueDate": "2026-01-02"
    }
  ]
}

Druga aktywna karta primary tego samego pracownika kończy się 422.


3. AttendanceCredential – zmiana karty głównej

Dwa kroki, nieatomowo: najpierw dotychczasowa karta na secondary, potem nowa karta na primary. W odwrotnej kolejności drugi zapis kończy się 422.

PATCH /v1/attendance-credentials?identifier=urn:oid:2.999.1|9001
Content-Type: application/json
{
  "resourceType": "AttendanceCredential",
  "role": { "coding": [{ "system": "https://api-erp.kamsoft.pl/vs/hr/attendance-credential-role", "code": "secondary" }] }
}
PATCH /v1/attendance-credentials?identifier=urn:oid:2.999.1|9002
Content-Type: application/json
{
  "resourceType": "AttendanceCredential",
  "role": { "coding": [{ "system": "https://api-erp.kamsoft.pl/vs/hr/attendance-credential-role", "code": "primary" }] }
}

Zablokowanie karty – ten sam wzorzec ze status = blocked i revocationDate. Nieznana karta → 404.


4. AttendanceTerminal – rejestracja rejestratora

Rejestrator musi istnieć przed pierwszym zdarzeniem z tego urządzenia. Wymagany identyfikator vendora (AttendanceTerminal.ExternalId).

POST /v1/attendance-terminals
Content-Type: application/json
{
  "resourceType": "AttendanceTerminal",
  "identifier": [
    { "system": "urn:oid:2.999.6", "value": "GATE-A-01" }
  ],
  "name": "Wejście główne A",
  "status": { "coding": [{ "system": "https://api-erp.kamsoft.pl/vs/hr/attendance-terminal-status", "code": "active" }] },
  "capability": [
    { "coding": [{ "system": "https://api-erp.kamsoft.pl/vs/hr/attendance-terminal-capability", "code": "clock-in" }] },
    { "coding": [{ "system": "https://api-erp.kamsoft.pl/vs/hr/attendance-terminal-capability", "code": "clock-out" }] }
  ]
}

5. AttendanceRecord – import zdarzenia

5.1 Żądanie

Jedno zdarzenie na żądanie. Pracownik rozpoznany po karcie; identyfikator vendora (AttendanceRecord.ExternalId) zapewnia idempotencję.

POST /v1/attendance-records
Content-Type: application/json
{
  "resourceType": "AttendanceRecord",
  "identifier": [
    { "system": "urn:oid:2.999.8", "value": "evt-77881" }
  ],
  "eventDate": "2026-10-05T08:00:00+02:00",
  "type": { "coding": [{ "system": "https://api-erp.kamsoft.pl/vs/hr/attendance-record-type", "code": "clock-in" }] },
  "credential": {
    "type": "AttendanceCredential",
    "identifier": { "system": "urn:oid:2.999.2", "value": "A1B2C3D4" }
  },
  "terminal": {
    "type": "AttendanceTerminal",
    "identifier": { "system": "urn:oid:2.999.6", "value": "GATE-A-01" }
  }
}

5.2 Odpowiedź 200 – zdarzenie przyjęte

  • eventDate wraca w UTC: zapisany czas zegarowy 08:00 (czas polski) → 06:00:00Z.
  • employee wraca rozpoznany z karty.
  • terminal wraca w przestrzeni AttendanceTerminal.Id, nie AttendanceTerminal.ExternalId.
{
  "items": [
    {
      "resourceType": "AttendanceRecord",
      "meta": {
        "lastModified": "2026-10-05T06:00:02Z",
        "warning": [
          { "system": "https://api-erp.kamsoft.pl/vs/resource-warning", "code": "unreconciled", "display": "Zasób nieuzgodniony między systemami" }
        ]
      },
      "identifier": [
        { "system": "urn:oid:2.999.7", "value": "80" },
        { "system": "urn:oid:2.999.8", "value": "evt-77881" }
      ],
      "eventDate": "2026-10-05T06:00:00Z",
      "type": { "coding": [{ "system": "https://api-erp.kamsoft.pl/vs/hr/attendance-record-type", "code": "clock-in", "display": "Przyjście" }] },
      "employee": {
        "type": "PartyRole",
        "identifier": { "system": "urn:oid:2.999.4", "value": "employee-1001" }
      },
      "credential": {
        "type": "AttendanceCredential",
        "identifier": { "system": "urn:oid:2.999.2", "value": "A1B2C3D4" }
      },
      "terminal": {
        "type": "AttendanceTerminal",
        "identifier": { "system": "urn:oid:2.999.5", "value": "4" }
      },
      "status": { "coding": [{ "system": "https://api-erp.kamsoft.pl/vs/hr/attendance-record-status", "code": "accepted", "display": "Przyjęte" }] }
    }
  ]
}

5.3 Odpowiedź 422 – zdarzenie odrzucone

Ponowne wysłanie evt-77881 daje duplicate; zdarzenie bez rejestratora lub z nieznanym rejestratorem – rejected. Oba przypadki zwracają problem details, a detail niesie powód:

{
  "status": 422,
  "type": "http://hl7.org/fhir/issue-type#business-rule",
  "title": "Business Rule Violation",
  "detail": "nie znaleziono terminalu",
  "instance": "/v1/attendance-records",
  "traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
  "issues": [
    { "severity": "error", "code": "business-rule", "details": { "text": "nie znaleziono terminalu" } }
  ]
}

Brak eventDate lub type, kod spoza słownika albo zły format employee → 400; nic nie trafia do bazy.


6. Odczyt

GET /v1/attendance-credentials?employee=urn:oid:2.999.4|employee-1001&status=https://api-erp.kamsoft.pl/vs/hr/attendance-credential-status|active
GET /v1/attendance-terminals?status=https://api-erp.kamsoft.pl/vs/hr/attendance-terminal-status|active
GET /v1/attendance-records?employee=urn:oid:2.999.4|employee-1001&terminal=urn:oid:2.999.5|4&type=https://api-erp.kamsoft.pl/vs/hr/attendance-record-type|clock-in&count=100
GET /v1/attendance-records?identifier=urn:oid:2.999.8|evt-77881

Odpowiedź – koperta listowa { "items": [...], "nextToken": null } (konwencje techniczne). Filtry po dacie zdarzenia i dacie zmiany nie są obsługiwane.


Odniesienia