001package io.konik.sdk.invoice; 002 003import com.google.api.client.http.HttpResponseException; 004import com.google.api.client.util.Maps; 005import io.konik.InvoiceTransformer; 006import io.konik.sdk.http.InsufficientCreditsAmountException; 007import io.konik.sdk.http.ZinvoiceHttpClient; 008import io.konik.zugferd.Invoice; 009import org.slf4j.Logger; 010import org.slf4j.LoggerFactory; 011 012import java.io.InputStream; 013import java.io.UnsupportedEncodingException; 014import java.net.URLEncoder; 015import java.nio.charset.Charset; 016import java.util.Map; 017 018 019public class RestInvoiceApi implements InvoiceApi { 020 021 private static final Logger log = LoggerFactory.getLogger(RestInvoiceApi.class); 022 023 private final ZinvoiceHttpClient httpClient; 024 025 private final InvoiceTransformer invoiceTransformer; 026 027 public RestInvoiceApi(ZinvoiceHttpClient zinvoiceHttpClient) { 028 this.httpClient = zinvoiceHttpClient; 029 this.invoiceTransformer = new InvoiceTransformer(); 030 } 031 032 public RestInvoiceApi(ZinvoiceHttpClient zinvoiceHttpClient, InvoiceTransformer invoiceTransformer) { 033 this.httpClient = zinvoiceHttpClient; 034 this.invoiceTransformer = invoiceTransformer; 035 } 036 037 @Override 038 public InvoiceDocument getInvoice(String id) { 039 InvoiceDocument.Response response = httpClient.get("/invoice/" + id, InvoiceDocument.Response.class); 040 if (response != null) { 041 return response.getDocument(); 042 } 043 return null; 044 } 045 046 @Override 047 public InvoiceResponse createInvoice(Invoice invoice) { 048 byte[] invoiceXml = invoiceTransformer.fromModel(invoice); 049 return httpClient.post("/invoice", invoiceXml, "application/xml", InvoiceResponse.class); 050 } 051 052 @Override 053 public InvoiceResponse createDraftInvoice(Invoice invoice) { 054 byte[] invoiceXml = invoiceTransformer.fromModel(invoice); 055 return httpClient.post("/invoice/draft", invoiceXml, "application/xml", InvoiceResponse.class); 056 } 057 058 @Override 059 public InvoiceResponse updateInvoice(String invoiceId, Invoice invoice) { 060 byte[] invoiceXml = invoiceTransformer.fromModel(invoice); 061 return httpClient.put("/invoice/" + invoiceId, invoiceXml, "application/xml", InvoiceResponse.class); 062 } 063 064 @Override 065 public InvoiceResponse updateDraftInvoice(String invoiceId, Invoice invoice) { 066 byte[] invoiceXml = invoiceTransformer.fromModel(invoice); 067 return httpClient.put("/invoice/draft/" + invoiceId, invoiceXml, "application/xml", InvoiceResponse.class); 068 } 069 070 @Override 071 public InputStream downloadInvoiceAsPDF(String invoiceId) { 072 try { 073 return httpClient.download("/invoice/" + invoiceId + "/pdf"); 074 } catch (RuntimeException e) { 075 if (e.getCause() instanceof HttpResponseException) { 076 HttpResponseException responseException = (HttpResponseException) e.getCause(); 077 if (responseException.getStatusCode() == 409) { 078 throw new InsufficientCreditsAmountException(); 079 } 080 } 081 throw e; 082 } 083 } 084 085 @Override 086 public void deleteInvoice(String invoiceId) { 087 httpClient.delete("/invoice/"+invoiceId); 088 } 089 090 @Override 091 public boolean sendInvoice(String invoiceId, String email, String message) { 092 try { 093 String encodedMessage = URLEncoder.encode(message, "UTF-8"); 094 String json = "{\"recipient\":\""+email+"\", \"message\":\""+encodedMessage+"\"}"; 095 096 InvoiceResponse createdInvoice = httpClient.post("/invoice/"+invoiceId+"/pdf/send", json.getBytes(Charset.forName("UTF-8")), "application/json", InvoiceResponse.class); 097 098 return createdInvoice != null && createdInvoice.getInvoiceId() != null; 099 } catch (RuntimeException e) { 100 if (e.getCause() instanceof HttpResponseException) { 101 HttpResponseException responseException = (HttpResponseException) e.getCause(); 102 if (responseException.getStatusCode() == 409) { 103 throw new InsufficientCreditsAmountException(); 104 } 105 } 106 throw e; 107 } catch (UnsupportedEncodingException e) { 108 throw new RuntimeException(e); 109 } 110 } 111 112 @Override 113 public boolean sendInvoice(String invoiceId, String email) { 114 return sendInvoice(invoiceId, email, ""); 115 } 116 117 @Override 118 public InvoiceResponse uploadInvoice(InputStream pdf, InvoiceDocument.Type type) { 119 Map<String, InputStream> files = Maps.newHashMap(); 120 files.put("pdf", pdf); 121 return httpClient.upload(String.format("/invoice/pdf?type=%s", type.toString()), files, InvoiceResponse.class); 122 } 123 124 @Override 125 public StatusResponse updateStatus(String invoiceId, Status status) { 126 try { 127 String json = String.format("{\"status\": \"%s\"}", status.toString()); 128 String url = String.format("/invoice/%s/status", invoiceId); 129 130 log.debug("Updating status of the invoice with id {}: {}", invoiceId, json); 131 132 StatusResponse response = httpClient.post(url, json.getBytes("UTF-8"), "application/json", StatusResponse.class); 133 134 log.debug("Change status response = {}", response); 135 136 return response; 137 } catch (Exception e) { 138 log.warn("Caught exception {}: {}", e.getClass().getSimpleName(), e.getMessage()); 139 throw new RuntimeException(e); 140 } 141 } 142}