zoho credit note interface
This commit is contained in:
parent
ffb0942737
commit
e350ece8f3
6 changed files with 2926 additions and 3 deletions
|
|
@ -20,6 +20,7 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.imixs.workflow.FileData;
|
import org.imixs.workflow.FileData;
|
||||||
import org.imixs.workflow.ItemCollection;
|
import org.imixs.workflow.ItemCollection;
|
||||||
|
import org.imixs.workflow.engine.DocumentService;
|
||||||
import org.imixs.workflow.exceptions.PluginException;
|
import org.imixs.workflow.exceptions.PluginException;
|
||||||
|
|
||||||
import com.alexanderlogistics.InvoiceUtil;
|
import com.alexanderlogistics.InvoiceUtil;
|
||||||
|
|
@ -33,6 +34,7 @@ import com.alexanderlogistics.zoho.dto.ZohoCreditnote;
|
||||||
import com.alexanderlogistics.zoho.dto.ZohoCreditnoteCreateResponse;
|
import com.alexanderlogistics.zoho.dto.ZohoCreditnoteCreateResponse;
|
||||||
import com.alexanderlogistics.zoho.dto.ZohoInvoice;
|
import com.alexanderlogistics.zoho.dto.ZohoInvoice;
|
||||||
import com.alexanderlogistics.zoho.dto.ZohoInvoiceCreateResponse;
|
import com.alexanderlogistics.zoho.dto.ZohoInvoiceCreateResponse;
|
||||||
|
import com.alexanderlogistics.zoho.dto.ZohoInvoiceFindResponse;
|
||||||
import com.alexanderlogistics.zoho.dto.ZohoInvoiceItem;
|
import com.alexanderlogistics.zoho.dto.ZohoInvoiceItem;
|
||||||
import com.alexanderlogistics.zoho.dto.ZohoTax;
|
import com.alexanderlogistics.zoho.dto.ZohoTax;
|
||||||
import com.alexanderlogistics.zoho.dto.ZohoTaxListResponse;
|
import com.alexanderlogistics.zoho.dto.ZohoTaxListResponse;
|
||||||
|
|
@ -75,6 +77,9 @@ public class ZohoAPIService {
|
||||||
@Inject
|
@Inject
|
||||||
ZohoOAuthManager zohoOAuthManager;
|
ZohoOAuthManager zohoOAuthManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
DocumentService documentService;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
void init() {
|
void init() {
|
||||||
this.httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
|
this.httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
|
||||||
|
|
@ -144,6 +149,61 @@ public class ZohoAPIService {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This finder method returns the invoice ID to a given invoice.number
|
||||||
|
* The method returns null if no invoice with this nubmer exists
|
||||||
|
*
|
||||||
|
* @param companyName
|
||||||
|
* @param accessToken
|
||||||
|
* @return
|
||||||
|
* @throws PluginException
|
||||||
|
*/
|
||||||
|
public ZohoInvoice findInvoiceIDByInvoiceNumber(String invoiceNumber, String accessToken)
|
||||||
|
throws PluginException {
|
||||||
|
|
||||||
|
// Print JSON to console for verification
|
||||||
|
logger.info("├── Zoho lookup invoice '" + invoiceNumber + "'...");
|
||||||
|
try {
|
||||||
|
// https://www.zohoapis.com/books/v3/contacts?organization_id=10234695&company_name=xxx'
|
||||||
|
String uri = zohoOAuthManager.getBaseURI() + "invoices?organization_id="
|
||||||
|
+ zohoOAuthManager.getOrganization() + "&invoice_number="
|
||||||
|
+ URLEncoder.encode(invoiceNumber, StandardCharsets.UTF_8);
|
||||||
|
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<String> 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 invoice - Status code: " + response.statusCode() + ", Response: "
|
||||||
|
+ response.body());
|
||||||
|
}
|
||||||
|
|
||||||
|
ZohoInvoiceFindResponse invoicesResponse = jsonb.fromJson(response.body(), ZohoInvoiceFindResponse.class);
|
||||||
|
|
||||||
|
if (invoicesResponse != null && invoicesResponse.getInvoices() != null
|
||||||
|
&& invoicesResponse.getInvoices().size() > 0) {
|
||||||
|
// return 1 entry
|
||||||
|
ZohoInvoice invoice = invoicesResponse.getInvoices().get(0);
|
||||||
|
return invoice;
|
||||||
|
}
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
||||||
|
"Failed to find Contacts: " + e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exports an invocie document
|
* Exports an invocie document
|
||||||
*
|
*
|
||||||
|
|
@ -231,8 +291,19 @@ public class ZohoAPIService {
|
||||||
|
|
||||||
String currencyID = lookupCurrency(invoice.getItemValueString("invoice.currency"), accessToken);
|
String currencyID = lookupCurrency(invoice.getItemValueString("invoice.currency"), accessToken);
|
||||||
|
|
||||||
|
// Lookup die Invoice ID in zOho
|
||||||
|
|
||||||
|
ZohoInvoice invoiceZoho = null;
|
||||||
|
String invoiceRefID = invoice.getItemValueString("invoice.ref");
|
||||||
|
ItemCollection invoiceRef = documentService.load(invoiceRefID);
|
||||||
|
if (invoiceRef != null) {
|
||||||
|
invoiceZoho = findInvoiceIDByInvoiceNumber(invoiceRef.getItemValueString("invoice.number"),
|
||||||
|
accessToken);
|
||||||
|
logger.info("├── Zoho fond invoice zoho ref: " + invoiceZoho.getInvoiceId());
|
||||||
|
}
|
||||||
|
|
||||||
// Konvertiere ItemCollection zu ZohoInvoiceDTO
|
// Konvertiere ItemCollection zu ZohoInvoiceDTO
|
||||||
ZohoCreditnote zohoCreditnote = convertToZohoCreditnote(invoice, contactID, currencyID);
|
ZohoCreditnote zohoCreditnote = convertToZohoCreditnote(invoice, contactID, currencyID, invoiceZoho);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String requestBody = jsonb.toJson(zohoCreditnote);
|
String requestBody = jsonb.toJson(zohoCreditnote);
|
||||||
|
|
@ -244,6 +315,10 @@ public class ZohoAPIService {
|
||||||
// https://www.zohoapis.com/books/v3/creditnotes?organization_id=10234695'
|
// https://www.zohoapis.com/books/v3/creditnotes?organization_id=10234695'
|
||||||
String uri = zohoOAuthManager.getBaseURI() + "creditnotes?organization_id="
|
String uri = zohoOAuthManager.getBaseURI() + "creditnotes?organization_id="
|
||||||
+ zohoOAuthManager.getOrganization();
|
+ zohoOAuthManager.getOrganization();
|
||||||
|
|
||||||
|
if (zohoCreditnote != null) {
|
||||||
|
uri = uri + "&invoice_id=" + invoiceZoho.getInvoiceId();
|
||||||
|
}
|
||||||
logger.fine("│ ├── uri= " + uri);
|
logger.fine("│ ├── uri= " + uri);
|
||||||
logger.fine("│ ├── accessToken=" + accessToken);
|
logger.fine("│ ├── accessToken=" + accessToken);
|
||||||
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri))
|
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri))
|
||||||
|
|
@ -565,14 +640,15 @@ public class ZohoAPIService {
|
||||||
* @return
|
* @return
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
private ZohoCreditnote convertToZohoCreditnote(ItemCollection invoice, String contactID, String currencyID)
|
private ZohoCreditnote convertToZohoCreditnote(ItemCollection invoice, String contactID, String currencyID,
|
||||||
|
ZohoInvoice zohoInvoice)
|
||||||
throws PluginException {
|
throws PluginException {
|
||||||
|
|
||||||
ZohoCreditnote zohoCreditnote = new ZohoCreditnote();
|
ZohoCreditnote zohoCreditnote = new ZohoCreditnote();
|
||||||
// Basisinformationen
|
// Basisinformationen
|
||||||
|
|
||||||
zohoCreditnote.setCreditNoteNumber(invoice.getItemValueString("invoice.number"));
|
zohoCreditnote.setCreditNoteNumber(invoice.getItemValueString("invoice.number"));
|
||||||
zohoCreditnote.setReferenceNumber(invoice.getItemValueString("invoice.number"));
|
|
||||||
zohoCreditnote.setDate(
|
zohoCreditnote.setDate(
|
||||||
LocalDate.ofInstant(invoice.getItemValueDate("invoice.date").toInstant(), ZoneId.systemDefault()));
|
LocalDate.ofInstant(invoice.getItemValueDate("invoice.date").toInstant(), ZoneId.systemDefault()));
|
||||||
// zohoCreditnote.setDueDate(
|
// zohoCreditnote.setDueDate(
|
||||||
|
|
@ -586,6 +662,19 @@ public class ZohoAPIService {
|
||||||
zohoCreditnote.setCurrencyId(currencyID);
|
zohoCreditnote.setCurrencyId(currencyID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// do we have an invoice?
|
||||||
|
if (zohoInvoice != null) {
|
||||||
|
String placeOfSupply = zohoInvoice.getPlaceOfSupply();
|
||||||
|
if (placeOfSupply == null) {
|
||||||
|
placeOfSupply = "DU";
|
||||||
|
}
|
||||||
|
logger.info("│ ├── set place of supply=" + placeOfSupply);
|
||||||
|
zohoCreditnote.setPlaceOfSupply(placeOfSupply);
|
||||||
|
// logger.info("....assign invoice");
|
||||||
|
// ZohoCreditnoteInvoiceItem zcii = new ZohoCreditnoteInvoiceItem(zohoInvoice);
|
||||||
|
// zohoCreditnote.setInvoices(java.util.Arrays.asList(zcii));
|
||||||
|
}
|
||||||
|
|
||||||
// convert total by rate - negativer betrag!
|
// convert total by rate - negativer betrag!
|
||||||
zohoCreditnote.setTotal(Math.abs(invoice.getItemValueDouble("invoice.total")));
|
zohoCreditnote.setTotal(Math.abs(invoice.getItemValueDouble("invoice.total")));
|
||||||
// set exchange Rate
|
// set exchange Rate
|
||||||
|
|
@ -606,6 +695,30 @@ public class ZohoAPIService {
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
zohoCreditnote.setLineItems(lineItems);
|
zohoCreditnote.setLineItems(lineItems);
|
||||||
|
|
||||||
|
// add line items...
|
||||||
|
// changes 24.06.2025 - Keine einzelPositionen mehr an Zoho senden, da diese von
|
||||||
|
// Cargosoft unbrauchbar sind.
|
||||||
|
// List<ItemCollection> positionen = InvoiceUtil.explodeChildList(invoice);
|
||||||
|
// List<ZohoInvoiceItem> lineItems = positionen.stream().map(item -> {
|
||||||
|
// ItemCollection itemCol = (ItemCollection) item;
|
||||||
|
// ZohoInvoiceItem lineItem = new ZohoInvoiceItem();
|
||||||
|
// lineItem.setName(itemCol.getItemValueString("datev.text"));
|
||||||
|
// lineItem.setDescription(itemCol.getItemValueString("billingtext"));
|
||||||
|
// lineItem.setRate(itemCol.getItemValueDouble("datev.umsatz"));
|
||||||
|
// lineItem.setQuantity(1);
|
||||||
|
// return lineItem;
|
||||||
|
// }).collect(Collectors.toList());
|
||||||
|
// List<ZohoInvoiceItem> lineItems = new ArrayList<>();
|
||||||
|
|
||||||
|
// create only one single item!
|
||||||
|
ZohoInvoiceItem lineItem = new ZohoInvoiceItem();
|
||||||
|
lineItem.setName(invoice.getItemValueString("invoice.text"));
|
||||||
|
lineItem.setDescription("");
|
||||||
|
lineItem.setRate(invoice.getItemValueDouble("invoice.total"));
|
||||||
|
lineItem.setQuantity(1);
|
||||||
|
lineItems.add(lineItem);
|
||||||
|
|
||||||
return zohoCreditnote;
|
return zohoCreditnote;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,18 @@ public class ZohoCreditnote {
|
||||||
@JsonbProperty("reference_number")
|
@JsonbProperty("reference_number")
|
||||||
private String referenceNumber;
|
private String referenceNumber;
|
||||||
|
|
||||||
|
@JsonbProperty("place_of_supply")
|
||||||
|
private String placeOfSupply;
|
||||||
|
|
||||||
@JsonbProperty("line_items")
|
@JsonbProperty("line_items")
|
||||||
private List<ZohoInvoiceItem> lineItems;
|
private List<ZohoInvoiceItem> lineItems;
|
||||||
|
|
||||||
@JsonbProperty("exchange_rate")
|
@JsonbProperty("exchange_rate")
|
||||||
private double exchangeRate;
|
private double exchangeRate;
|
||||||
|
|
||||||
|
@JsonbProperty("invoices")
|
||||||
|
private List<ZohoCreditnoteInvoiceItem> invoices;
|
||||||
|
|
||||||
private double total;
|
private double total;
|
||||||
|
|
||||||
// Getter und Setter
|
// Getter und Setter
|
||||||
|
|
@ -106,4 +112,20 @@ public class ZohoCreditnote {
|
||||||
public void setReferenceNumber(String referenceNumber) {
|
public void setReferenceNumber(String referenceNumber) {
|
||||||
this.referenceNumber = referenceNumber;
|
this.referenceNumber = referenceNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<ZohoCreditnoteInvoiceItem> getInvoices() {
|
||||||
|
return invoices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInvoices(List<ZohoCreditnoteInvoiceItem> invoices) {
|
||||||
|
this.invoices = invoices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlaceOfSupply() {
|
||||||
|
return placeOfSupply;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlaceOfSupply(String placeOfSupply) {
|
||||||
|
this.placeOfSupply = placeOfSupply;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.alexanderlogistics.zoho.dto;
|
||||||
|
|
||||||
|
import jakarta.json.bind.annotation.JsonbProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Referenz von Invoices in einer CreditNote
|
||||||
|
*/
|
||||||
|
public class ZohoCreditnoteInvoiceItem {
|
||||||
|
|
||||||
|
@JsonbProperty("invoice_id")
|
||||||
|
private String invoiceId;
|
||||||
|
|
||||||
|
@JsonbProperty("invoice_number")
|
||||||
|
private String invoiceNumber;
|
||||||
|
|
||||||
|
private double amount;
|
||||||
|
|
||||||
|
public ZohoCreditnoteInvoiceItem(ZohoInvoice invoice) {
|
||||||
|
this.invoiceId = invoice.getInvoiceId();
|
||||||
|
this.invoiceNumber = invoice.getInvoiceNumber();
|
||||||
|
this.amount = invoice.getTotal();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getter und Setter
|
||||||
|
public String getInvoiceId() {
|
||||||
|
return invoiceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInvoiceId(String invoiceId) {
|
||||||
|
this.invoiceId = invoiceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInvoiceNumber() {
|
||||||
|
return invoiceNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInvoiceNumber(String invoiceNumber) {
|
||||||
|
this.invoiceNumber = invoiceNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(double amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -33,6 +33,9 @@ public class ZohoInvoice {
|
||||||
@JsonbProperty("exchange_rate")
|
@JsonbProperty("exchange_rate")
|
||||||
private double exchangeRate;
|
private double exchangeRate;
|
||||||
|
|
||||||
|
@JsonbProperty("place_of_supply")
|
||||||
|
private String placeOfSupply;
|
||||||
|
|
||||||
private double total;
|
private double total;
|
||||||
|
|
||||||
// Getter und Setter
|
// Getter und Setter
|
||||||
|
|
@ -108,4 +111,12 @@ public class ZohoInvoice {
|
||||||
public void setExchangeRate(double exchangeRate) {
|
public void setExchangeRate(double exchangeRate) {
|
||||||
this.exchangeRate = exchangeRate;
|
this.exchangeRate = exchangeRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPlaceOfSupply() {
|
||||||
|
return placeOfSupply;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlaceOfSupply(String placeOfSupply) {
|
||||||
|
this.placeOfSupply = placeOfSupply;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.alexanderlogistics.zoho.dto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import jakarta.json.bind.annotation.JsonbProperty;
|
||||||
|
|
||||||
|
public class ZohoInvoiceFindResponse {
|
||||||
|
@JsonbProperty("code")
|
||||||
|
private int code;
|
||||||
|
|
||||||
|
@JsonbProperty("message")
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
@JsonbProperty("invoices")
|
||||||
|
private List<ZohoInvoice> invoices;
|
||||||
|
|
||||||
|
// 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 List<ZohoInvoice> getInvoices() {
|
||||||
|
return invoices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInvoices(List<ZohoInvoice> invoices) {
|
||||||
|
this.invoices = invoices;
|
||||||
|
}
|
||||||
|
}
|
||||||
2687
workflow/dwc/rechnungsausgang-dwc-1.0.6.bpmn
Normal file
2687
workflow/dwc/rechnungsausgang-dwc-1.0.6.bpmn
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue