API ORSR.SK - Parser obchodného registra
Postupujúca informatizácia spoločnosti kladie nároky na dostupnosť informačných zdrojov pre tvorcov softwarových aplikácií.
Ku základným zdrojom patria nepochybne verejne dostupné databázy obchodných firiem a spoločností, živnostníkov, verejné zoznamy dlžníkov odvodov a neplatičov daní apod.
Obchodný register SR je primárny zdroj informácií o obchodných subjektoch SR. Bol zriadený pred niekoľkými rokmi v čase, keď vývojári podnikových a účtovných systémov neboli ešte tak ďaleko, aby dokázali integrovať služby spojené s vyhľadávaním obchodných subjektov.
Dnes je situácia však iná. Dopyt po verejných spravovaných zdrojoch údajov je veľmi veľký. Vznikli spoločnosti profesionálne sa venujúce data miningu, predávajúce sofistikované údaje o spoločnostiach, analyzujúce parametre o subjektoch ako napr. bonitu alebo podlžnosti potenciálnych obchodných partnerov apod.
Bohužiaľ, obchodný register SR trochu zaostáva za svojou dobou. Neposkytnuje žiadne verejné rozhranie umožňujúce prístup ku informáciám v ORSR tvorcom softwarov - API pre web services. Neposkytuje taktiež žiadnu možnosť získať bežným komerčným spôsobom prístup ku databáze ORSR napr. zakúpením si CD/DVD s ročným poplatkom za pravidelné aktualizácie databázy.
Nakoľko pri vývoji portálu ipdf.sk som potreboval vyriešiť tento problém, napísal som parser obchodného registra SR. Umožňuje vyhľadávanie subjektov podľa IČO, názvu spoločnosti alebo priezviska a mena osoby. Výsledkom vyhľadania sú normalizované štruktúrované dáta, napr. príslušnosť ku súdu, typ osoby, či sa spoločnosť nachádza v likvidácii, adresa s rozložením do ulice, popisného čísla, PSČ a mesta apod.
Parser sa snaží zároveň ošetriť chyby vzniknuté pri zadávaní údajov do databázy (bežne sa vyskytujúce uvodzovky v názve spoločností), normalizovať údaje (napr. rôzne usporiadané adresy, zahraničné adresy apod.) a formátovanie pre vhodnejšie použitie vo vývojovom prostredí (napr. 10.000,- Sk zmení na 10000).
Sprístupnenie kódu - Github.com
Z dôvodu početných žiadostí od developerov bol kód ORSR API sprístupnený na githube.Demo - vyhľadávanie v obchodnom registri SR
Výsledok hľadania:
HTML:
<div class="form-group">
<label for="byName">podľa názvu spoločnosti (zadajte aspoň 3 písmená):</label>
<input type="text" id="byName" placeholder="napr. Kerametal" maxlength="30" class="form-control" />
<div id="response-message"></div>
</div>
JS / jQuery:
$("#byName").autocomplete({
// solution #1 - simpler e.g. without spinner
// 'source' => '/orsr/find-by-company-name', // implement in your own OrsrController
// solution #2 - advanced e.g. add spinner or custom "no match" message
'source' => function(request, response) {
var msg = $("#response-message");
$("#byName").parent().find("label")
.append("<span class='spinner-border spinner-border-sm'></span>");
$.ajax({
url: "/orsr/find-by-company-name", // implement in your own OrsrController
data: { term: request.term },
success: function (data) {
$("span.spinner-border").remove();
if (!data.length) {
msg.hide().html("Žádné záznamy pro: <b>"+request.term+"</b>").fadeIn();
}
response ($.map(data, function(item) {
return {
label: item.label, // e.g. "AAA AUTODOPRAVA s. r. o."
value: item.value // unique hash e.g. dnlwaXUyOCZTSUQ9NyZQPTA=
// note: instead of hash you can return from OrsrController e.g. IČO
}
}));
}
})
},
'minLength' => 3,
'delay' => 750,
'select' => function(event, ui) {
var msg = $("#response-message");
$("span.spinner-border").remove();
$("#byName").parent().find("label")
.append("<span class='spinner-border spinner-border-sm'></span>");
event.preventDefault(); // prevent from setting JSON string into search field
$(this).val(ui.item.label);
// load company details
$.ajax({
url: "/orsr/company-detail", // implement in your own OrsrController
data: { id : ui.item.value }, // company identifier - hash, ico, ..
complete: function (response) {
$("span.spinner-border").remove();
},
success: function (response) {
if (response && response.html) {
msg.html("<h3>Spoločnosť: "+(ui.item.label)+" </h3>"+response.html);
}else{
msg.hide().html("<span class='text-red'>Neplatná odpoveď zo servera.</span>").fadeIn();
}
},
error : function() {
msg.hide().html("<span class='text-red'>Chyba spojenia.</span>").fadeIn();
}
})
},
'focus' => function(event, ui) {
event.preventDefault();
$(this).val(ui.item.label); // set company name into search field
},
});
PHP:
// see parser source code at Github.com:
// https://github.com/lubosdz/parser-orsr/blob/master/ConnectorOrsr.php
// OrsrController example:
class OrsrController extends Controller
{
/**
* Ajax demo handler - return autocomplete options for matching company name
*/
public function actionFindByCompanyName()
{
$term = empty($_GET['term']) ? '' : htmlspecialchars(trim($_GET['term']));
$out = [];
$connector = new ConnectorOrsr();
$results = $connector->findByObchodneMeno($term);
if($results && is_array($results)){
foreach($results as $name => $link){
// here we are returning link hash, which needs to be back decoded on selection
// instead, you may return another attribute, e.g. IČO
$link = StringHelper::base64UrlEncode($link);
$out[] = [
'label' => $name,
'value' => $link
];
}
}
return $this->asJson($out);
}
/**
* Ajax demo handler - return parsed company details
*/
public function actionCompanyDetail()
{
$link = empty($_GET['hash']) ? '' : StringHelper::base64UrlDecode($_GET['hash']);
$out = [];
if ($link) {
$connector = new ConnectorOrsr();
// here we assume hash contains company permalink
// instead you can supply another parameters and use different
// method e.g. $connector->getDetailById() or $connector->getDetailByICO()
$out = $connector->getDetailByPartialLink($link);
}
return $this->asJson($out);
}
}