From 6cd3d5d25815908629c817bb611bcde3e3f0e686 Mon Sep 17 00:00:00 2001 From: Ralph Soika Date: Fri, 9 May 2025 12:24:15 +0200 Subject: [PATCH] zoho currency lookup --- .../zoho/ZohoAPIService.java | 177 +++++++----------- .../zoho/ZohoController.java | 4 +- .../zoho/ZohoExportAdapter.java | 8 +- .../alexanderlogistics/zoho/dto/ZohoBill.java | 11 ++ .../zoho/dto/ZohoExpense.java | 99 ---------- .../zoho/dto/ZohoExpenseCreateResponse.java | 39 ---- .../zoho/dto/ZohoExpenseItem.java | 16 -- .../zoho/dto/ZohoInvoice.java | 11 ++ .../src/main/webapp/pages/admin/zoho.xhtml | 2 +- 9 files changed, 98 insertions(+), 269 deletions(-) delete mode 100644 office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoExpense.java delete mode 100644 office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoExpenseCreateResponse.java delete mode 100644 office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoExpenseItem.java diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoAPIService.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoAPIService.java index 9da0de6..eea709b 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoAPIService.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoAPIService.java @@ -14,6 +14,8 @@ import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import org.imixs.workflow.FileData; @@ -27,9 +29,6 @@ import com.alexanderlogistics.zoho.dto.ZohoBillItem; import com.alexanderlogistics.zoho.dto.ZohoContact; import com.alexanderlogistics.zoho.dto.ZohoContactCreateResponse; import com.alexanderlogistics.zoho.dto.ZohoContactFindResponse; -import com.alexanderlogistics.zoho.dto.ZohoExpense; -import com.alexanderlogistics.zoho.dto.ZohoExpenseCreateResponse; -import com.alexanderlogistics.zoho.dto.ZohoExpenseItem; import com.alexanderlogistics.zoho.dto.ZohoInvoice; import com.alexanderlogistics.zoho.dto.ZohoInvoiceCreateResponse; import com.alexanderlogistics.zoho.dto.ZohoInvoiceItem; @@ -132,12 +131,12 @@ public class ZohoAPIService { * @param invoice * @throws PluginException */ - public ZohoInvoice exportInvoice(ItemCollection invoice, String contactID, String accessToken) + public ZohoInvoice exportInvoice(ItemCollection invoice, String contactID, String currencyID, String accessToken) throws PluginException { logger.info("├── Zoho Export Invoice " + invoice.getItemValueString("invoice.number") + "..."); // Konvertiere ItemCollection zu ZohoInvoiceDTO - ZohoInvoice zohoInvoice = convertToZohoInvoice(invoice, contactID); + ZohoInvoice zohoInvoice = convertToZohoInvoice(invoice, contactID, currencyID); try { String requestBody = jsonb.toJson(zohoInvoice); @@ -203,82 +202,12 @@ public class ZohoAPIService { * @param invoice * @throws PluginException */ - public ZohoExpense exportExpense(ItemCollection invoice, String contactID, String accessToken) - throws PluginException { - logger.info("├── Zoho Export Expense " + invoice.getItemValueString("invoice.number") + "..."); - - // Konvertiere ItemCollection zu ZohoInvoiceDTO - ZohoExpense zohoExpense = convertToZohoExpense(invoice, contactID); - - try { - String requestBody = jsonb.toJson(zohoExpense); - - // Print JSON to console for verification - logger.fine("├── Zoho Expense JSON Request..."); - logger.fine("│ ├── " + requestBody); - - // https://www.zohoapis.com/books/v3/expenses?organization_id=10234695' - String uri = zohoOAuthManager.getBaseURI() + "expenses?organization_id=" - + zohoOAuthManager.getOrganization(); - logger.fine("│ ├── uri= " + uri); - logger.fine("│ ├── accessToken=" + accessToken); - HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri)) - .header("Authorization", "Zoho-oauthtoken " + accessToken) - .header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(requestBody)) - .build(); - - HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); - - // Print response details to console - logger.fine("├── Zoho Response:"); - logger.fine("│ ├── Status Code: " + response.statusCode()); - - if (response.statusCode() >= 300) { - throw new PluginException(this.getClass().getName(), "Zoho API error", - "Failed to create expense. Status code: " + response.statusCode() + ", Response: " - + response.body()); - } - - // Erfolgreiche Erstellung - String bodyContent = response.body(); - logger.fine("│ ├── Response Body: " + bodyContent); - - System.out.print(bodyContent); - ZohoExpenseCreateResponse createResponse = jsonb.fromJson(bodyContent, ZohoExpenseCreateResponse.class); - - if (createResponse != null) { - logger.info("│ ├── OK - customerID=" + createResponse.getExpense().getCustomerId()); - logger.info("│ ├── OK - expenseID=" + createResponse.getExpense().getExpenseId()); - zohoExpense = createResponse.getExpense(); - - // now mark the invoice as send - - logger.info("│ ├── Invoice Export successful."); - return zohoExpense; - } - - } catch (IOException | InterruptedException e) { - throw new PluginException(this.getClass().getName(), "Zoho API error", - "Failed to export invoice to Zoho: " + e.getMessage(), e); - } - return null; - - } - - /** - * Exports an Eingangsrechnung document - * - * @see https://www.zoho.com/books/api/v3/expenses/#create-an-expense - * - * @param invoice - * @throws PluginException - */ - public ZohoBill exportBill(ItemCollection invoice, String contactID, String accountID, String accessToken) - throws PluginException { + public ZohoBill exportBill(ItemCollection invoice, String contactID, String currencyID, String accountID, + String accessToken) throws PluginException { logger.info("├── Zoho Export Bill " + invoice.getItemValueString("invoice.number") + "..."); // Konvertiere ItemCollection zu ZohoInvoiceDTO - ZohoBill zohoBill = convertToZohoBill(invoice, contactID, accountID); + ZohoBill zohoBill = convertToZohoBill(invoice, contactID, currencyID, accountID); try { String requestBody = jsonb.toJson(zohoBill); @@ -401,7 +330,8 @@ public class ZohoAPIService { } - private ZohoInvoice convertToZohoInvoice(ItemCollection invoice, String contactID) throws PluginException { + private ZohoInvoice convertToZohoInvoice(ItemCollection invoice, String contactID, String currencyID) + throws PluginException { ZohoInvoice zohoInvoice = new ZohoInvoice(); // Basisinformationen @@ -414,8 +344,10 @@ public class ZohoAPIService { LocalDate.ofInstant(invoice.getItemValueDate("invoice.duedate").toInstant(), ZoneId.systemDefault())); zohoInvoice.setTotal(invoice.getItemValueDouble("invoice.total")); - // Kunden-ID (muss angepasst werden je nachdem wie du sie speicherst) zohoInvoice.setCustomerId(contactID); + if (currencyID != null && !currencyID.isEmpty()) { + zohoInvoice.setCurrencyId(currencyID); + } List positionen = InvoiceUtil.explodeChildList(invoice); List lineItems = positionen.stream().map(item -> { @@ -432,35 +364,7 @@ public class ZohoAPIService { return zohoInvoice; } - private ZohoExpense convertToZohoExpense(ItemCollection invoice, String contactID) throws PluginException { - - ZohoExpense zohoExpense = new ZohoExpense(); - // Basisinformationen - - zohoExpense.setInvoiceNumber(invoice.getItemValueString("invoice.number")); - zohoExpense.setDate( - LocalDate.ofInstant(invoice.getItemValueDate("invoice.date").toInstant(), ZoneId.systemDefault())); - - zohoExpense.setAmount(invoice.getItemValueDouble("invoice.total")); - // Kunden-ID (muss angepasst werden je nachdem wie du sie speicherst) - zohoExpense.setCustomerId(contactID); - zohoExpense.setPaid_through_account_id("1700"); - List positionen = InvoiceUtil.explodeChildList(invoice); - // {amount=[11825.00], total=[11825.00], numpos=[1], name=[AB-DEFGHI-1234-567], - // tax=[0], category=[STORAGE], invoice.period=[]} - List lineItems = positionen.stream().map(item -> { - ItemCollection itemCol = (ItemCollection) item; - ZohoExpenseItem lineItem = new ZohoExpenseItem(); - lineItem.setDescription(itemCol.getItemValueString("name")); - - return lineItem; - }).collect(Collectors.toList()); - - zohoExpense.setLineItems(lineItems); - return zohoExpense; - } - - private ZohoBill convertToZohoBill(ItemCollection invoice, String contactID, String accountID) + private ZohoBill convertToZohoBill(ItemCollection invoice, String contactID, String currencyID, String accountID) throws PluginException { ZohoBill zohoBill = new ZohoBill(); @@ -473,6 +377,9 @@ public class ZohoAPIService { zohoBill.setAmount(invoice.getItemValueDouble("invoice.total")); // Kunden-ID (muss angepasst werden je nachdem wie du sie speicherst) zohoBill.setVendorId(contactID); + if (currencyID != null && !currencyID.isEmpty()) { + zohoBill.setCurrencyId(currencyID); + } // zohoBill.setPaid_through_account_id("1700"); List positionen = InvoiceUtil.explodeChildList(invoice); // {amount=[11825.00], total=[11825.00], numpos=[1], name=[AB-DEFGHI-1234-567], @@ -603,4 +510,56 @@ public class ZohoAPIService { } } + /** + * Sucht eine currency ID Wegen eifnachheit parsen wir hier direkt die JSON + * struktur + * + * @param currency + * @param accessToken + * @return + * @throws PluginException + */ + public String lookupCurrency(String currency, String accessToken) throws PluginException { + + // Print JSON to console for verification + logger.info("├── Zoho lookup currency '" + currency + "'..."); + try { + // https://www.zohoapis.com/books/v3/contacts?organization_id=10234695&company_name=xxx' + String uri = zohoOAuthManager.getBaseURI() + "settings/currencies?organization_id=" + + zohoOAuthManager.getOrganization(); + logger.fine("│ ├── uri= " + uri); + logger.fine("│ ├── accessToken=" + accessToken); + HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri)) + .header("Authorization", "Zoho-oauthtoken " + accessToken) + .header("Content-Type", "application/json").GET().build(); + + HttpResponse response; + + response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + + // Print response details to console + logger.fine("├── Zoho Response:"); + logger.fine("│ ├── Status Code: " + response.statusCode()); + logger.fine("│ ├── Response Body: " + response.body()); + if (response.statusCode() >= 300) { + throw new PluginException(this.getClass().getName(), "Zoho API error", + "Failed to find currencies - Status code: " + response.statusCode() + ", Response: " + + response.body()); + } + + String json = response.body(); + String pattern = "\"currency_code\":\"" + Pattern.quote(currency) + "\".*?\"currency_id\":\"(\\d+)\""; + Matcher matcher = Pattern.compile(pattern).matcher(json); + + String result = matcher.find() ? matcher.group(1) : null; + logger.info("│ ├── Currency ID=" + result); + return result; + + } catch (IOException | InterruptedException e) { + throw new PluginException(this.getClass().getName(), "Zoho API error", + "Failed to find Contacts: " + e.getMessage()); + } + + } + } diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoController.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoController.java index 1e61a5f..fa0660a 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoController.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoController.java @@ -29,7 +29,7 @@ import java.util.logging.Logger; import org.imixs.workflow.exceptions.PluginException; import org.imixs.workflow.office.config.ConfigController; -import jakarta.enterprise.context.ConversationScoped; +import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Inject; import jakarta.inject.Named; @@ -43,7 +43,7 @@ import jakarta.inject.Named; */ @Named("zohoController") // @ApplicationScoped -@ConversationScoped +@SessionScoped public class ZohoController extends ConfigController { public static final String ZOHO_CONFIGURATION = "ZOHO_CONFIGURATION"; diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoExportAdapter.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoExportAdapter.java index 416ccdc..478cf6c 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoExportAdapter.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/ZohoExportAdapter.java @@ -86,8 +86,8 @@ public class ZohoExportAdapter implements SignalAdapter { // find companyID String contactID = zohoAPIService.lookupContact(document.getItemValueString("dbtr.name"), "customer", accessToken); - - ZohoInvoice zohoInvoice = zohoAPIService.exportInvoice(document, contactID, accessToken); + String currencyID = zohoAPIService.lookupCurrency(document.getItemValueString("invoice.currency"), accessToken); + ZohoInvoice zohoInvoice = zohoAPIService.exportInvoice(document, contactID, currencyID, accessToken); // Attache Files.... List files = null; @@ -117,9 +117,10 @@ public class ZohoExportAdapter implements SignalAdapter { String contactID = zohoAPIService.lookupContact(document.getItemValueString("cdtr.name"), "vendor", accessToken); + String currencyID = zohoAPIService.lookupCurrency(document.getItemValueString("invoice.currency"), accessToken); String accountID = zohoOAuthManager.getAccountId(); - ZohoBill zohoBill = zohoAPIService.exportBill(document, contactID, accountID, accessToken); + ZohoBill zohoBill = zohoAPIService.exportBill(document, contactID, currencyID, accountID, accessToken); // Attache Files.... List files = null; @@ -135,4 +136,5 @@ public class ZohoExportAdapter implements SignalAdapter { } } } + } \ No newline at end of file diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoBill.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoBill.java index 5720977..58a6f44 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoBill.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoBill.java @@ -14,6 +14,9 @@ public class ZohoBill { @JsonbProperty("vendor_id") private String vendorId; + @JsonbProperty("currency_id") + private String currencyId; + @JsonbDateFormat("yyyy-MM-dd") private LocalDate date; @@ -87,4 +90,12 @@ public class ZohoBill { this.amount = amount; } + public String getCurrencyId() { + return currencyId; + } + + public void setCurrencyId(String currencyId) { + this.currencyId = currencyId; + } + } diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoExpense.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoExpense.java deleted file mode 100644 index 3103c56..0000000 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoExpense.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.alexanderlogistics.zoho.dto; - -import java.time.LocalDate; -import java.util.List; - -import jakarta.json.bind.annotation.JsonbDateFormat; -import jakarta.json.bind.annotation.JsonbProperty; - -public class ZohoExpense { - - @JsonbProperty("expense_id") - private String expenseId; - - @JsonbProperty("account_id") - private String accountId; - - @JsonbProperty("paid_through_account_id") - private String paid_through_account_id; - - @JsonbProperty("customer_id") - private String customerId; - - @JsonbDateFormat("yyyy-MM-dd") - private LocalDate date; - - @JsonbProperty("reference_number") - private String invoiceNumber; - - @JsonbProperty("line_items") - private List lineItems; - - private double amount; - - // Getter und Setter - - public String getExpenseId() { - return expenseId; - } - - public void setExpenseId(String expenseId) { - this.expenseId = expenseId; - } - - public String getAccountId() { - return accountId; - } - - public void setAccountId(String accountId) { - this.accountId = accountId; - } - - public String getCustomerId() { - return customerId; - } - - public void setCustomerId(String customerId) { - this.customerId = customerId; - } - - public LocalDate getDate() { - return date; - } - - public void setDate(LocalDate date) { - this.date = date; - } - - public String getInvoiceNumber() { - return invoiceNumber; - } - - public void setInvoiceNumber(String invoiceNumber) { - this.invoiceNumber = invoiceNumber; - } - - public List getLineItems() { - return lineItems; - } - - public void setLineItems(List lineItems) { - this.lineItems = lineItems; - } - - public double getAmount() { - return amount; - } - - public void setAmount(double amount) { - this.amount = amount; - } - - public String getPaid_through_account_id() { - return paid_through_account_id; - } - - public void setPaid_through_account_id(String paid_through_account_id) { - this.paid_through_account_id = paid_through_account_id; - } -} diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoExpenseCreateResponse.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoExpenseCreateResponse.java deleted file mode 100644 index 53e90c9..0000000 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoExpenseCreateResponse.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.alexanderlogistics.zoho.dto; - -import jakarta.json.bind.annotation.JsonbProperty; - -public class ZohoExpenseCreateResponse { - @JsonbProperty("code") - private int code; - - @JsonbProperty("message") - private String message; - - @JsonbProperty("expense") - private ZohoExpense expense; - - // Getter und Setter - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public ZohoExpense getExpense() { - return expense; - } - - public void setExpense(ZohoExpense expense) { - this.expense = expense; - } -} diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoExpenseItem.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoExpenseItem.java deleted file mode 100644 index 7837b3e..0000000 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoExpenseItem.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.alexanderlogistics.zoho.dto; - -public class ZohoExpenseItem { - private String description; - - // Getter und Setter - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - -} diff --git a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoInvoice.java b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoInvoice.java index 22cf91f..8d64281 100644 --- a/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoInvoice.java +++ b/office-alexander-logistics-app/src/main/java/com/alexanderlogistics/zoho/dto/ZohoInvoice.java @@ -14,6 +14,9 @@ public class ZohoInvoice { @JsonbProperty("customer_id") private String customerId; + @JsonbProperty("currency_id") + private String currencyId; + @JsonbDateFormat("yyyy-MM-dd") private LocalDate date; @@ -86,4 +89,12 @@ public class ZohoInvoice { public void setTotal(double total) { this.total = total; } + + public String getCurrencyId() { + return currencyId; + } + + public void setCurrencyId(String currencyId) { + this.currencyId = currencyId; + } } diff --git a/office-alexander-logistics-app/src/main/webapp/pages/admin/zoho.xhtml b/office-alexander-logistics-app/src/main/webapp/pages/admin/zoho.xhtml index cde0c46..8e69122 100644 --- a/office-alexander-logistics-app/src/main/webapp/pages/admin/zoho.xhtml +++ b/office-alexander-logistics-app/src/main/webapp/pages/admin/zoho.xhtml @@ -137,7 +137,7 @@ Generieren Sie einen neuen Access Code
Scope: - ZohoBooks.contacts.ALL,ZohoBooks.invoices.ALL,ZohoBooks.bills.ALL + ZohoBooks.contacts.ALL,ZohoBooks.invoices.ALL,ZohoBooks.bills.ALL,ZohoBooks.settings.READ
  • Code über den Button "Create" anfordern und in das Feld "Access Code"