zoho invoice export

This commit is contained in:
Ralph Soika 2025-04-30 11:25:08 +02:00
parent 72a10ddcf5
commit f30cc8e8fe
7 changed files with 388 additions and 98 deletions

View file

@ -0,0 +1,177 @@
{
"code": 0,
"message": "The contact has been added.",
"contact": {
"contact_id": "777249000000077029",
"contact_name": "HQ Recyclers Network e.K.",
"company_name": "HQ Recyclers Network e.K.",
"contact_number": "CUS-00008",
"contact_tax_information": "",
"first_name": "",
"last_name": "",
"designation": "",
"department": "",
"website": "",
"is_bcy_only_contact": true,
"is_credit_limit_migration_completed": true,
"language_code": "",
"language_code_formatted": "",
"contact_salutation": "",
"email": "",
"phone": "",
"mobile": "",
"invited_by": "",
"portal_status": "disabled",
"is_client_review_asked": false,
"has_transaction": false,
"contact_type": "customer",
"customer_sub_type": "business",
"owner_id": "",
"owner_name": "",
"source": "api",
"documents": [],
"twitter": "",
"facebook": "",
"is_crm_customer": false,
"is_linked_with_zohocrm": false,
"primary_contact_id": "",
"zcrm_account_id": "",
"zcrm_contact_id": "",
"crm_owner_id": "",
"payment_terms": 0,
"payment_terms_label": "Due on Receipt",
"payment_terms_id": "",
"credit_limit_exceeded_amount": 0.00,
"currency_id": "777249000000000071",
"currency_code": "EUR",
"currency_symbol": "€",
"price_precision": 2,
"exchange_rate": "",
"can_show_customer_ob": true,
"can_show_vendor_ob": true,
"opening_balance_amount": 0.00,
"opening_balance_amount_bcy": "",
"outstanding_ob_receivable_amount": 0.00,
"outstanding_ob_payable_amount": 0.00,
"outstanding_receivable_amount": 0.00,
"outstanding_receivable_amount_bcy": 0.00,
"outstanding_payable_amount": 0.00,
"outstanding_payable_amount_bcy": 0.00,
"unused_credits_receivable_amount": 0.00,
"unused_credits_receivable_amount_bcy": 0.00,
"unused_credits_payable_amount": 0.00,
"unused_credits_payable_amount_bcy": 0.00,
"unused_retainer_payments": 0.00,
"status": "active",
"payment_reminder_enabled": true,
"is_sms_enabled": true,
"is_consent_agreed": false,
"consent_date": "",
"is_client_review_settings_enabled": false,
"custom_fields": [],
"custom_field_hash": {},
"tax_reg_label": "",
"contact_category": "",
"sales_channel": "direct_sales",
"ach_supported": false,
"portal_receipt_count": 0,
"opening_balances": [],
"entity_address_id": "777249000000077035",
"billing_address": {
"address_id": "777249000000077031",
"attention": "",
"address": "",
"street2": "",
"city": "",
"state_code": "",
"state": "",
"zip": "",
"country": "",
"county": "",
"country_code": "",
"phone": "",
"fax": ""
},
"shipping_address": {
"address_id": "777249000000077033",
"attention": "",
"address": "",
"street2": "",
"city": "",
"state_code": "",
"state": "",
"zip": "",
"country": "",
"county": "",
"country_code": "",
"phone": "",
"fax": "",
"latitude": "",
"longitude": ""
},
"contact_persons": [],
"addresses": [],
"pricebook_id": "",
"pricebook_name": "",
"default_templates": {
"statement_template_id": "",
"statement_template_name": "",
"invoice_template_id": "",
"invoice_template_name": "",
"bill_template_id": "",
"bill_template_name": "",
"estimate_template_id": "",
"estimate_template_name": "",
"creditnote_template_id": "",
"creditnote_template_name": "",
"paymentthankyou_template_id": "",
"paymentthankyou_template_name": "",
"invoice_email_template_id": "",
"invoice_email_template_name": "",
"estimate_email_template_id": "",
"estimate_email_template_name": "",
"creditnote_email_template_id": "",
"creditnote_email_template_name": "",
"paymentthankyou_email_template_id": "",
"paymentthankyou_email_template_name": "",
"payment_remittance_email_template_id": "",
"payment_remittance_email_template_name": ""
},
"associated_with_square": false,
"cards": [],
"checks": [],
"bank_accounts": [],
"vpa_list": [],
"notes": "",
"created_time": "2025-04-30T11:14:42+0200",
"created_date": "2025-04-30",
"created_by_name": "Ralph Soika",
"last_modified_time": "2025-04-30T11:14:42+0200",
"tags": [],
"zohopeople_client_id": "",
"customer_currency_summaries": [
{
"currency_id": "777249000000000071",
"currency_code": "EUR",
"currency_symbol": "€",
"price_precision": 2,
"is_base_currency": true,
"currency_name_formatted": "EUR- Euro",
"outstanding_receivable_amount": 0.00,
"unused_credits_receivable_amount": 0.00
}
],
"is_valid_trn": false,
"trn_last_validated_time": "",
"trn_last_validated_time_formatted": "",
"approvers_list": [],
"submitted_date": "",
"submitted_by": "",
"submitted_by_name": "",
"submitted_by_email": "",
"submitted_by_photo_url": "",
"submitter_id": "",
"approver_id": "",
"integration_references": []
}
}

