zoho credit note
This commit is contained in:
parent
8d236df375
commit
d4f1bd318e
5 changed files with 296 additions and 11 deletions
|
|
@ -30,6 +30,8 @@ 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.ZohoCreditnote;
|
||||
import com.alexanderlogistics.zoho.dto.ZohoCreditnoteCreateResponse;
|
||||
import com.alexanderlogistics.zoho.dto.ZohoInvoice;
|
||||
import com.alexanderlogistics.zoho.dto.ZohoInvoiceCreateResponse;
|
||||
import com.alexanderlogistics.zoho.dto.ZohoInvoiceItem;
|
||||
|
|
@ -197,6 +199,76 @@ public class ZohoAPIService {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports an Credit Note - outgoing invoice total < 0,00
|
||||
*
|
||||
* @see https://www.zoho.com/books/api/v3/expenses/#create-an-expense
|
||||
*
|
||||
* @param invoice
|
||||
* @throws PluginException
|
||||
*/
|
||||
public ZohoCreditnote exportCreditnote(ItemCollection invoice, String contactID,
|
||||
String accessToken) throws PluginException {
|
||||
logger.info("├── Zoho Export creditnote " + invoice.getItemValueString("invoice.number") + "...");
|
||||
|
||||
// Konvertiere ItemCollection zu ZohoInvoiceDTO
|
||||
ZohoCreditnote zohoCreditnote = convertToZohoCreditnote(invoice, contactID);
|
||||
|
||||
try {
|
||||
String requestBody = jsonb.toJson(zohoCreditnote);
|
||||
|
||||
// Print JSON to console for verification
|
||||
logger.fine("├── Zoho CreditNote JSON Request...");
|
||||
logger.fine("│ ├── " + requestBody);
|
||||
|
||||
// https://www.zohoapis.com/books/v3/creditnotes?organization_id=10234695'
|
||||
String uri = zohoOAuthManager.getBaseURI() + "creditnotes?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<String> 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 creditnote. Status code: " + response.statusCode() + ", Response: "
|
||||
+ response.body());
|
||||
}
|
||||
|
||||
// Erfolgreiche Erstellung
|
||||
String bodyContent = response.body();
|
||||
logger.fine("│ ├── Response Body: " + bodyContent);
|
||||
|
||||
System.out.print(bodyContent);
|
||||
ZohoCreditnoteCreateResponse createResponse = jsonb.fromJson(bodyContent,
|
||||
ZohoCreditnoteCreateResponse.class);
|
||||
|
||||
if (createResponse != null) {
|
||||
logger.info("│ ├── OK - customerID=" + createResponse.getCreditnote().getCustomerId());
|
||||
logger.info("│ ├── OK - creditNoteID=" + createResponse.getCreditnote().getCreditNoteNumber());
|
||||
zohoCreditnote = createResponse.getCreditnote();
|
||||
|
||||
// now mark the invoice as send
|
||||
logger.info("│ ├── VendorCredit Export successful.");
|
||||
return zohoCreditnote;
|
||||
}
|
||||
|
||||
} catch (IOException | InterruptedException e) {
|
||||
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
||||
"Failed to export creditnote to Zoho: " + e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports an Eingangsrechnung document
|
||||
*
|
||||
|
|
@ -421,6 +493,7 @@ public class ZohoAPIService {
|
|||
zohoInvoice.setTotal(convertInvoiceTotalToAED(invoice, invoice.getItemValueDouble("invoice.total")));
|
||||
|
||||
/*
|
||||
* Change: 10.06.2025
|
||||
* Das Cargosoft unlogische Positionen sendet, ZOHO diese aber erzwingt,
|
||||
* erzeugen wir nur noch eine einzige Zeile mit dem tatsächlichen Betrag!
|
||||
*
|
||||
|
|
@ -448,6 +521,54 @@ public class ZohoAPIService {
|
|||
return zohoInvoice;
|
||||
}
|
||||
|
||||
private ZohoCreditnote convertToZohoCreditnote(ItemCollection invoice, String contactID)
|
||||
throws PluginException {
|
||||
|
||||
ZohoCreditnote zohoCreditnote = new ZohoCreditnote();
|
||||
// Basisinformationen
|
||||
|
||||
zohoCreditnote.setCreditNoteNumber(invoice.getItemValueString("invoice.number"));
|
||||
zohoCreditnote.setDate(
|
||||
LocalDate.ofInstant(invoice.getItemValueDate("invoice.date").toInstant(), ZoneId.systemDefault()));
|
||||
zohoCreditnote.setDueDate(
|
||||
LocalDate.ofInstant(invoice.getItemValueDate("invoice.duedate").toInstant(), ZoneId.systemDefault()));
|
||||
|
||||
zohoCreditnote.setCustomerId(contactID);
|
||||
|
||||
// convert total by rate - negativer betrag!
|
||||
zohoCreditnote
|
||||
.setTotal(convertInvoiceTotalToAED(invoice, Math.abs(invoice.getItemValueDouble("invoice.total"))));
|
||||
|
||||
/*
|
||||
* Change: 10.06.2025
|
||||
* Das Cargosoft unlogische Positionen sendet, ZOHO diese aber erzwingt,
|
||||
* erzeugen wir nur noch eine einzige Zeile mit dem tatsächlichen Betrag!
|
||||
*
|
||||
*/
|
||||
// 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(convertInvoiceTotalToAED(invoice,
|
||||
// itemCol.getItemValueDouble("datev.umsatz")));
|
||||
// lineItem.setQuantity(1);
|
||||
// return lineItem;
|
||||
// }).collect(Collectors.toList());
|
||||
List<ZohoInvoiceItem> lineItems = new ArrayList<>();
|
||||
ZohoInvoiceItem lineItem = new ZohoInvoiceItem();
|
||||
lineItem.setName(invoice.getItemValueString("invoice.text"));
|
||||
lineItem.setDescription("");
|
||||
// negativer Betrag!
|
||||
lineItem.setRate(convertInvoiceTotalToAED(invoice, Math.abs(invoice.getItemValueDouble("invoice.total"))));
|
||||
lineItem.setQuantity(1);
|
||||
lineItems.add(lineItem);
|
||||
|
||||
zohoCreditnote.setLineItems(lineItems);
|
||||
return zohoCreditnote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Diese Hilfsmethode rechnet den Rechnungsbetrag in Fremdwährung auf AED um
|
||||
*
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import org.imixs.workflow.exceptions.AdapterException;
|
|||
import org.imixs.workflow.exceptions.PluginException;
|
||||
|
||||
import com.alexanderlogistics.zoho.dto.ZohoBill;
|
||||
import com.alexanderlogistics.zoho.dto.ZohoCreditnote;
|
||||
import com.alexanderlogistics.zoho.dto.ZohoInvoice;
|
||||
import com.alexanderlogistics.zoho.dto.ZohoVendorCredit;
|
||||
|
||||
|
|
@ -90,21 +91,46 @@ public class ZohoExportAdapter implements SignalAdapter {
|
|||
// String currencyID =
|
||||
// zohoAPIService.lookupCurrency(document.getItemValueString("invoice.currency"),
|
||||
// accessToken);
|
||||
ZohoInvoice zohoInvoice = zohoAPIService.exportInvoice(document, contactID, accessToken);
|
||||
|
||||
// Attache Files....
|
||||
List<FileData> files = null;
|
||||
ItemCollection snapshot = snapshotService.findSnapshot(document);
|
||||
if (snapshot != null) {
|
||||
files = snapshot.getFileData();
|
||||
if (files != null) {
|
||||
for (FileData file : files) {
|
||||
if (file.getName().toLowerCase().endsWith(".pdf")) {
|
||||
zohoAPIService.attacheFileData(zohoInvoice.getInvoiceId(), file, "invoices", accessToken);
|
||||
// Gutschrift??
|
||||
if (document.getItemValueDouble("invoice.total") < 0) {
|
||||
// create credit note!
|
||||
logger.info("├── CreditNote Export");
|
||||
ZohoCreditnote zohoCreditnote = zohoAPIService.exportCreditnote(document, contactID, accessToken);
|
||||
|
||||
// Attache Files....
|
||||
List<FileData> files = null;
|
||||
ItemCollection snapshot = snapshotService.findSnapshot(document);
|
||||
if (snapshot != null) {
|
||||
files = snapshot.getFileData();
|
||||
if (files != null) {
|
||||
for (FileData file : files) {
|
||||
if (file.getName().toLowerCase().endsWith(".pdf")) {
|
||||
zohoAPIService.attacheFileData(zohoCreditnote.getCreditnoteId(), file, "creditnotes",
|
||||
accessToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.info("├── Invoice Export");
|
||||
ZohoInvoice zohoInvoice = zohoAPIService.exportInvoice(document, contactID, accessToken);
|
||||
|
||||
// Attache Files....
|
||||
List<FileData> files = null;
|
||||
ItemCollection snapshot = snapshotService.findSnapshot(document);
|
||||
if (snapshot != null) {
|
||||
files = snapshot.getFileData();
|
||||
if (files != null) {
|
||||
for (FileData file : files) {
|
||||
if (file.getName().toLowerCase().endsWith(".pdf")) {
|
||||
zohoAPIService.attacheFileData(zohoInvoice.getInvoiceId(), file, "invoices", accessToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,99 @@
|
|||
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 ZohoCreditnote {
|
||||
@JsonbProperty("creditnote_id")
|
||||
private String creditnoteId;
|
||||
|
||||
@JsonbProperty("customer_id")
|
||||
private String customerId;
|
||||
|
||||
@JsonbProperty("currency_id")
|
||||
private String currencyId;
|
||||
|
||||
@JsonbDateFormat("yyyy-MM-dd")
|
||||
private LocalDate date;
|
||||
|
||||
@JsonbProperty("due_date")
|
||||
@JsonbDateFormat("yyyy-MM-dd")
|
||||
private LocalDate dueDate;
|
||||
|
||||
@JsonbProperty("creditnote_number")
|
||||
private String creditNoteNumber;
|
||||
|
||||
@JsonbProperty("line_items")
|
||||
private List<ZohoInvoiceItem> lineItems;
|
||||
|
||||
private double total;
|
||||
|
||||
// Getter und Setter
|
||||
|
||||
public String getCreditnoteId() {
|
||||
return creditnoteId;
|
||||
}
|
||||
|
||||
public void setCreditnoteId(String creditnoteId) {
|
||||
this.creditnoteId = creditnoteId;
|
||||
}
|
||||
|
||||
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 LocalDate getDueDate() {
|
||||
return dueDate;
|
||||
}
|
||||
|
||||
public void setDueDate(LocalDate duedate) {
|
||||
this.dueDate = duedate;
|
||||
}
|
||||
|
||||
public String getCreditNoteNumber() {
|
||||
return creditNoteNumber;
|
||||
}
|
||||
|
||||
public void setCreditNoteNumber(String creditNoteNumber) {
|
||||
this.creditNoteNumber = creditNoteNumber;
|
||||
}
|
||||
|
||||
public List<ZohoInvoiceItem> getLineItems() {
|
||||
return lineItems;
|
||||
}
|
||||
|
||||
public void setLineItems(List<ZohoInvoiceItem> lineItems) {
|
||||
this.lineItems = lineItems;
|
||||
}
|
||||
|
||||
public double getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(double total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public String getCurrencyId() {
|
||||
return currencyId;
|
||||
}
|
||||
|
||||
public void setCurrencyId(String currencyId) {
|
||||
this.currencyId = currencyId;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package com.alexanderlogistics.zoho.dto;
|
||||
|
||||
import jakarta.json.bind.annotation.JsonbProperty;
|
||||
|
||||
public class ZohoCreditnoteCreateResponse {
|
||||
@JsonbProperty("code")
|
||||
private int code;
|
||||
|
||||
@JsonbProperty("message")
|
||||
private String message;
|
||||
|
||||
@JsonbProperty("creditnote")
|
||||
private ZohoCreditnote creditnote;
|
||||
|
||||
// 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 ZohoCreditnote getCreditnote() {
|
||||
return creditnote;
|
||||
}
|
||||
|
||||
public void setCreditnote(ZohoCreditnote creditnote) {
|
||||
this.creditnote = creditnote;
|
||||
}
|
||||
}
|
||||
|
|
@ -137,7 +137,7 @@
|
|||
Generieren Sie einen neuen Access Code
|
||||
<br />
|
||||
Scope:
|
||||
<code>ZohoBooks.contacts.ALL,ZohoBooks.invoices.ALL,ZohoBooks.bills.ALL,ZohoBooks.debitnotes.ALL,ZohoBooks.settings.READ</code>
|
||||
<code>ZohoBooks.contacts.ALL,ZohoBooks.invoices.ALL,ZohoBooks.creditnotes.ALL,ZohoBooks.bills.ALL,ZohoBooks.debitnotes.ALL,ZohoBooks.settings.READ</code>
|
||||
</li>
|
||||
<li>
|
||||
Code über den Button "Create" anfordern und in das Feld "Access Code"
|
||||
|
|
|
|||
Loading…
Reference in a new issue