package io.konik.sdk.invoice;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.util.Maps;
import io.konik.InvoiceTransformer;
import io.konik.sdk.http.InsufficientCreditsAmountException;
import io.konik.sdk.http.ZinvoiceHttpClient;
import io.konik.zugferd.Invoice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Map;
public class RestInvoiceApi implements InvoiceApi {
private static final Logger log = LoggerFactory.getLogger(RestInvoiceApi.class);
private final ZinvoiceHttpClient httpClient;
private final InvoiceTransformer invoiceTransformer;
public RestInvoiceApi(ZinvoiceHttpClient zinvoiceHttpClient) {
this.httpClient = zinvoiceHttpClient;
this.invoiceTransformer = new InvoiceTransformer();
}
public RestInvoiceApi(ZinvoiceHttpClient zinvoiceHttpClient, InvoiceTransformer invoiceTransformer) {
this.httpClient = zinvoiceHttpClient;
this.invoiceTransformer = invoiceTransformer;
}
@Override
public InvoiceDocument getInvoice(String id) {
InvoiceDocument.Response response = httpClient.get("/invoice/" + id, InvoiceDocument.Response.class);
if (response != null) {
return response.getDocument();
}
return null;
}
@Override
public InvoiceResponse createInvoice(Invoice invoice) {
byte[] invoiceXml = invoiceTransformer.fromModel(invoice);
return httpClient.post("/invoice", invoiceXml, "application/xml", InvoiceResponse.class);
}
@Override
public InvoiceResponse createDraftInvoice(Invoice invoice) {
byte[] invoiceXml = invoiceTransformer.fromModel(invoice);
return httpClient.post("/invoice/draft", invoiceXml, "application/xml", InvoiceResponse.class);
}
@Override
public InvoiceResponse updateInvoice(String invoiceId, Invoice invoice) {
byte[] invoiceXml = invoiceTransformer.fromModel(invoice);
return httpClient.put("/invoice/" + invoiceId, invoiceXml, "application/xml", InvoiceResponse.class);
}
@Override
public InvoiceResponse updateDraftInvoice(String invoiceId, Invoice invoice) {
byte[] invoiceXml = invoiceTransformer.fromModel(invoice);
return httpClient.put("/invoice/draft/" + invoiceId, invoiceXml, "application/xml", InvoiceResponse.class);
}
@Override
public InputStream downloadInvoiceAsPDF(String invoiceId) {
try {
return httpClient.download("/invoice/" + invoiceId + "/pdf");
} catch (RuntimeException e) {
if (e.getCause() instanceof HttpResponseException) {
HttpResponseException responseException = (HttpResponseException) e.getCause();
if (responseException.getStatusCode() == 409) {
throw new InsufficientCreditsAmountException();
}
}
throw e;
}
}
@Override
public void deleteInvoice(String invoiceId) {
httpClient.delete("/invoice/"+invoiceId);
}
@Override
public boolean sendInvoice(String invoiceId, String email, String message) {
try {
String encodedMessage = URLEncoder.encode(message, "UTF-8");
String json = "{\"recipient\":\""+email+"\", \"message\":\""+encodedMessage+"\"}";
InvoiceResponse createdInvoice = httpClient.post("/invoice/"+invoiceId+"/pdf/send", json.getBytes(Charset.forName("UTF-8")), "application/json", InvoiceResponse.class);
return createdInvoice != null && createdInvoice.getInvoiceId() != null;
} catch (RuntimeException e) {
if (e.getCause() instanceof HttpResponseException) {
HttpResponseException responseException = (HttpResponseException) e.getCause();
if (responseException.getStatusCode() == 409) {
throw new InsufficientCreditsAmountException();
}
}
throw e;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
@Override
public boolean sendInvoice(String invoiceId, String email) {
return sendInvoice(invoiceId, email, "");
}
@Override
public InvoiceResponse uploadInvoice(InputStream pdf, InvoiceDocument.Type type) {
Map<String, InputStream> files = Maps.newHashMap();
files.put("pdf", pdf);
return httpClient.upload(String.format("/invoice/pdf?type=%s", type.toString()), files, InvoiceResponse.class);
}
@Override
public StatusResponse updateStatus(String invoiceId, Status status) {
try {
String json = String.format("{\"status\": \"%s\"}", status.toString());
String url = String.format("/invoice/%s/status", invoiceId);
log.debug("Updating status of the invoice with id {}: {}", invoiceId, json);
StatusResponse response = httpClient.post(url, json.getBytes("UTF-8"), "application/json", StatusResponse.class);
log.debug("Change status response = {}", response);
return response;
} catch (Exception e) {
log.warn("Caught exception {}: {}", e.getClass().getSimpleName(), e.getMessage());
throw new RuntimeException(e);
}
}
}