View file

@ -1,5 +1,6 @@
package com.alexanderlogistics.zoho;
import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
@ -17,7 +18,8 @@ import org.imixs.workflow.exceptions.PluginException;
import com.alexanderlogistics.InvoiceUtil;
import com.alexanderlogistics.zoho.dto.ZohoContact;
import com.alexanderlogistics.zoho.dto.ZohoContactsResponse;
import com.alexanderlogistics.zoho.dto.ZohoContactCreateResponse;
import com.alexanderlogistics.zoho.dto.ZohoContactFindResponse;
import com.alexanderlogistics.zoho.dto.ZohoInvoice;
import com.alexanderlogistics.zoho.dto.ZohoInvoiceItem;
@ -67,13 +69,13 @@ public class ZohoAPIService {
public String findContactIDByCompanyName(String companyName, String accessToken) throws PluginException {
// Print JSON to console for verification
logger.info("├── Zoho getcontact Request...");
logger.info("├── Zoho lookup contact '" + companyName + "'...");
try {
// https://www.zohoapis.com/books/v3/contacts?organization_id=10234695&company_name=xxx'
String uri = ZOHO_API_BASE_URL + "contacts?organization_id="
+ zohoOAuthManager.getOrganization() + "&company_name="
+ URLEncoder.encode(companyName, StandardCharsets.UTF_8);
logger.info("│ ├── uri= " + uri);
logger.fine("│ ├── uri= " + uri);
logger.fine("│ ├── accessToken=" + accessToken);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(uri))
@ -86,23 +88,23 @@ public class ZohoAPIService {
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());
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 Contacts - Status code: " + response.statusCode() +
", Response: " + response.body());
}
ZohoContactsResponse contactsResponse = jsonb.fromJson(response.body(),
ZohoContactsResponse.class);
ZohoContactFindResponse contactsResponse = jsonb.fromJson(response.body(),
ZohoContactFindResponse.class);
if (contactsResponse != null && contactsResponse.getContacts() != null) {
// Durchsuche die Ergebnisse nach exakter Übereinstimmung
for (ZohoContact contact : contactsResponse.getContacts()) {
if (companyName.equalsIgnoreCase(contact.getCompanyName())) {
logger.info("│ ├── contactID= " + contact.getContactId());
return contact.getContactId();
}
}
@ -125,21 +127,31 @@ public class ZohoAPIService {
*/
public void exportInvoice(ItemCollection invoice) throws PluginException {
String accessToken = zohoOAuthManager.getValidAccessToken();
logger.info("├── Zoho Export Invoice " + invoice.getItemValueString("invoice.number") + "...");
// first lookup contact!
String contactID = "";
contactID = findContactIDByCompanyName(invoice.getItemValueString("dbtr.name"), accessToken);
if (contactID == null) {
logger.info("│ ├── contact not found");
ZohoContact contact = createContact(invoice.getItemValueString("dbtr.name"), accessToken);
contactID = contact.getContactId();
}
// Konvertiere ItemCollection zu ZohoInvoiceDTO
ZohoInvoice zohoInvoice = convertToZohoInvoice(invoice, accessToken);
ZohoInvoice zohoInvoice = convertToZohoInvoice(invoice, contactID, accessToken);
try {
String requestBody = jsonb.toJson(zohoInvoice);
// Print JSON to console for verification
logger.info("├── Zoho Invoice JSON Request...");
logger.info("│ ├── " + requestBody);
logger.fine("├── Zoho Invoice JSON Request...");
logger.fine("│ ├── " + 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.fine("│ ├── uri= " + uri);
logger.fine("│ ├── accessToken=" + accessToken);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(uri))
@ -152,9 +164,9 @@ public class ZohoAPIService {
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());
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",
@ -164,10 +176,10 @@ public class ZohoAPIService {
// Erfolgreiche Verarbeitung hier
// Optional: Response auswerten
} catch (Exception e) {
logger.info("│ ├── Invoice Export successful.");
} catch (IOException | InterruptedException e) {
throw new PluginException(this.getClass().getName(), "Zoho API error",
"Failed to export invoice to Zoho", e);
"Failed to export invoice to Zoho: " + e.getMessage(), e);
}
}
@ -179,7 +191,7 @@ public class ZohoAPIService {
* @throws PluginException Wenn der API-Aufruf fehlschlägt
*/
public ZohoContact createContact(String companyName, String accessToken) throws PluginException {
logger.info("├── Zoho create contact '" + companyName + "'...");
try {
// Contact-DTO vorbereiten
ZohoContact newContact = new ZohoContact();
@ -188,10 +200,7 @@ public class ZohoAPIService {
// JSON serialisieren
String requestBody = jsonb.toJson(newContact);
logger.info("├── Zoho Contact Creation...");
logger.info("│ ├── " + requestBody);
logger.fine("│ ├── " + requestBody);
String uri = ZOHO_API_BASE_URL + "contacts?organization_id="
+ zohoOAuthManager.getOrganization();
@ -204,61 +213,44 @@ public class ZohoAPIService {
HttpResponse<String> response = httpClient.send(
request, HttpResponse.BodyHandlers.ofString());
logger.info("├── Zoho Response:");
logger.info("│ ├── Status Code: " + response.statusCode());
logger.info("│ ├── Response Body: " + response.body());
if (response.statusCode() == 201) {
// Erfolgreiche Erstellung
ZohoContact createResponse = jsonb.fromJson(response.body(), ZohoContact.class);
if (createResponse != null) {
return createResponse;
}
}
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 create contact. Status code: " + response.statusCode() +
"Failed to create invoice. Status code: " + response.statusCode() +
", Response: " + response.body());
}
} catch (Exception e) {
// Erfolgreiche Erstellung
ZohoContactCreateResponse createResponse = jsonb.fromJson(response.body(), ZohoContactCreateResponse.class);
if (createResponse != null) {
logger.info("│ ├── OK - contactID=" + createResponse.getContact().getContactId());
return createResponse.getContact();
} else {
throw new PluginException(this.getClass().getName(), "Zoho API error",
"Failed to create contact", e);
}
"Response could not be resolved!");
}
private ZohoInvoice convertToZohoInvoice(ItemCollection invoice, String accessToken) throws PluginException {
} catch (IOException | InterruptedException e) {
throw new PluginException(this.getClass().getName(), "Zoho API error",
"Failed to create contact: " + e.getMessage(), e);
}
// teste ob wir einen contact finden
String contactID = "";
try {
contactID = findContactIDByCompanyName(invoice.getItemValueString("dbtr.name"), accessToken);
if (contactID == null) {
ZohoContact contact = createContact(invoice.getItemValueString("dbtr.name"), accessToken);
contactID = contact.getContactId();
}
} catch (PluginException ef) {
logger.severe("Failed to find Contact by company name: " + ef.getMessage());
}
private ZohoInvoice convertToZohoInvoice(ItemCollection invoice, String contactID, String accessToken)
throws PluginException {
ZohoInvoice zohoInvoice = new ZohoInvoice();
// Basisinformationen
// zohoInvoice.setInvoiceNumber(invoice.getItemValueString("invoice.number"));
logger.info("invoice.date=" + invoice.getItemValueDate("invoice.date"));
logger.info("invoice.duedate=" + invoice.getItemValueDate("invoice.duedate"));
logger.fine("invoice.date=" + invoice.getItemValueDate("invoice.date"));
logger.fine("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(contactID);
// zohoInvoice.setCustomerId("777249000000055569");
// Positionen (muss angepasst werden je nach Datenstruktur)
// List<ZohoInvoiceItemDTO> lineItems = new ArrayList<>();
List<ItemCollection> positionen = InvoiceUtil.explodeChildList(invoice);
List<ZohoInvoiceItem> lineItems = positionen.stream()
@ -274,7 +266,6 @@ public class ZohoAPIService {
.collect(Collectors.toList());
zohoInvoice.setLineItems(lineItems);
return zohoInvoice;
}
}

View file

@ -50,8 +50,7 @@ public class ZohoExportAdapter implements SignalAdapter {
@Override
public ItemCollection execute(ItemCollection document, ItemCollection event)
throws AdapterException, PluginException {
logger.info("......starting export...");
logger.info("├── Invoice Export");
// read the cargosoft export options
ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "zoho", document, false);

View file

@ -63,7 +63,7 @@ public class ZohoOAuthManager {
*/
@Lock(LockType.READ)
public String getValidAccessToken() throws PluginException {
logger.info("├── get Zoho AccessTokens");
logger.fine("├── get Zoho AccessTokens");
ItemCollection zohoConfig = configService.loadConfiguration(ZohoController.ZOHO_CONFIGURATION, false);
String accessToken = zohoConfig.getItemValueString("zoho.accessToken");
logger.fine("│ ├── accessToken=" + accessToken);
@ -72,7 +72,7 @@ public class ZohoOAuthManager {
Date expireDate = zohoConfig.getItemValueDate("zoho.expires");
if (expireDate.getTime() < System.currentTimeMillis()) {
logger.info("│ ├── Access Token expired (" + expireDate + ")");
logger.fine("│ ├── Access Token expired (" + expireDate + ")");
accessToken = refreshAccessToken();
}
@ -114,7 +114,7 @@ public class ZohoOAuthManager {
"&redirect_uri=" + URLEncoder.encode(redirectURI, StandardCharsets.UTF_8) +
"&grant_type=authorization_code";
logger.info("│ ├── Request URI=" + requestUrl);
logger.fine("│ ├── Request URI=" + requestUrl);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(requestUrl))
@ -126,10 +126,10 @@ public class ZohoOAuthManager {
response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
logger.info("│ ├── Response statusCode=" + response.statusCode());
logger.fine("│ ├── Response statusCode=" + response.statusCode());
if (response.statusCode() == 200) {
// 1. Response-Logging für Debugging
logger.info("│ ├── Response Body=" + response.body());
logger.fine("│ ├── Response Body=" + response.body());
if (response.body().contains("error")) {
throw new PluginException(ZohoOAuthManager.class.getSimpleName(),
@ -176,7 +176,7 @@ public class ZohoOAuthManager {
+
"&grant_type=refresh_token";
logger.info("│ ├── Request URI=" + requestUrl);
logger.fine("│ ├── Request URI=" + requestUrl);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(requestUrl))
@ -189,11 +189,11 @@ public class ZohoOAuthManager {
response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
logger.info("│ ├── Response statusCode=" + response.statusCode());
logger.fine("│ ├── Response statusCode=" + response.statusCode());
if (response.statusCode() == 200) {
// 1. Response-Logging für Debugging
logger.info("│ ├── Response Body=" + response.body());
logger.fine("│ ├── Response Body=" + response.body());
TokenResponse tokenResponse = jsonb.fromJson(response.body(),
TokenResponse.class);
@ -221,33 +221,33 @@ public class ZohoOAuthManager {
String apiDomain = tokenResponse.getApi_domain();
if (apiDomain != null && !apiDomain.isEmpty()) {
logger.info("│ ├── apiDomain=" + apiDomain);
logger.fine("│ ├── apiDomain=" + apiDomain);
zohoConfig.setItemValue("zoho.apiDomain", apiDomain);
}
String scope = tokenResponse.getScope();
if (scope != null && !scope.isEmpty()) {
logger.info("│ ├── scope=" + scope);
logger.fine("│ ├── scope=" + scope);
zohoConfig.setItemValue("zoho.scope", scope);
}
String accessToken = tokenResponse.getAccess_token();
if (accessToken != null && !accessToken.isEmpty()) {
logger.info("│ ├── accessToken=" + accessToken);
logger.fine("│ ├── accessToken=" + accessToken);
zohoConfig.setItemValue("zoho.accessToken", accessToken);
}
String refreshToken = tokenResponse.getRefresh_token();
if (refreshToken != null && !refreshToken.isEmpty()) {
logger.info("│ ├── refreshToken=" + refreshToken);
logger.fine("│ ├── refreshToken=" + refreshToken);
zohoConfig.setItemValue("zoho.refreshToken", refreshToken);
}
logger.info("│ ├── expires_in=" + tokenResponse.getExpires_in());
logger.fine("│ ├── expires_in=" + tokenResponse.getExpires_in());
// Expires-Zeit in Millisekunden berechnen
long expiresInSeconds = tokenResponse.getExpires_in() - 60;
long currentTimeMillis = System.currentTimeMillis();
long expiresTimeMillis = currentTimeMillis + (expiresInSeconds * 1000);
// Expires-Zeit in ein Date-Objekt konvertieren
Date expiresDate = new Date(expiresTimeMillis);
logger.info("│ ├── expire date=" + expiresDate);
logger.fine("│ ├── expire date=" + expiresDate);
zohoConfig.setItemValue("zoho.expires", expiresDate);
zohoConfig.setItemValue("message", "Access Token OK");
configService.save(zohoConfig);

View file

@ -0,0 +1,39 @@
package com.alexanderlogistics.zoho.dto;
import jakarta.json.bind.annotation.JsonbProperty;
public class ZohoContactCreateResponse {
@JsonbProperty("code")
private int code;
@JsonbProperty("message")
private String message;
@JsonbProperty("contact")
private ZohoContact contact;
// 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 ZohoContact getContact() {
return contact;
}
public void setContact(ZohoContact contact) {
this.contact = contact;
}
}

View file

@ -4,7 +4,7 @@ import java.util.List;
import jakarta.json.bind.annotation.JsonbProperty;
public class ZohoContactsResponse {
public class ZohoContactFindResponse {
@JsonbProperty("code")
private int code;

View file

@ -131,6 +131,7 @@ th { font-weight: bold;}
<bpmn2:flowNodeRef>event_0zodvw</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>textAnnotation_QBZ00w</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_iUSXSg</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>event_07fo0g</bpmn2:flowNodeRef>
</bpmn2:lane>
<bpmn2:lane id="Lane_6" name="Bereich Team">
<bpmn2:flowNodeRef>Task_1</bpmn2:flowNodeRef>
@ -283,6 +284,7 @@ Bei Fragen wenden Sie sich bitte an info@imixs.com
<bpmn2:outgoing>SequenceFlow_39</bpmn2:outgoing>
<bpmn2:outgoing>SequenceFlow_22</bpmn2:outgoing>
<bpmn2:incoming>sequenceFlow_OttgXA</bpmn2:incoming>
<bpmn2:incoming>sequenceFlow_mdGzDQ</bpmn2:incoming>
</bpmn2:task>
<bpmn2:dataObject id="DataObject_2" name="Invoice Form">
<bpmn2:documentation id="Documentation_8"><![CDATA[<?xml version="1.0"?>
@ -872,9 +874,9 @@ Betrag: <itemvalue>invoice.total</itemvalue> <itemvalue>invoice.currency</itemva
</bpmn2:extensionElements>
<bpmn2:documentation id="Documentation_35"/>
<bpmn2:outputSet id="OutputSet_4" name="Output Set 3"/>
<bpmn2:signalEventDefinition id="SignalEventDefinition_8"/>
<bpmn2:outgoing>sequenceFlow_zhcE7Q</bpmn2:outgoing>
<bpmn2:outgoing>association_P36Fzw</bpmn2:outgoing>
<bpmn2:compensationEventDefinition id="compensationEventDefinition_M3jl8w"/>
</bpmn2:intermediateCatchEvent>
<bpmn2:task id="Task_8" imixs:processid="5910" name="Debt collection paid">
<bpmn2:extensionElements>
@ -1305,7 +1307,7 @@ Wiedervorlage wird um 7 bzw. 5 Tage erhöht</bpmn2:text>
<imixs:value><![CDATA[2]]></imixs:value>
</imixs:item>
<imixs:item name="keypublicresult" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
<imixs:value><![CDATA[1]]></imixs:value>
</imixs:item>
<imixs:item name="keylogdateformat" type="xs:string">
<imixs:value><![CDATA[2]]></imixs:value>
@ -1329,16 +1331,6 @@ Wiedervorlage wird um 7 bzw. 5 Tage erhöht</bpmn2:text>
<imixs:item name="keyupdateacl" type="xs:boolean">
<imixs:value>false</imixs:value>
</imixs:item>
<imixs:item name="txtbusinessrule" type="xs:string">
<imixs:value><![CDATA[var result={};
var refField="dbtr.mail";
result.isValid=true;
if ( ( workitem.get(refField) == null || ''==workitem.get(refField)[0]) ) {
result.isValid=false;
result.errorMessage='No email address has been recorded for this vendor yet. Please update it in the Creditor/Debitor Management.';
}]]></imixs:value>
</imixs:item>
<imixs:item name="namaddreadaccess" type="xs:string">
<imixs:value><![CDATA[{process:?:member}]]></imixs:value>
<imixs:value><![CDATA[{space:?:member}]]></imixs:value>
@ -1435,6 +1427,86 @@ result.isValid=true;
<bpmn2:association id="association_xVkeww" sourceRef="DataObject_2" targetRef="Task_1">
<bpmn2:documentation id="documentation_euQGuA"/>
</bpmn2:association>
<bpmn2:intermediateCatchEvent id="event_07fo0g" imixs:activityid="400" name="ZOHO Test">
<bpmn2:extensionElements>
<imixs:item name="keylogtimeformat" type="xs:string">
<imixs:value><![CDATA[2]]></imixs:value>
</imixs:item>
<imixs:item name="keyarchive" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="txtmailsubject" type="xs:string">
<imixs:value/>
</imixs:item>
<imixs:item name="keyaccessmode" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="keyscheduledactivity" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="rtfmailbody" type="xs:string">
<imixs:value/>
</imixs:item>
<imixs:item name="keymailreceiverfields" type="xs:string"/>
<imixs:item name="keyversion" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="keyaddwritefields" type="xs:string">
<imixs:value><![CDATA[process.manager]]></imixs:value>
<imixs:value><![CDATA[process.team]]></imixs:value>
<imixs:value><![CDATA[space.manager]]></imixs:value>
</imixs:item>
<imixs:item name="numnextactivityid" type="xs:int">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="keyfollowup" type="xs:string">
<imixs:value><![CDATA[2]]></imixs:value>
</imixs:item>
<imixs:item name="keypublicresult" type="xs:string">
<imixs:value><![CDATA[1]]></imixs:value>
</imixs:item>
<imixs:item name="keylogdateformat" type="xs:string">
<imixs:value><![CDATA[2]]></imixs:value>
</imixs:item>
<imixs:item name="keyownershipfields" type="xs:string"/>
<imixs:item name="numnextid" type="xs:int">
<imixs:value><![CDATA[5005]]></imixs:value>
</imixs:item>
<imixs:item name="txtnextprocesstree" type="xs:string">
<imixs:value/>
</imixs:item>
<imixs:item name="txtname" type="xs:string">
<imixs:value><![CDATA[Freigabe einholen]]></imixs:value>
</imixs:item>
<imixs:item name="keyownershipmode" type="xs:string">
<imixs:value><![CDATA[0]]></imixs:value>
</imixs:item>
<imixs:item name="rtfresultlog" type="xs:string">
<imixs:value><![CDATA[Zoho export]]></imixs:value>
</imixs:item>
<imixs:item name="keyupdateacl" type="xs:boolean">
<imixs:value>false</imixs:value>
</imixs:item>
<imixs:item name="namaddreadaccess" type="xs:string">
<imixs:value><![CDATA[{process:?:member}]]></imixs:value>
<imixs:value><![CDATA[{space:?:member}]]></imixs:value>
</imixs:item>
<imixs:item name="keyaddreadfields" type="xs:string"/>
</bpmn2:extensionElements>
<bpmn2:documentation id="documentation_WC7jtA"/>
<bpmn2:dataOutput id="dataOutput_B0vRwQ" name="Signal_2_Output"/>
<bpmn2:dataOutputAssociation id="dataOutputAssociation_VdUGcQ">
<bpmn2:sourceRef>DataOutput_1</bpmn2:sourceRef>
</bpmn2:dataOutputAssociation>
<bpmn2:outputSet id="outputSet_b1tCbA" name="Output Set 2">
<bpmn2:dataOutputRefs>DataOutput_1</bpmn2:dataOutputRefs>
</bpmn2:outputSet>
<bpmn2:signalEventDefinition id="signalEventDefinition_h50HrA" signalRef="signal_8"/>
<bpmn2:outgoing>sequenceFlow_mdGzDQ</bpmn2:outgoing>
</bpmn2:intermediateCatchEvent>
<bpmn2:sequenceFlow id="sequenceFlow_mdGzDQ" sourceRef="event_07fo0g" targetRef="Task_2">
<bpmn2:documentation id="documentation_NV1xfg"/>
</bpmn2:sequenceFlow>
</bpmn2:process>
<bpmn2:process id="process_2" name="Default Process" processType="Public">
<bpmn2:documentation id="documentation_J67Rkw"/>
@ -1800,14 +1872,14 @@ result.isValid=true;
<di:waypoint x="1317.0" y="215.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_zhcE7Q" id="BPMNEdge_oQt4SA" sourceElement="BPMNShape_IntermediateCatchEvent_8" targetElement="BPMNShape_Task_3">
<di:waypoint x="690.0" y="818.0"/>
<di:waypoint x="690.0" y="805.0"/>
<di:waypoint x="695.0" y="817.0"/>
<di:waypoint x="695.0" y="805.0"/>
<di:waypoint x="710.0" y="805.0"/>
<di:waypoint x="710.0" y="780.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="association_P36Fzw" id="BPMNEdge_QtxjNQ" sourceElement="BPMNShape_IntermediateCatchEvent_8" targetElement="BPMNShape_TextAnnotation_3">
<di:waypoint x="678.0" y="840.0"/>
<di:waypoint x="575.0" y="840.0"/>
<di:waypoint x="677.0" y="835.0"/>
<di:waypoint x="575.0" y="835.0"/>
<di:waypoint x="575.0" y="920.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="task_LqbtSQ" id="BPMNShape_PXTHfw">
@ -1895,6 +1967,18 @@ result.isValid=true;
<di:waypoint x="648.0" y="755.0"/>
<di:waypoint x="690.0" y="755.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape bpmnElement="event_07fo0g" id="BPMNShape_i8omwg">
<dc:Bounds height="36.0" width="36.0" x="797.0" y="397.0"/>
<bpmndi:BPMNLabel id="BPMNLabel_i9tvtw">
<dc:Bounds height="20.0" width="100.0" x="765.0" y="436.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sequenceFlow_mdGzDQ" id="BPMNEdge_VUfhzg" sourceElement="BPMNShape_i8omwg" targetElement="BPMNShape_Task_5">
<di:waypoint x="815.0" y="397.0"/>
<di:waypoint x="815.0" y="364.0"/>
<di:waypoint x="775.0" y="364.0"/>
<di:waypoint x="775.0" y="330.0"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
<bpmndi:BPMNLabelStyle id="BPMNLabelStyle_1">
<dc:Font name="arial" size="9.0"/>