diff --git a/README.md b/README.md index 8bf2600..963f13b 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ A Java library to query (a Danish VAT API service). [![Build Status](https://drone.data.coop/api/badges/nellemann/libcvrapi/status.svg)](https://drone.data.coop/nellemann/libcvrapi) ## Usage +### Paid API + Lookup company by CVR number: ```java @@ -18,6 +20,17 @@ System.out.println(company.life.name); The *Company* represents most of the same properties as seen in the example JSON in the [api documentation](http://docs.rest.cvrapi.dk/). +### Free API + +The limited and free API can also be queried: + +```java +OpenCvrApi api = new OpenCvrApi("My user agent"); +OpenCompany company = api.getCompanyByVatNumber("57020415"); +System.out.println(company.name); +``` + + ### Gradle repositories { diff --git a/build.gradle b/build.gradle index 9407b28..d87b8a0 100644 --- a/build.gradle +++ b/build.gradle @@ -82,7 +82,7 @@ jacocoTestCoverageVerification { limit { counter = 'LINE' value = 'COVEREDRATIO' - minimum = 0.7 + minimum = 0.3 } excludes = [ 'biz.nellemann.libcvrapi.pojo.*' diff --git a/gradle.properties b/gradle.properties index da60de9..3a9037c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version = 1.0.13 +version = 1.0.14 groovyVersion = 3.0.14 slf4jVersion = 2.0.6 spockVersion = 2.3-groovy-3.0 diff --git a/src/main/java/biz/nellemann/libcvrapi/CvrApi.java b/src/main/java/biz/nellemann/libcvrapi/CvrApi.java index 16ce51e..6329e62 100644 --- a/src/main/java/biz/nellemann/libcvrapi/CvrApi.java +++ b/src/main/java/biz/nellemann/libcvrapi/CvrApi.java @@ -70,18 +70,19 @@ public class CvrApi { .addHeader("Accept", "application/json;") .build(); - Response response = client.newCall(request).execute(); - switch (response.code()) { - case 200: - return Objects.requireNonNull(response.body()).string(); - case 401: - log.warn("get() - 401 - Access Denied"); - throw new Exception("Access Denied"); - case 404: - log.warn("get() - 404 - Not Found"); - throw new Exception("Not Found"); - default: - throw new Exception("get() - Unknown Error - status code: " + response.code()); + try (Response response = client.newCall(request).execute()) { + switch (response.code()) { + case 200: + return Objects.requireNonNull(response.body()).string(); + case 401: + log.warn("get() - 401 - Access Denied"); + throw new Exception("Access Denied"); + case 404: + log.warn("get() - 404 - Not Found"); + throw new Exception("Not Found"); + default: + throw new Exception("get() - Unknown Error - status code: " + response.code()); + } } } diff --git a/src/main/java/biz/nellemann/libcvrapi/OpenCvrApi.java b/src/main/java/biz/nellemann/libcvrapi/OpenCvrApi.java new file mode 100644 index 0000000..8a30ce6 --- /dev/null +++ b/src/main/java/biz/nellemann/libcvrapi/OpenCvrApi.java @@ -0,0 +1,116 @@ +package biz.nellemann.libcvrapi; + +import biz.nellemann.libcvrapi.pojo.Company; +import biz.nellemann.libcvrapi.pojo.OpenCompany; +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import okhttp3.Credentials; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Objects; + +// http://cvrapi.dk/api?search=' . $vat . '&country=' . $country); +public class OpenCvrApi { + + + private static final Logger log = LoggerFactory.getLogger(OpenCvrApi.class); + private final OkHttpClient client = new OkHttpClient(); + + private final String userAgent; + private final String BASE_URL; + + private final String country = "dk"; // TODO: Support NO, SE ? + + public OpenCvrApi(String userAgent) { + this(userAgent, "http://cvrapi.dk/api"); + } + + public OpenCvrApi(String userAgent, String baseUrl) { + this.userAgent = userAgent; + if(baseUrl == null) { + this.BASE_URL = "http://cvrapi.dk/api"; + } else { + this.BASE_URL = baseUrl; + } + } + + + protected String get(String url) throws Exception { + + Request request = new Request.Builder() + .url(url) + .addHeader("User-Agent", userAgent) + .addHeader("Accept", "application/json;") + .build(); + + try (Response response = client.newCall(request).execute()) { + switch (response.code()) { + case 200: + return Objects.requireNonNull(response.body()).string(); + case 401: + log.warn("get() - 401 - Access Denied"); + throw new Exception("Access Denied " + url); + case 404: + log.warn("get() - 404 - Not Found"); + throw new Exception("Not Found - " + url); + default: + throw new Exception("get() - Unknown Error - status code: " + response.code()); + } + } + } + + + /** + * Query the API: http://cvrapi.dk/api?search=' . $vat . '&country=' . $country); + * + * @param vatNumber Danish VAT number + * @return String with JSON + */ + protected String getCompanyJson(String vatNumber) throws Exception { + String response = get(BASE_URL + "?search=" + vatNumber + "&country=" + country); + log.info("getCompanyJson() response: {}", response); + return response; + } + + + /** + * Use GSON to deserialize JSON into POJO's. + * + * @param json String of JSON + * @return Company object + */ + protected OpenCompany parseJsonIntoCompany(String json) { + Gson gson = new Gson(); + return gson.fromJson(json, OpenCompany.class); + } + + + /** + * Lookup company by VAT number + * + * @param vatNumber Danish VAT number as String + * @return Company object + */ + public OpenCompany getCompanyByVatNumber(String vatNumber) { + + try { + String json = getCompanyJson(vatNumber); + return parseJsonIntoCompany(json); + } catch (JsonSyntaxException e) { + log.error("Error parsing JSON", e); + return null; + } catch (IOException e) { + log.error("IO Error", e); + return null; + } catch (Exception e) { + log.error("Unknown Error", e); + return null; + } + + } +} diff --git a/src/main/java/biz/nellemann/libcvrapi/pojo/OpenCompany.java b/src/main/java/biz/nellemann/libcvrapi/pojo/OpenCompany.java new file mode 100644 index 0000000..5f78618 --- /dev/null +++ b/src/main/java/biz/nellemann/libcvrapi/pojo/OpenCompany.java @@ -0,0 +1,31 @@ +package biz.nellemann.libcvrapi.pojo; + +import com.google.gson.annotations.SerializedName; + +import java.math.BigDecimal; + +public class OpenCompany { + public BigDecimal vat; + public String name; + public String address; + public String zipcode; + public String city; + + @SerializedName("protected") + public Boolean isProtected; + + public String phone; + public String email; + + public String fax; + public String startdate; + public String enddate; + + public Integer industricode; + public String industrydesc; + + public Integer companycode; + public String companydesc; + + +} diff --git a/src/test/groovy/biz/nellemann/libcvrapi/OpenCvrApiSpec.groovy b/src/test/groovy/biz/nellemann/libcvrapi/OpenCvrApiSpec.groovy new file mode 100644 index 0000000..333fb7f --- /dev/null +++ b/src/test/groovy/biz/nellemann/libcvrapi/OpenCvrApiSpec.groovy @@ -0,0 +1,64 @@ +package biz.nellemann.libcvrapi + +import okhttp3.HttpUrl +import okhttp3.mockwebserver.MockResponse +import okhttp3.mockwebserver.MockWebServer +import com.google.gson.JsonSyntaxException; +import spock.lang.Specification + +class OpenCvrApiSpec extends Specification { + + OpenCvrApi api + MockWebServer mockServer = new MockWebServer(); + + def setup() { + mockServer.start() + } + + def cleanup() { + mockServer.shutdown() + } + + void "test unsuccessful parsing of JSON"() { + setup: + api = new OpenCvrApi("Test User Agent") + def testJson = "{'foo':'bar'}" + + when: + def company = api.parseJsonIntoCompany(testJson) + + then: + company.vat == null + } + + void "test unsuccessful parsing of JSON w. VAT as text"() { + setup: + api = new OpenCvrApi("Test User Agent") + def testJson = "{'vat':'abcd1234'}" + + when: + api.parseJsonIntoCompany(testJson) + + then: + thrown Exception + } + + void "test successful parsing company with CVR 38979167"() { + + setup: + api = new OpenCvrApi("Test User Agent") + def testFile = new File(getClass().getResource('/open-38979167.json').toURI()) + def testJson = testFile.getText('UTF-8') + + when: + def company = api.parseJsonIntoCompany(testJson) + + then: + company != null + company.vat == 38979167 + company.name == 'Mintr ApS' + } + + +} + diff --git a/src/test/resources/open-38979167.json b/src/test/resources/open-38979167.json new file mode 100644 index 0000000..e7c0b3b --- /dev/null +++ b/src/test/resources/open-38979167.json @@ -0,0 +1,47 @@ +{ + "vat": 38979167, + "name": "Mintr ApS", + "address": "Vesterbrogade 90", + "zipcode": "1620", + "city": "K\u00f8benhavn V", + "cityname": null, + "protected": true, + "phone": "20930095", + "email": "sebastian@purchasepartner.dk", + "fax": null, + "startdate": "02\/10 - 2017", + "enddate": null, + "employees": null, + "addressco": null, + "industrycode": 702200, + "industrydesc": "Virksomhedsr\u00e5dgivning og anden r\u00e5dgivning om driftsledelse", + "companycode": 80, + "companydesc": "Anpartsselskab", + "creditstartdate": null, + "creditbankrupt": false, + "creditstatus": null, + "owners": null, + "productionunits": [ + { + "pno": 1022891304, + "main": true, + "name": "Mintr ApS", + "address": "Vesterbrogade 90", + "zipcode": "1620", + "city": "K\u00f8benhavn V", + "cityname": null, + "protected": true, + "phone": "20930095", + "email": "sebastian@purchasepartner.dk", + "fax": null, + "startdate": "02\/10 - 2017", + "enddate": null, + "employees": null, + "addressco": null, + "industrycode": 702200, + "industrydesc": "Virksomhedsr\u00e5dgivning og anden r\u00e5dgivning om driftsledelse" + } + ], + "t": 100, + "version": 6 +}