Partneru API (#19245)¶
Ticket #19245 ietvaros ieviesto/paplašināto softera API galapunktu dokumentācija: partnerorganizācijas izveide, organizāciju meklēšana, LOCCAT kataloga atrašanās vietu CRUD, organizācijas GLN maiņa.
Vispārīgi¶
- Pamaturl:
https://api-test.docura.net/ap1/partner/api/ - Autentifikācija: galvene
X-Authorization: <api_key>(lietotāja pilnvaru, lauksapi_keytabulāusers). - Klienti neizmanto galveni
X-App-Key— aizmugursistēmā šī pārbaude pašlaik nav savienota ar nevienu filtru ķēdi (nedarbojošs kods kopš 2023. gada), tāpēc to var izlaist. - Formāts — JSON (izņemot gadījumus, kad tas ir skaidri norādīts citādi).
- Lomām (pilnvarām):
SYSTEM_ADMIN,SYSTEM_SUPPORT,CLIENT_ADMIN,CLIENT_EDITOR,PROVIDER_ADMIN— par konkrētām atļautajām lomām skatīt katra galapunkta aprakstu.
1. Partnerorganizācijas izveide¶
POST /user/organization¶
Izveido jaunu organizāciju un pievieno tai izsaucošo lietotāju kā CLIENT_ADMIN (ar atsevišķu, agrāku soli izveides procesā).
Tiesības: nav lomu ierobežojumu — pieejams jebkuram autentificētam lietotājam. Tiesības tiek izteiktas nevis ar zvanītāja lomu, bet gan ar to, kurai organizācijai pieder pats zvanītājs (skat. operatorId loģiku zemāk).
Pieprasījuma pamatteksts:
| Lauks | Tips | Obligāts | Ierobežojumi |
|---|---|---|---|
| taxId | string | jā | 2–20 rakstzīmes |
| registrationNumber | string | jā | 2–50 rakstzīmes |
| name | string | jā | 2–50 rakstzīmes |
| countryCode | string | jā | 2 rakstzīmes |
| locale | string | jā | 2 rakstzīmes, jābūt pieejamam lokalizāciju sarakstā |
| errorEmail | string | nē | līdz 250 rakstzīmēm, e-pasta formāts |
| notes | string | nē | līdz 255 rakstzīmēm |
| phones | string | nē | līdz 50 rakstzīmēm |
| string | nē | līdz 150 rakstzīmēm, e-pasta formāts |
Lauks integrationProfileType, kas parādījās šīs funkcijas agrākajās iterācijās tajā pašā biļetē, tika noņemts no gala versijas — klients nevar skaidri izvēlēties profilu/connectionType (skat. zemāk).
Atbilde (200): tas pats lauku kopums + id (Long), iln (ģenerētais organizācijas GLN).
Kļūdas:
-
409 Conflict(organization.create.conflict.tax_id) — organizācija ar šotaxIdjau pastāv. -
400— nederīgi pieprasījuma pamatteksta lauki (bean validācija), vai lokalizācija nav atrasta (not.exists.specified.organization.locale).
Loģika, lai noteiktu jaunās organizācijas operatoru (operatorId)¶
Tas tiek aprēķināts no IZSAUCĒJA lietotāja organizācijas pašas (callerIln — sesijas pašreizējās organizācijas ILN), bez skaidriem parametriem pieprasījumā:
- Ja zvanītāja organizācija ir pati softera (
profile.softeraOrganizationIln) → jaunās organizācijas operators = pati softera. Turklāt šajā gadījumā jaunajai organizācijai kāCLIENT_ADMINtiek pievienots noklusējuma softera lietotājs (profile.softeraDefaultUserId, ja ir iestatīts). - Ja zvanītāja organizācija ir pakalpojumu sniedzējs (
role='P', bet ne softera) → operators = paša zvanītāja organizācija. - Citādi (ne softera, ne pakalpojumu sniedzējs) → operators = organizācija no
profile.defaultOperatorOrganizationIln(atgriežas pie "noklusējuma operatora"). - Ja ne izsaucošā organizācija, ne rezerves organizācija netiek atrasta pēc ILN —
500(IllegalStateException, parasti nevajadzētu notikt).
connectionType loģika jaunajai organizācijai¶
- Izsaucējs ir Softra → vienmēr
Payment(cīti kodēts, neatkarīgi ne no kā). - Citādi →
connectionType= operatora organizācijas pašasconnectionType(iepriekš aprēķinātais — pakalpojumu sniedzējs vai rezerves organizācija). Klients nevar skaidri norādītconnectionType/integrācijas profilu.
2. Organizāciju meklēšana¶
GET /organizations/search?query=<string>¶
Tiesības: SYSTEM_ADMIN, SYSTEM_SUPPORT, PROVIDER_ADMIN. Nav ierobežojumu pēc operatorId — pakalpojumu sniedzējs redz rezultātus visā organizāciju datubāzē, ne tikai savus klientus (apzināts lēmums, kas pieņemts šīs biļetes ietvaros).
Parametri:
| Parametrs | Tips | Obligāts | Apraksts |
|---|---|---|---|
| query | string | yes | Meklēšanas virkne. Tukša/trūkstoša virkne → tukšs saraksts bez kļūdas. |
Meklēšanas loģika DB — viens OR organizācijā:
- precīza atbilstība
id(kā tekstam); - precīza atbilstība
iln(GLN); - precīza atbilstība
regNr(bez reģistra jutības); - precīza atbilstība
vatNr(bez reģistra jutības); - apakšvirkne (
ILIKE) organizācijasname; - apakšvirkne (
ILIKE) jebkuras tās LOCCAT atrašanās vietasname.
Atbilde (200): masīvs, katrs elements ietverts organization objektā:
[
{
"organization": {
"id": 100099815,
"name": "New brand sof",
"iln": "2000005810008",
"taxId": "...",
"registrationNumber": "...",
"countryCode": "EE",
"locations": [ { "id": ..., "iln": "...", "name": "...", "formattedAddress": "...", ... } ]
}
}
]
Svarīga nianse: locations[] satur tikai tās atrašanās vietas, kuru nosaukums atbilda meklēšanas virknei — ne visas atrastās organizācijas atrašanās vietas. Ja organizācija tika atrasta pēc id/iln/regNr/vatNr/nosaukuma, un ne pēc atrašanās vietas nosaukuma, locations būs tukšs masīvs. Šī ir apzināta darbība, nevis kļūda.
3. LOCCAT organizācijas atrašanās vietas¶
Pamatceļš: /organization/{gln}/locations, kur {gln} ir organizācijas GLN (nevis ciparu ID).
Tiesības (kopīgas visām trim tālāk norādītajām metodēm):
-
SYSTEM_ADMIN/SYSTEM_SUPPORT— bez ierobežojumiem. -
PROVIDER_ADMIN— tikai tad, ja zvanītāja organizācija = mērķa organizācijasoperatorId(pakalpojumu sniedzējs pārvalda paša apkalpoto organizāciju atrašanās vietas). - Citas lomas —
403(not.have.access). - Organizācija nav atrasta pēc GLN →
400(organization.not.exists).
3.1 POST /organization/{gln}/locations — izveidot/atjaunināt atrašanās vietu¶
Upsert loģika:
- Ja
idtiek nodots pamattekstā — esošās atrašanās vietas tieša atjaunināšana pēc tās iekšējā ID (tai jāpieder norādītajai organizācijai, pretējā gadījumā404). - Ja
idnetiek nodots, betilntiek nodots — tiek meklēta esoša organizācijas atrašanās vieta ar šoiln; ja tiek atrasta, tā tiek atjaunināta, ja nē, tiek izveidota jauna. - Ja
ilnnetiek nodots (vai ir "tukšs" saskaņā arIlnHelper.isEmpty) — atrašanās vietas GLN tiek ģenerēts automātiski (skatīt zemāk).
Pieprasījuma pamatteksts (LoccatLocationWithIdData — LoccatLocationData + neobligāts id):
| Lauks | Tips | Obligāts | Ierobežojumi |
|---|---|---|---|
| id | Long | nē | tiešai atjaunināšanai |
| iln | virkne | nē | līdz 13 simboliem; ja nav — automātiski ģenerēts |
| codeBySender | virkne | jā | līdz 70 simboliem |
| codeByReceiver | virkne | nē | līdz 70 simboliem |
| name | virkne | jā | līdz 175 simboliem |
| legal | boolean | nē | "juridiskās adreses" karodziņš |
| formattedAddress | virkne | nē | līdz 300 simboliem |
| streetAndNumber | virkne | nē | līdz 140 simboliem |
| streetAndNumber2 | virkne | nē | līdz 140 simboliem |
| city | virkne | nē | līdz 175 simboliem |
| state | virkne | nē | līdz 175 simboliem |
| postalCode | virkne | nē | līdz 9 simboliem |
| countryCode | virkne | nē | līdz 2 simboliem |
| latitude / longitude | double | nē | |
| remarks | virkne | nē | līdz 350 simboliem |
| phoneNumber | virkne | nē | līdz 175 simboliem |
| virkne | nē | līdz 350 simboliem, e-pasta formāts | |
| web | virkne | nē | līdz 175 simboliem |
Atbilde (200): tas pats pamatteksts + izveidotās/atjauninātās atrašanās vietas id.
Atrašanās vietas GLN automātiska ģenerēšana (ja iln netiek nodots)¶
Tā atkārtoti izmanto mantoto algoritmu UserWebController.getNextLocalizationCatalogGln (pamata):
- Ja organizācijai jau ir atrašanās vietas (
maxIlnatrasts) → nākamais GLN = pēdējā ģenerētā GLN pamatteksts + 1. - Ja nav atrašanās vietu un organizācija ir testa organizācija (
isTest) → GLN tiek veidots no organizācijasglnPrefix, papildināts ar nullēm. - Ja nav atrašanās vietu, organizācija nav testa organizācija un nav "juridiskās" atrašanās vietas → tiek atgriezts pašas organizācijas GLN.
- Ja ir juridiskā atrašanās vieta, bet nav citu (robežgadījums) → GLN tiek veidots no
glnPrefix.
Papildus (izmaiņas no šīs biļetes): ja šādi ģenerētais GLN sakrīt ar pašas organizācijas GLN (iepriekš minētās 2. un 3. sadaļas) — tas tiek palielināts par 1, lai tas nekad nepārklātos ar organizācijas GLN.
Zināmie ierobežojumi (pieņemti tādi, kādi tie ir, bez papildu aizsardzības):
- Nav transakciju bloķēšanas starp "iegūt nākamo GLN" un "izveidot atrašanās vietu ar to" — ar paralēliem pieprasījumiem bez
ilnir iespējama sacensība un400 duplicate.line.iln. - Pārpildes palielinājums (GLN pamatteksts =
999999999999) teorētiski varētu radīt GLN, kas ir par vienu rakstzīmi garāks nekā parasti — ārkārtīgi maz ticams robežgadījums, labojums netika pieprasīts. -
legalkarogs NETIEK automātiski iestatīts pirmajā atrašanās vietā, kas izveidota beziln— ja organizācijai nav juridiskās atrašanās vietas, atkārtotsPOSTbezilnmēģinās atkārtoti ģenerēt to pašu organizācijas GLN un neizdosies ar400 duplicate.line.iln. Klientam jāpasniedzilnvai nu skaidri otrajos un nākamajos pieprasījumos, vai arī jāpārvaldalegalpats.
3.2 GET /organization/{gln}/locations — iegūt atrašanās vietas¶
Specifika: filtrs tiek nodots GET pieprasījuma pamattekstā (JSON); tie nav vaicājuma parametri. Ja pamatteksts ir tukšs (Content-Length <= 0) — tiek atgrieztas visas organizācijas atrašanās vietas.
Pieprasījuma pamatteksts (neobligāts):
| Lauks | Tips | Apraksts |
|---|---|---|
| id | Long | precīza meklēšana pēc atrašanās vietas ID (plus neobligāta pārbaude pret GLN, ja tas ir nodots) |
| iln | string | filtrēt pēc GLN |
| name | string | filtrēt pēc nosaukuma (apakšvirkne) |
| address | string | filtrēt pēc adreses (apakšvirkne) |
Prioritāte: ja id tiek nodots — tiek atgriezta (maksimums) viena atrašanās vieta pēc ID; citādi, ja vismaz viens no iln/name/address ir iestatīts — filtrēta meklēšana; citādi — visas organizācijas atrašanās vietas.
Atbilde (200): atrašanās vietu masīvs (tāds pats formāts kā POST atbildē).
3.3 DELETE /organization/{gln}/locations¶
Pieprasījuma pamatteksts (obligāts):
| Lauks | Tips | Obligāts |
|---|---|---|
| id | Long | jā |
Dzēšana tikai pēc iekšējā atrašanās vietas ID; dzēšana pēc iln netiek īstenota (tika apsvērta un atcelta šīs biļetes ietvaros).
Atbilde: 200 veiksmes gadījumā, 404, ja atrašanās vieta ar šādu ID netiek atrasta organizācijā, 400 location.id.should.be.specified, ja id netiek nodots.
4. Organizācijas GLN maiņa¶
PATCH /organization/{organizationId}/gln?gln=<new GLN>¶
Piezīme: šeit {organizationId} ir organizācijas skaitliskais iekšējais ID (atšķirībā no iepriekšminētajiem atrašanās vietas galapunktiem, kas ceļā izmanto GLN).
Tiesības:
-
SYSTEM_ADMIN/SYSTEM_SUPPORT— nav ierobežojumu. -
PROVIDER_ADMIN— tikai tad, ja izsaucēja organizācija = mērķa organizācijasoperatorId. - Citi —
403 not.have.access. - Organizācija nav atrasta pēc ID →
404(tukšs korpuss).
Parametri:
| Parametrs | Tips | Obligāts |
|---|---|---|
| gln | string | jā, vaicājuma parametrs |
Kas notiek iekšpusē (tiek atkārtoti izmantots standarta organizācijas atjaunināšanas konveijers, OrganizationUpdateEvent → OrganizationCommonUpdateHandler):
- GLN formāta validācija + kontroldati →
400kļūdas gadījumā. - Dublikātu pārbaude — GLN nedrīkst piederēt citai organizācijai →
400 Duplicate ILN. - Vecā vērtība tiek saglabāta
previousIln. - Ja organizācijai ir "juridiska" LOCCAT atrašanās vieta — tās
ilntiek automātiski sinhronizēts ar organizācijas jauno GLN (loccatReconciliation). Ja nav juridiskas atrašanās vietas — solis tiek klusi izlaists. - Standarta organizācijas atjaunināšanas saskaņošanas soļi (partneris/nosacījums/paziņojumi utt., nav specifiski šai funkcijai).
Atbilde (200): organizācijas korpuss (OrganizationWithIdData) ar jau piemērotu jauno GLN.
5. Beigu punktu kopsavilkuma tabula¶
| Metode | Ceļš | Ceļa identifikators | Lomas |
|---|---|---|---|
| POST | /user/organization | — | jebkurš autentificēts |
| GET | /organizations/search | — | SYSTEM_ADMIN, SYSTEM_SUPPORT, PROVIDER_ADMIN |
| POST | /organization/{gln}/locations | GLN | SYSTEM_ADMIN, SYSTEM_SUPPORT, PROVIDER_ADMIN (operatorId-match) |
| GET | /organization/{gln}/locations | GLN | SYSTEM_ADMIN, SYSTEM_SUPPORT, PROVIDER_ADMIN (operatorId-match) |
| DELETE | /organization/{gln}/locations | GLN | SYSTEM_ADMIN, SYSTEM_SUPPORT, PROVIDER_ADMIN (operatorId-match) |
| PATCH | /organization/{organizationId}/gln | ciparu ID | SYSTEM_ADMIN, SYSTEM_SUPPORT, PROVIDER_ADMIN (operatorId-match) |
6. Piemēri¶
# Create an organisation
curl --location --request POST 'https://api-test.docura.net/ap1/partner/api/user/organization' \
--header 'X-Authorization: <token>' \
--header 'Content-Type: application/json' \
--data '{
"taxId": "EE100000001",
"registrationNumber": "12345678",
"name": "Example OU",
"countryCode": "EE",
"locale": "en"
}'
# Search organisations
curl --location 'https://api-test.docura.net/ap1/partner/api/organizations/search?query=Example' \
--header 'X-Authorization: <token>'
# Create a location without an explicit GLN (auto-generation)
curl --location --request POST 'https://api-test.docura.net/ap1/partner/api/organization/<org_gln>/locations' \
--header 'X-Authorization: <token>' \
--header 'Content-Type: application/json' \
--data '{
"name": "Warehouse 1",
"codeBySender": "WH1",
"countryCode": "EE"
}'
# Get all locations of an organisation
curl --location 'https://api-test.docura.net/ap1/partner/api/organization/<org_gln>/locations' \
--header 'X-Authorization: <token>'
# Delete a location by id
curl --location --request DELETE 'https://api-test.docura.net/ap1/partner/api/organization/<org_gln>/locations' \
--header 'X-Authorization: <token>' \
--header 'Content-Type: application/json' \
--data '{"id": 682021}'
# Change an organisation's GLN
curl --location --request PATCH 'https://api-test.docura.net/ap1/partner/api/organization/<numeric_id>/gln?gln=2000005819995' \
--header 'X-Authorization: <token>'
Source version: 3 · Status: fresh · Roman Startsev