zoho invoice export - draft
This commit is contained in:
parent
39099700fe
commit
27f7b2b4f6
7 changed files with 2430 additions and 45 deletions
|
|
@ -1,17 +1,34 @@
|
|||
package com.alexanderlogistics.zoho;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.imixs.workflow.ItemCollection;
|
||||
import org.imixs.workflow.exceptions.PluginException;
|
||||
|
||||
import com.alexanderlogistics.InvoiceUtil;
|
||||
import com.alexanderlogistics.zoho.dto.ZohoInvoiceDTO;
|
||||
import com.alexanderlogistics.zoho.dto.ZohoInvoiceItemDTO;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.security.DeclareRoles;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
import jakarta.annotation.security.RunAs;
|
||||
import jakarta.ejb.Lock;
|
||||
import jakarta.ejb.LockType;
|
||||
import jakarta.ejb.Singleton;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.json.bind.Jsonb;
|
||||
import jakarta.json.bind.JsonbBuilder;
|
||||
import jakarta.json.bind.JsonbConfig;
|
||||
|
||||
/**
|
||||
* Der ZohoAPIService stellt methoden für den Zugriff auf die Zoho API bereit.
|
||||
* Er handelt auch die Authentifizeirung über einen Access Token. Der
|
||||
* ZohoOAuhtGrantService der dazu dient einen AccessCode von Zoho zu ermitteln
|
||||
* übergibt den code an diesesn Servcie. Er dietn also als Singelton
|
||||
*/
|
||||
@DeclareRoles({ "org.imixs.ACCESSLEVEL.NOACCESS", "org.imixs.ACCESSLEVEL.READERACCESS",
|
||||
"org.imixs.ACCESSLEVEL.AUTHORACCESS", "org.imixs.ACCESSLEVEL.EDITORACCESS",
|
||||
|
|
@ -23,18 +40,116 @@ import jakarta.ejb.Singleton;
|
|||
@RunAs("org.imixs.ACCESSLEVEL.MANAGERACCESS")
|
||||
public class ZohoAPIService {
|
||||
|
||||
private String accessToken;
|
||||
private String clientID;
|
||||
private String clientSecret;
|
||||
private static Logger logger = Logger.getLogger(ZohoAPIService.class.getName());
|
||||
private static final String ZOHO_API_BASE_URL = "https://www.zohoapis.eu/books/v3/";
|
||||
|
||||
@Lock(LockType.WRITE) // Standardmäßig ist @Lock(LockType.READ)
|
||||
public void setAccessToken(String token) {
|
||||
this.accessToken = token;
|
||||
}
|
||||
@Inject
|
||||
ZohoOAuthManager zohoOAuthManager;
|
||||
|
||||
@Lock(LockType.READ) // Erlaubt parallele Lesezugriffe
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
private HttpClient httpClient;
|
||||
private Jsonb jsonb;
|
||||
|
||||
@PostConstruct
|
||||
void init() {
|
||||
this.httpClient = HttpClient.newBuilder()
|
||||
.connectTimeout(Duration.ofSeconds(10))
|
||||
.build();
|
||||
// this.jsonb = JsonbBuilder.create();
|
||||
this.jsonb = JsonbBuilder.create(new JsonbConfig()
|
||||
.withDateFormat("yyyy-MM-dd", Locale.getDefault()));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports an invocie document
|
||||
*
|
||||
* @see https://www.zoho.com/books/api/v3/invoices/#create-an-invoice
|
||||
*
|
||||
* @param invoice
|
||||
* @throws PluginException
|
||||
*/
|
||||
public void exportInvoice(ItemCollection invoice) throws PluginException {
|
||||
String accessToken = zohoOAuthManager.getValidAccessToken();
|
||||
|
||||
// Konvertiere ItemCollection zu ZohoInvoiceDTO
|
||||
ZohoInvoiceDTO zohoInvoice = convertToZohoInvoice(invoice);
|
||||
|
||||
try {
|
||||
String requestBody = jsonb.toJson(zohoInvoice);
|
||||
|
||||
// Print JSON to console for verification
|
||||
logger.info("├── Zoho Invoice JSON Request...");
|
||||
logger.info("│ ├── " + requestBody);
|
||||
|
||||
// https://www.zohoapis.com/books/v3/invoices?organization_id=10234695'
|
||||
String uri = ZOHO_API_BASE_URL + "invoices?organization_id=" + zohoOAuthManager.getOrganization();
|
||||
logger.info("│ ├── uri= " + uri);
|
||||
logger.info("│ ├── 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.info("├── Zoho Response:");
|
||||
logger.info("│ ├── Status Code: " + response.statusCode());
|
||||
logger.info("│ ├── Response Body: " + response.body());
|
||||
|
||||
if (response.statusCode() >= 300) {
|
||||
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
||||
"Failed to create invoice. Status code: " + response.statusCode() +
|
||||
", Response: " + response.body());
|
||||
}
|
||||
|
||||
// Erfolgreiche Verarbeitung hier
|
||||
// Optional: Response auswerten
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
||||
"Failed to export invoice to Zoho", e);
|
||||
}
|
||||
}
|
||||
|
||||
private ZohoInvoiceDTO convertToZohoInvoice(ItemCollection invoice) {
|
||||
ZohoInvoiceDTO zohoInvoice = new ZohoInvoiceDTO();
|
||||
|
||||
// Basisinformationen
|
||||
// zohoInvoice.setInvoiceNumber(invoice.getItemValueString("invoice.number"));
|
||||
|
||||
logger.info("invoice.date=" + invoice.getItemValueDate("invoice.date"));
|
||||
logger.info("invoice.duedate=" + invoice.getItemValueDate("invoice.duedate"));
|
||||
|
||||
zohoInvoice.setDate(invoice.getItemValueDate("invoice.date"));
|
||||
zohoInvoice.setDueDate(invoice.getItemValueDate("invoice.duedate"));
|
||||
zohoInvoice.setTotal(invoice.getItemValueDouble("invoice.total"));
|
||||
|
||||
// Kunden-ID (muss angepasst werden je nachdem wie du sie speicherst)
|
||||
// zohoInvoice.setCustomerId(invoice.getItemValueString("dbtr.number"));
|
||||
zohoInvoice.setCustomerId("777249000000055569");
|
||||
|
||||
// Positionen (muss angepasst werden je nach Datenstruktur)
|
||||
// List<ZohoInvoiceItemDTO> lineItems = new ArrayList<>();
|
||||
List<ItemCollection> positionen = InvoiceUtil.explodeChildList(invoice);
|
||||
|
||||
List<ZohoInvoiceItemDTO> lineItems = positionen.stream()
|
||||
.map(item -> {
|
||||
ItemCollection itemCol = (ItemCollection) item;
|
||||
ZohoInvoiceItemDTO lineItem = new ZohoInvoiceItemDTO();
|
||||
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());
|
||||
|
||||
zohoInvoice.setLineItems(lineItems);
|
||||
|
||||
return zohoInvoice;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,130 @@
|
|||
package com.alexanderlogistics.zoho;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||
import org.imixs.archive.core.SnapshotService;
|
||||
import org.imixs.workflow.FileData;
|
||||
import org.imixs.workflow.ItemCollection;
|
||||
import org.imixs.workflow.SignalAdapter;
|
||||
import org.imixs.workflow.engine.WorkflowService;
|
||||
import org.imixs.workflow.exceptions.AdapterException;
|
||||
import org.imixs.workflow.exceptions.PluginException;
|
||||
|
||||
import com.alexanderlogistics.InvoicePlugin;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
/**
|
||||
* This adapter exports the invoice data to zoho
|
||||
*
|
||||
* @version 1.0
|
||||
* @author rsoika
|
||||
*/
|
||||
public class ZohoExportAdapter implements SignalAdapter {
|
||||
|
||||
public static final String CONFIG_ERROR = "CONFIG_ERROR";
|
||||
public static final String ENV_ZOHO_EXPORT_MAX_ATTACHMENT_SIZE = "zoho.export.maxattachmentsize";
|
||||
|
||||
private static Logger logger = Logger.getLogger(ZohoExportAdapter.class.getName());
|
||||
|
||||
@Inject
|
||||
ZohoAPIService zohoAPIService;
|
||||
|
||||
@Inject
|
||||
WorkflowService workflowService;
|
||||
|
||||
@Inject
|
||||
SnapshotService snapshotService;
|
||||
|
||||
@Inject
|
||||
@ConfigProperty(name = ENV_ZOHO_EXPORT_MAX_ATTACHMENT_SIZE, defaultValue = "10485760")
|
||||
long maxAttachmentSize;
|
||||
|
||||
/**
|
||||
* This method calls the zoho api
|
||||
*
|
||||
* @throws PluginException
|
||||
*/
|
||||
@Override
|
||||
public ItemCollection execute(ItemCollection document, ItemCollection event)
|
||||
throws AdapterException, PluginException {
|
||||
|
||||
logger.info("......starting export...");
|
||||
|
||||
// read the cargosoft export options
|
||||
ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "zoho", document, false);
|
||||
|
||||
zohoAPIService.exportInvoice(document);
|
||||
return document;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method lookups the origin snapshot data and add the content of the $file
|
||||
* to the export document
|
||||
* <p>
|
||||
* Change 14.10.2021 - Wir senden maximal 5MB and Daten, da die Cargosoft
|
||||
* Schnittstelle größere Datensätze mit großen Dateianhängen einfach verschluckt
|
||||
* ohne eine Fehlermeldugn zu liefern.
|
||||
*
|
||||
*
|
||||
* @param document
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private ItemCollection loadFileDataFromSnapshot(ItemCollection document) {
|
||||
ItemCollection origin = null;
|
||||
ItemCollection result = (ItemCollection) document.clone();
|
||||
|
||||
// find the origin document
|
||||
List<String> refs = document.getItemValue(WorkflowService.UNIQUEIDREF);
|
||||
for (String ref : refs) {
|
||||
origin = workflowService.getWorkItem(ref);
|
||||
// "Rechnungseingang".equals(origin.getWorkflowGroup())
|
||||
if (InvoicePlugin.isCargoRechnung(origin)) {
|
||||
break;
|
||||
}
|
||||
origin = null;
|
||||
}
|
||||
|
||||
// we should have found the origin...
|
||||
if (origin != null) {
|
||||
ItemCollection snapshot = snapshotService.findSnapshot(origin);
|
||||
// we should have found a snapshot...
|
||||
if (snapshot != null) {
|
||||
List<FileData> fileDataList = snapshot.getFileData();
|
||||
// transfer origin file content
|
||||
result.removeItem("$file");
|
||||
long currentAttachmentSize = 0;
|
||||
// we do only accept .pdf files and a maximum size of 10MB
|
||||
for (FileData filedata : fileDataList) {
|
||||
if (filedata.getName().toLowerCase().endsWith(".pdf")) {
|
||||
// test if the size of the file is below the
|
||||
// "cargosoft.export.ftp.maxattachmentsize"
|
||||
if ((currentAttachmentSize + filedata.getContent().length) > maxAttachmentSize) {
|
||||
long maxSizeInMB = maxAttachmentSize / 1024 / 1024;
|
||||
String message = "Attachment '" + filedata.getName()
|
||||
+ "' can not be exported to cargosoft - max file size exeeded (" + maxSizeInMB
|
||||
+ "MB)!";
|
||||
logger.warning(message);
|
||||
// add comment
|
||||
document.setItemValue("txtComment", message);
|
||||
} else {
|
||||
result.addFileData(filedata);
|
||||
currentAttachmentSize = currentAttachmentSize + filedata.getContent().length;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.warning("...did not found snapshot for origin workitem " + origin.getUniqueID());
|
||||
}
|
||||
} else {
|
||||
logger.warning("...did not found origin workitem " + document.getUniqueID());
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -48,9 +48,12 @@ import jakarta.ws.rs.core.MediaType;
|
|||
*
|
||||
* https://www.zoho.com/books/api/v3/oauth/
|
||||
*
|
||||
* Er dient als redirect URL wenn jemand einen solchen Token über den Browser
|
||||
* anfordert.
|
||||
* Der URL muss hier als CallBack URL angegeben sein!
|
||||
* Der Service wird aktuell nicht benötigt, das wir sogenannte Zoho Self-Clients
|
||||
* verwenden!
|
||||
*
|
||||
* Der Service stellt im Grunde nur eine Callback URL für einen normalen Zoho
|
||||
* Client ein. Also wenn jemand einen solchen Token über den Browser
|
||||
* anfordert. Der URL muss dann odrt als CallBack URL angegeben sein!
|
||||
*
|
||||
* Beispiel:
|
||||
*
|
||||
|
|
@ -60,9 +63,10 @@ import jakarta.ws.rs.core.MediaType;
|
|||
* @author rsoika
|
||||
*
|
||||
*/
|
||||
@Deprecated
|
||||
@Path("/zoho")
|
||||
@Stateless
|
||||
public class ZohoOAuthGrantService {
|
||||
public class ZohoOAuthCallbackService {
|
||||
|
||||
@Context
|
||||
private HttpServletRequest servletRequest;
|
||||
|
|
@ -70,7 +74,7 @@ public class ZohoOAuthGrantService {
|
|||
@EJB
|
||||
ZohoOAuthManager zohoOAuthManager;
|
||||
|
||||
private static Logger logger = Logger.getLogger(ZohoOAuthGrantService.class.getName());
|
||||
private static Logger logger = Logger.getLogger(ZohoOAuthCallbackService.class.getName());
|
||||
|
||||
@GET
|
||||
@Path("/ping")
|
||||
|
|
@ -117,8 +121,6 @@ public class ZohoOAuthGrantService {
|
|||
logger.info("│ ├── location=" + location);
|
||||
logger.info("│ ├── accounts-server=" + accountsServer);
|
||||
|
||||
// zohoOAuthManager.updateTokens(code);
|
||||
|
||||
return "Zoho Callback received!";
|
||||
}
|
||||
|
||||
|
|
@ -35,12 +35,8 @@ import jakarta.json.bind.JsonbBuilder;
|
|||
public class ZohoOAuthManager {
|
||||
|
||||
private static Logger logger = Logger.getLogger(ZohoOAuthManager.class.getName());
|
||||
|
||||
private String refreshToken;
|
||||
private String accessToken;
|
||||
private long accessTokenExpiry; // Timestamp (System.currentTimeMillis() + expires_in*1000)
|
||||
|
||||
private String redirectURI = "https://alexander-logistics-dwc.office-workflow.de/api/zoho/grant";
|
||||
|
||||
public static final String ERROR_CONFIG = "CONFIG_ERROR";
|
||||
|
||||
@EJB
|
||||
|
|
@ -57,11 +53,40 @@ public class ZohoOAuthManager {
|
|||
this.jsonb = JsonbBuilder.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt den aktuellen Access Token zurück. Falls dieser expired ist wird
|
||||
* automatisch ein refresh durchgeführt. Somit liefert die Methode immer einen
|
||||
* gültigen token.
|
||||
*
|
||||
* @return
|
||||
* @throws PluginException
|
||||
*/
|
||||
@Lock(LockType.READ)
|
||||
public String getValidAccessToken() {
|
||||
public String getValidAccessToken() throws PluginException {
|
||||
logger.info("├── get Zoho AccessTokens");
|
||||
ItemCollection zohoConfig = configService.loadConfiguration(ZohoController.ZOHO_CONFIGURATION, false);
|
||||
String accessToken = zohoConfig.getItemValueString("zoho.accessToken");
|
||||
logger.fine("│ ├── accessToken=" + accessToken);
|
||||
logger.fine("│ ├── refresh=" + zohoConfig.getItemValueString("zoho.refreshToken"));
|
||||
logger.fine("│ ├── expires_in=" + zohoConfig.getItemValueDate("zoho.expires"));
|
||||
|
||||
Date expireDate = zohoConfig.getItemValueDate("zoho.expires");
|
||||
if (expireDate.getTime() < System.currentTimeMillis()) {
|
||||
logger.info("│ ├── Access Token expired (" + expireDate + ")");
|
||||
accessToken = refreshAccessToken();
|
||||
}
|
||||
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public String getOrganization() throws PluginException {
|
||||
ItemCollection zohoConfig = configService.loadConfiguration(ZohoController.ZOHO_CONFIGURATION, false);
|
||||
if (zohoConfig != null) {
|
||||
return zohoConfig.getItemValueString("zoho.organization");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Step 3: Generate Access and Refresh Token
|
||||
*
|
||||
|
|
@ -75,14 +100,10 @@ public class ZohoOAuthManager {
|
|||
*/
|
||||
@Lock(LockType.WRITE)
|
||||
public void updateTokens(String code) throws PluginException {
|
||||
|
||||
logger.info("├── update Zoho tokens");
|
||||
refreshToken = null;
|
||||
accessToken = null;
|
||||
|
||||
try {
|
||||
|
||||
ItemCollection zohoConfig = configService.loadConfiguration(ZohoController.ZOHO_CONFIGURATION);
|
||||
ItemCollection zohoConfig = configService.loadConfiguration(ZohoController.ZOHO_CONFIGURATION, false);
|
||||
|
||||
String clientID = zohoConfig.getItemValueString("zoho.clientid");
|
||||
String clientSecret = zohoConfig.getItemValueString("zoho.clientsecret");
|
||||
|
|
@ -138,18 +159,15 @@ public class ZohoOAuthManager {
|
|||
* @throws PluginException
|
||||
*/
|
||||
@Lock(LockType.WRITE)
|
||||
public void refreshAccessToken() throws PluginException {
|
||||
public String refreshAccessToken() throws PluginException {
|
||||
|
||||
logger.info("├── refresh Zoho access token");
|
||||
|
||||
ItemCollection zohoConfig = configService.loadConfiguration(ZohoController.ZOHO_CONFIGURATION);
|
||||
|
||||
ItemCollection zohoConfig = configService.loadConfiguration(ZohoController.ZOHO_CONFIGURATION, false);
|
||||
String clientID = zohoConfig.getItemValueString("zoho.clientid");
|
||||
String clientSecret = zohoConfig.getItemValueString("zoho.clientsecret");
|
||||
|
||||
refreshToken = zohoConfig.getItemValueString("zoho.refreshToken");
|
||||
String refreshToken = zohoConfig.getItemValueString("zoho.refreshToken");
|
||||
try {
|
||||
|
||||
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" +
|
||||
"?refresh_token=" + URLEncoder.encode(refreshToken, StandardCharsets.UTF_8) +
|
||||
"&client_id=" + URLEncoder.encode(clientID, StandardCharsets.UTF_8) +
|
||||
|
|
@ -179,12 +197,9 @@ public class ZohoOAuthManager {
|
|||
|
||||
TokenResponse tokenResponse = jsonb.fromJson(response.body(),
|
||||
TokenResponse.class);
|
||||
|
||||
saveTokenData(zohoConfig, tokenResponse);
|
||||
return zohoConfig.getItemValueString("zoho.accessToken");
|
||||
|
||||
// String accessToken = tokenResponse.getAccess_token();
|
||||
// logger.info("│ ├── accessToken=" + accessToken);
|
||||
// logger.info("│ ├── expires_in=" + tokenResponse.getExpires_in());
|
||||
} else {
|
||||
throw new RuntimeException("Failed to get tokens: " +
|
||||
response.statusCode() + " - " + response.body());
|
||||
|
|
@ -194,7 +209,6 @@ public class ZohoOAuthManager {
|
|||
throw new PluginException(ZohoOAuthManager.class.getSimpleName(),
|
||||
ZohoOAuthManager.ERROR_CONFIG, "Unable to refresh access tokens: " + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -216,12 +230,12 @@ public class ZohoOAuthManager {
|
|||
zohoConfig.setItemValue("zoho.scope", scope);
|
||||
}
|
||||
|
||||
accessToken = tokenResponse.getAccess_token();
|
||||
String accessToken = tokenResponse.getAccess_token();
|
||||
if (accessToken != null && !accessToken.isEmpty()) {
|
||||
logger.info("│ ├── accessToken=" + accessToken);
|
||||
zohoConfig.setItemValue("zoho.accessToken", accessToken);
|
||||
}
|
||||
refreshToken = tokenResponse.getRefresh_token();
|
||||
String refreshToken = tokenResponse.getRefresh_token();
|
||||
if (refreshToken != null && !refreshToken.isEmpty()) {
|
||||
logger.info("│ ├── refreshToken=" + refreshToken);
|
||||
zohoConfig.setItemValue("zoho.refreshToken", refreshToken);
|
||||
|
|
@ -233,6 +247,7 @@ public class ZohoOAuthManager {
|
|||
long expiresTimeMillis = currentTimeMillis + (expiresInSeconds * 1000);
|
||||
// Expires-Zeit in ein Date-Objekt konvertieren
|
||||
Date expiresDate = new Date(expiresTimeMillis);
|
||||
logger.info("│ ├── expire date=" + expiresDate);
|
||||
zohoConfig.setItemValue("zoho.expires", expiresDate);
|
||||
zohoConfig.setItemValue("message", "Access Token OK");
|
||||
configService.save(zohoConfig);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
package com.alexanderlogistics.zoho.dto;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.json.bind.annotation.JsonbProperty;
|
||||
|
||||
public class ZohoInvoiceDTO {
|
||||
|
||||
private String customerId;
|
||||
private Date date;
|
||||
private Date dueDate;
|
||||
private String invoiceNumber;
|
||||
private List<ZohoInvoiceItemDTO> lineItems;
|
||||
private double total;
|
||||
|
||||
// Getter und Setter
|
||||
|
||||
@JsonbProperty("customer_id")
|
||||
public String getCustomerId() {
|
||||
return customerId;
|
||||
}
|
||||
|
||||
public void setCustomerId(String customerId) {
|
||||
this.customerId = customerId;
|
||||
}
|
||||
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
@JsonbProperty("due_date")
|
||||
public Date getDueDate() {
|
||||
return dueDate;
|
||||
}
|
||||
|
||||
public void setDueDate(Date duedate) {
|
||||
this.dueDate = duedate;
|
||||
}
|
||||
|
||||
@JsonbProperty("invoice_number")
|
||||
public String getInvoiceNumber() {
|
||||
return invoiceNumber;
|
||||
}
|
||||
|
||||
public void setInvoiceNumber(String invoiceNumber) {
|
||||
this.invoiceNumber = invoiceNumber;
|
||||
}
|
||||
|
||||
@JsonbProperty("line_items")
|
||||
public List<ZohoInvoiceItemDTO> getLineItems() {
|
||||
return lineItems;
|
||||
}
|
||||
|
||||
public void setLineItems(List<ZohoInvoiceItemDTO> lineItems) {
|
||||
this.lineItems = lineItems;
|
||||
}
|
||||
|
||||
public double getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(double total) {
|
||||
this.total = total;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.alexanderlogistics.zoho.dto;
|
||||
|
||||
public class ZohoInvoiceItemDTO {
|
||||
private String name;
|
||||
private String description;
|
||||
private double rate;
|
||||
private int quantity;
|
||||
|
||||
// Getter und Setter
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public double getRate() {
|
||||
return rate;
|
||||
}
|
||||
|
||||
public void setRate(double rate) {
|
||||
this.rate = rate;
|
||||
}
|
||||
|
||||
public int getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(int quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
}
|
||||
2011
workflow/dwc/rechnungsausgang-dwc-1.0.3-draft.bpmn
Normal file
2011
workflow/dwc/rechnungsausgang-dwc-1.0.3-draft.bpmn
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue