zoho expense export
This commit is contained in:
parent
4b9da4d98a
commit
d47518224f
16 changed files with 906 additions and 105 deletions
|
|
@ -18,7 +18,7 @@ Base API URI= https://accounts.zoho.eu/
|
||||||
|
|
||||||
## 1. Client Einrichten
|
## 1. Client Einrichten
|
||||||
|
|
||||||
https://api-console.zoho.eu/client/1000.NLTM2KUEHI696MSLGEIANATVGGX7IN
|
https://api-console.zoho.eu/
|
||||||
|
|
||||||
## 2. Generating Grant Token
|
## 2. Generating Grant Token
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,60 @@ zoho.scope ZohoBooks.contacts.ALL ZohoBooks.invoices.CREATE ZohoBooks.i
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Forum
|
||||||
|
|
||||||
|
form@imixs.com
|
||||||
|
imixs4zoho
|
||||||
|
|
||||||
|
https://api-console.zoho.eu/
|
||||||
|
|
||||||
|
ZohoBooks.contacts.ALL,ZohoBooks.invoices.ALL,ZohoBooks.bills.ALL
|
||||||
|
|
||||||
|
```
|
||||||
|
zoho.accesstoken 1.....3
|
||||||
|
zoho.apidomain https://www.zohoapis.eu
|
||||||
|
zoho.clientid 1000.5SMVXH92JIA5BTIGJF27OY41TAFFAS
|
||||||
|
zoho.clientsecret 64aabb5e819757e471c9d0dff6a072b1bcf2c7687d
|
||||||
|
zoho.code 10-
|
||||||
|
zoho.organization 886888983
|
||||||
|
zoho.refreshtoken 10...ff440e
|
||||||
|
zoho.scope ZohoBooks.contacts.ALL ZohoBooks.invoices.CREATE ZohoBooks.invoices.READ ZohoBooks.invoices.UPDATE
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Atari
|
||||||
|
|
||||||
|
atari.600xl@gmail.com
|
||||||
|
800xlAtari
|
||||||
|
|
||||||
|
```
|
||||||
|
zoho.apidomain https://www.zohoapis.eu
|
||||||
|
zoho.clientid 1000.86O4P321HDYDRX0Q0N1G7YOJRJ9D5W
|
||||||
|
zoho.clientsecret 2a67b6cfc364f5df27cc8eb33e9b0e4e8a0221ebc3
|
||||||
|
zoho.code 1000.c7dc89c06111b93f1242b587fabed4ac.44c591dffbd978a316e3d90ed3fefc78
|
||||||
|
zoho.organization 886924765
|
||||||
|
zoho.scope ZohoBooks.contacts.ALL,ZohoBooks.invoices.ALL,ZohoBooks.bills.ALL
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prod DWC
|
||||||
|
|
||||||
|
info@imixs.com
|
||||||
|
imixs4zoho
|
||||||
|
|
||||||
|
https://api-console.zoho.com/
|
||||||
|
|
||||||
|
ZohoBooks.contacts.ALL,ZohoBooks.invoices.ALL,ZohoBooks.bills.ALL
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
zoho.apidomain https://www.zohoapis.com
|
||||||
|
zoho.clientid 1000.MQE1SU8UGY6F2PBPASOXGTLWYQD1FS
|
||||||
|
zoho.clientsecret 1ca70e1ab803b3fed6b1b5e00858c316e2003d289b
|
||||||
|
zoho.organization 884218508
|
||||||
|
zoho.scope ZohoBooks.contacts.ALL,ZohoBooks.invoices.ALL,ZohoBooks.bills.ALL
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
# API Dokumentation
|
# API Dokumentation
|
||||||
|
|
||||||
- API Docu: https://www.zoho.com/books/api/v3/introduction/
|
- API Docu: https://www.zoho.com/books/api/v3/introduction/
|
||||||
|
|
|
||||||
167
doc/zoho/bill-create-example.json
Normal file
167
doc/zoho/bill-create-example.json
Normal file
|
|
@ -0,0 +1,167 @@
|
||||||
|
{
|
||||||
|
"code": 0,
|
||||||
|
"message": "The bill has been created.",
|
||||||
|
"bill": {
|
||||||
|
"bill_id": "6206847000000103003",
|
||||||
|
"vendor_id": "6206847000000100015",
|
||||||
|
"vendor_name": "Feldmuehle GmbH",
|
||||||
|
"source": "Api",
|
||||||
|
"contact_category": "",
|
||||||
|
"tax_treatment": "",
|
||||||
|
"unused_credits_payable_amount": 0.00,
|
||||||
|
"status": "paid",
|
||||||
|
"color_code": "",
|
||||||
|
"current_sub_status_id": "",
|
||||||
|
"current_sub_status": "paid",
|
||||||
|
"sub_statuses": [],
|
||||||
|
"bill_number": "28195",
|
||||||
|
"date": "2024-07-26",
|
||||||
|
"due_date": "2024-07-26",
|
||||||
|
"discount_setting": "flat",
|
||||||
|
"tds_calculation_type": "tds_item_level",
|
||||||
|
"payment_terms": 0,
|
||||||
|
"payment_terms_label": "Due on Receipt",
|
||||||
|
"payment_expected_date": "",
|
||||||
|
"reference_number": "",
|
||||||
|
"scanned_po_number": "",
|
||||||
|
"recurring_bill_id": "",
|
||||||
|
"due_by_days": 286,
|
||||||
|
"due_in_days": "",
|
||||||
|
"currency_id": "6206847000000000109",
|
||||||
|
"currency_code": "EUR",
|
||||||
|
"currency_symbol": "€",
|
||||||
|
"currency_name_formatted": "EUR- Euro",
|
||||||
|
"documents": [],
|
||||||
|
"subject_content": "",
|
||||||
|
"price_precision": 2,
|
||||||
|
"exchange_rate": 1.00,
|
||||||
|
"custom_fields": [],
|
||||||
|
"custom_field_hash": {},
|
||||||
|
"is_viewed_by_client": false,
|
||||||
|
"client_viewed_time": "",
|
||||||
|
"is_item_level_tax_calc": false,
|
||||||
|
"is_inclusive_tax": false,
|
||||||
|
"tax_rounding": "entity_level",
|
||||||
|
"is_uber_bill": false,
|
||||||
|
"is_tally_bill": false,
|
||||||
|
"track_discount_in_account": true,
|
||||||
|
"is_bill_reconciliation_violated": false,
|
||||||
|
"bill_order_type": "",
|
||||||
|
"line_items": [
|
||||||
|
{
|
||||||
|
"purchaseorder_id": "",
|
||||||
|
"purchaseorder_item_id": "",
|
||||||
|
"receive_id": "",
|
||||||
|
"line_item_id": "6206847000000103013",
|
||||||
|
"item_id": "",
|
||||||
|
"name": "AB-DEFGHI-1234-567",
|
||||||
|
"account_id": "6206847000000092271",
|
||||||
|
"account_name": "TEst",
|
||||||
|
"description": "",
|
||||||
|
"bcy_rate": 0.00,
|
||||||
|
"rate": 0.00,
|
||||||
|
"sales_rate": "",
|
||||||
|
"pricebook_id": "",
|
||||||
|
"header_id": "",
|
||||||
|
"header_name": "",
|
||||||
|
"tags": [],
|
||||||
|
"quantity": 1.00,
|
||||||
|
"discount": 0.00,
|
||||||
|
"discounts": [],
|
||||||
|
"discount_account_id": "",
|
||||||
|
"discount_account_name": "",
|
||||||
|
"markup_percent": 0.00,
|
||||||
|
"tax_id": "",
|
||||||
|
"tax_name": "",
|
||||||
|
"tax_type": "tax",
|
||||||
|
"tax_percentage": 0,
|
||||||
|
"line_item_taxes": [],
|
||||||
|
"item_total": 0.00,
|
||||||
|
"item_order": 1,
|
||||||
|
"unit": "",
|
||||||
|
"item_type": "",
|
||||||
|
"image_name": "",
|
||||||
|
"image_type": "",
|
||||||
|
"is_billable": false,
|
||||||
|
"customer_id": "",
|
||||||
|
"receipt_line_item_id": "",
|
||||||
|
"customer_name": "",
|
||||||
|
"project_id": "",
|
||||||
|
"project_name": "",
|
||||||
|
"invoice_id": "",
|
||||||
|
"invoice_number": "",
|
||||||
|
"item_custom_fields": [],
|
||||||
|
"purchase_request_items": [],
|
||||||
|
"item_matching_type": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"submitted_date": "",
|
||||||
|
"submitted_by": "",
|
||||||
|
"submitted_by_name": "",
|
||||||
|
"submitted_by_email": "",
|
||||||
|
"submitted_by_photo_url": "",
|
||||||
|
"submitter_id": "",
|
||||||
|
"approver_id": "",
|
||||||
|
"adjustment": 0.00,
|
||||||
|
"adjustment_description": "",
|
||||||
|
"discount_amount": 0.00,
|
||||||
|
"discount": 0.00,
|
||||||
|
"discount_applied_on_amount": 0.00,
|
||||||
|
"is_discount_before_tax": true,
|
||||||
|
"discount_account_id": "",
|
||||||
|
"discount_account_name": "",
|
||||||
|
"discount_type": "entity_level",
|
||||||
|
"sub_total": 0.00,
|
||||||
|
"sub_total_inclusive_of_tax": 0.00,
|
||||||
|
"tax_total": 0.00,
|
||||||
|
"discount_total": 0.00,
|
||||||
|
"discount_percent": 0.00,
|
||||||
|
"total": 0.00,
|
||||||
|
"payment_made": 0.00,
|
||||||
|
"vendor_credits_applied": 0.00,
|
||||||
|
"is_line_item_invoiced": false,
|
||||||
|
"purchaseorders": [],
|
||||||
|
"taxes": [],
|
||||||
|
"computation_type": "basic",
|
||||||
|
"tax_override_preference": "no_override",
|
||||||
|
"tds_override_preference": "no_override",
|
||||||
|
"balance": 0.00,
|
||||||
|
"unprocessed_payment_amount": 0.00,
|
||||||
|
"billing_address_id": "6206847000000100017",
|
||||||
|
"billing_address": {
|
||||||
|
"address": "",
|
||||||
|
"street2": "",
|
||||||
|
"city": "",
|
||||||
|
"state": "",
|
||||||
|
"zip": "",
|
||||||
|
"country": "",
|
||||||
|
"fax": "",
|
||||||
|
"phone": "",
|
||||||
|
"attention": ""
|
||||||
|
},
|
||||||
|
"payments": [],
|
||||||
|
"vendor_credits": [],
|
||||||
|
"created_time": "2025-05-08T21:36:04+0100",
|
||||||
|
"created_by_id": "6206847000000092001",
|
||||||
|
"last_modified_id": "6206847000000092001",
|
||||||
|
"last_modified_time": "2025-05-08T21:36:04+0100",
|
||||||
|
"reference_id": "",
|
||||||
|
"notes": "",
|
||||||
|
"terms": "",
|
||||||
|
"attachment_name": "",
|
||||||
|
"template_id": "6206847000000031017",
|
||||||
|
"template_name": "Standard Template",
|
||||||
|
"page_width": "8.27in",
|
||||||
|
"page_height": "11.69in",
|
||||||
|
"orientation": "portrait",
|
||||||
|
"template_type": "standard",
|
||||||
|
"is_approval_required": false,
|
||||||
|
"allocated_landed_costs": [],
|
||||||
|
"unallocated_landed_costs": [],
|
||||||
|
"entity_type": "bill",
|
||||||
|
"total_retention_amount": 0.00,
|
||||||
|
"retention_items": [],
|
||||||
|
"can_send_in_mail": false,
|
||||||
|
"approvers_list": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -21,9 +21,15 @@ import org.imixs.workflow.ItemCollection;
|
||||||
import org.imixs.workflow.exceptions.PluginException;
|
import org.imixs.workflow.exceptions.PluginException;
|
||||||
|
|
||||||
import com.alexanderlogistics.InvoiceUtil;
|
import com.alexanderlogistics.InvoiceUtil;
|
||||||
|
import com.alexanderlogistics.zoho.dto.ZohoBill;
|
||||||
|
import com.alexanderlogistics.zoho.dto.ZohoBillCreateResponse;
|
||||||
|
import com.alexanderlogistics.zoho.dto.ZohoBillItem;
|
||||||
import com.alexanderlogistics.zoho.dto.ZohoContact;
|
import com.alexanderlogistics.zoho.dto.ZohoContact;
|
||||||
import com.alexanderlogistics.zoho.dto.ZohoContactCreateResponse;
|
import com.alexanderlogistics.zoho.dto.ZohoContactCreateResponse;
|
||||||
import com.alexanderlogistics.zoho.dto.ZohoContactFindResponse;
|
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.ZohoInvoice;
|
||||||
import com.alexanderlogistics.zoho.dto.ZohoInvoiceCreateResponse;
|
import com.alexanderlogistics.zoho.dto.ZohoInvoiceCreateResponse;
|
||||||
import com.alexanderlogistics.zoho.dto.ZohoInvoiceItem;
|
import com.alexanderlogistics.zoho.dto.ZohoInvoiceItem;
|
||||||
|
|
@ -53,12 +59,12 @@ public class ZohoAPIService {
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(ZohoAPIService.class.getName());
|
private static Logger logger = Logger.getLogger(ZohoAPIService.class.getName());
|
||||||
|
|
||||||
@Inject
|
|
||||||
ZohoOAuthManager zohoOAuthManager;
|
|
||||||
|
|
||||||
private HttpClient httpClient;
|
private HttpClient httpClient;
|
||||||
private Jsonb jsonb;
|
private Jsonb jsonb;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ZohoOAuthManager zohoOAuthManager;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
void init() {
|
void init() {
|
||||||
this.httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
|
this.httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
|
||||||
|
|
@ -68,10 +74,11 @@ public class ZohoAPIService {
|
||||||
this.jsonb = JsonbBuilder.create(config);
|
this.jsonb = JsonbBuilder.create(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String findContactIDByCompanyName(String companyName, String accessToken) throws PluginException {
|
public String findContactIDByCompanyName(String companyName, String contactType, String accessToken)
|
||||||
|
throws PluginException {
|
||||||
|
|
||||||
// Print JSON to console for verification
|
// Print JSON to console for verification
|
||||||
logger.info("├── Zoho lookup contact '" + companyName + "'...");
|
logger.info("├── Zoho lookup contact (" + contactType + ") '" + companyName + "'...");
|
||||||
try {
|
try {
|
||||||
// https://www.zohoapis.com/books/v3/contacts?organization_id=10234695&company_name=xxx'
|
// https://www.zohoapis.com/books/v3/contacts?organization_id=10234695&company_name=xxx'
|
||||||
String uri = zohoOAuthManager.getBaseURI() + "contacts?organization_id="
|
String uri = zohoOAuthManager.getBaseURI() + "contacts?organization_id="
|
||||||
|
|
@ -83,7 +90,9 @@ public class ZohoAPIService {
|
||||||
.header("Authorization", "Zoho-oauthtoken " + accessToken)
|
.header("Authorization", "Zoho-oauthtoken " + accessToken)
|
||||||
.header("Content-Type", "application/json").GET().build();
|
.header("Content-Type", "application/json").GET().build();
|
||||||
|
|
||||||
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
HttpResponse<String> response;
|
||||||
|
|
||||||
|
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
|
||||||
// Print response details to console
|
// Print response details to console
|
||||||
logger.fine("├── Zoho Response:");
|
logger.fine("├── Zoho Response:");
|
||||||
|
|
@ -100,16 +109,18 @@ public class ZohoAPIService {
|
||||||
if (contactsResponse != null && contactsResponse.getContacts() != null) {
|
if (contactsResponse != null && contactsResponse.getContacts() != null) {
|
||||||
// Durchsuche die Ergebnisse nach exakter Übereinstimmung
|
// Durchsuche die Ergebnisse nach exakter Übereinstimmung
|
||||||
for (ZohoContact contact : contactsResponse.getContacts()) {
|
for (ZohoContact contact : contactsResponse.getContacts()) {
|
||||||
if (companyName.equalsIgnoreCase(contact.getCompanyName())) {
|
if (companyName.equalsIgnoreCase(contact.getCompanyName())
|
||||||
|
&& contactType.equalsIgnoreCase((contact.getContactType()))) {
|
||||||
logger.info("│ ├── contactID= " + contact.getContactId());
|
logger.info("│ ├── contactID= " + contact.getContactId());
|
||||||
return contact.getContactId();
|
return contact.getContactId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
} catch (IOException | InterruptedException e) {
|
||||||
} catch (Exception e) {
|
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
||||||
throw new PluginException(this.getClass().getName(), "Zoho API error", "Failed to find contacts", e);
|
"Failed to find Contacts: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,21 +132,12 @@ public class ZohoAPIService {
|
||||||
* @param invoice
|
* @param invoice
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
public ZohoInvoice exportInvoice(ItemCollection invoice, List<FileData> files) throws PluginException {
|
public ZohoInvoice exportInvoice(ItemCollection invoice, String contactID, String accessToken)
|
||||||
String accessToken = zohoOAuthManager.getValidAccessToken();
|
throws PluginException {
|
||||||
logger.info("├── Zoho Export Invoice " + invoice.getItemValueString("invoice.number") + "...");
|
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
|
// Konvertiere ItemCollection zu ZohoInvoiceDTO
|
||||||
ZohoInvoice zohoInvoice = convertToZohoInvoice(invoice, contactID, accessToken);
|
ZohoInvoice zohoInvoice = convertToZohoInvoice(invoice, contactID);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String requestBody = jsonb.toJson(zohoInvoice);
|
String requestBody = jsonb.toJson(zohoInvoice);
|
||||||
|
|
@ -173,52 +175,193 @@ public class ZohoAPIService {
|
||||||
System.out.print(bodyContent);
|
System.out.print(bodyContent);
|
||||||
ZohoInvoiceCreateResponse createResponse = jsonb.fromJson(bodyContent, ZohoInvoiceCreateResponse.class);
|
ZohoInvoiceCreateResponse createResponse = jsonb.fromJson(bodyContent, ZohoInvoiceCreateResponse.class);
|
||||||
|
|
||||||
logger.fine("│ ├── OK - customerID=" + createResponse.getInvoice().getCustomerId());
|
|
||||||
logger.info("│ ├── OK - invoiceID=" + createResponse.getInvoice().getInvoiceId());
|
|
||||||
|
|
||||||
if (createResponse != null) {
|
if (createResponse != null) {
|
||||||
|
logger.fine("│ ├── OK - customerID=" + createResponse.getInvoice().getCustomerId());
|
||||||
|
logger.info("│ ├── OK - invoiceID=" + createResponse.getInvoice().getInvoiceId());
|
||||||
zohoInvoice = createResponse.getInvoice();
|
zohoInvoice = createResponse.getInvoice();
|
||||||
|
|
||||||
// now add attachments (optional)
|
// now mark the invoice as send
|
||||||
try {
|
markInvoiceAsSend(zohoInvoice.getInvoiceId(), "invoices", accessToken);
|
||||||
if (files != null) {
|
|
||||||
for (FileData file : files) {
|
|
||||||
attacheFileData(zohoInvoice.getInvoiceId(), file, "invoices", accessToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// now mark the invoice as send
|
|
||||||
markInvoiceAsSend(zohoInvoice.getInvoiceId(), "invoices", accessToken);
|
|
||||||
} catch (PluginException e) {
|
|
||||||
logger.warning("Failed to export Invoice: " + e.getMessage());
|
|
||||||
}
|
|
||||||
logger.info("│ ├── Invoice Export successful.");
|
logger.info("│ ├── Invoice Export successful.");
|
||||||
return zohoInvoice;
|
return zohoInvoice;
|
||||||
} else {
|
|
||||||
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
|
||||||
"Failed to export invoice to Zoho: unable to resolve response");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException | InterruptedException e) {
|
} catch (IOException | InterruptedException e) {
|
||||||
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
||||||
"Failed to export invoice to Zoho: " + e.getMessage(), e);
|
"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 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<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 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 {
|
||||||
|
logger.info("├── Zoho Export Bill " + invoice.getItemValueString("invoice.number") + "...");
|
||||||
|
|
||||||
|
// Konvertiere ItemCollection zu ZohoInvoiceDTO
|
||||||
|
ZohoBill zohoBill = convertToZohoBill(invoice, contactID, accountID);
|
||||||
|
|
||||||
|
try {
|
||||||
|
String requestBody = jsonb.toJson(zohoBill);
|
||||||
|
|
||||||
|
// Print JSON to console for verification
|
||||||
|
logger.fine("├── Zoho Bill JSON Request...");
|
||||||
|
logger.fine("│ ├── " + requestBody);
|
||||||
|
|
||||||
|
// https://www.zohoapis.com/books/v3/expenses?organization_id=10234695'
|
||||||
|
String uri = zohoOAuthManager.getBaseURI() + "bills?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 expense. Status code: " + response.statusCode() + ", Response: "
|
||||||
|
+ response.body());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erfolgreiche Erstellung
|
||||||
|
String bodyContent = response.body();
|
||||||
|
logger.fine("│ ├── Response Body: " + bodyContent);
|
||||||
|
|
||||||
|
System.out.print(bodyContent);
|
||||||
|
ZohoBillCreateResponse createResponse = jsonb.fromJson(bodyContent, ZohoBillCreateResponse.class);
|
||||||
|
|
||||||
|
if (createResponse != null) {
|
||||||
|
logger.info("│ ├── OK - customerID=" + createResponse.getBill().getVendorId());
|
||||||
|
logger.info("│ ├── OK - billID=" + createResponse.getBill().getBillId());
|
||||||
|
zohoBill = createResponse.getBill();
|
||||||
|
|
||||||
|
// now mark the invoice as send
|
||||||
|
logger.info("│ ├── Bill Export successful.");
|
||||||
|
return zohoBill;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException | InterruptedException e) {
|
||||||
|
throw new PluginException(this.getClass().getName(), "Zoho API error",
|
||||||
|
"Failed to export bill to Zoho: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String lookupContact(String companyName, String contactType, String accessToken) throws PluginException {
|
||||||
|
// first lookup contact!
|
||||||
|
String contactID = "";
|
||||||
|
contactID = findContactIDByCompanyName(companyName, contactType, accessToken);
|
||||||
|
if (contactID == null) {
|
||||||
|
logger.info("│ ├── contact '" + companyName + "' not found");
|
||||||
|
ZohoContact contact = createContact(companyName, contactType, accessToken);
|
||||||
|
contactID = contact.getContactId();
|
||||||
|
}
|
||||||
|
return contactID;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erstellt einen neuen Contact in Zoho Books
|
* Erstellt einen neuen Contact in Zoho Books
|
||||||
*
|
*
|
||||||
* @param companyName Der Firmenname für den neuen Contact
|
* @param companyName Der Firmenname für den neuen Contact
|
||||||
|
* @param contactType - customer/vendor
|
||||||
* @return Der erstellte ZohoContact mit contact_id
|
* @return Der erstellte ZohoContact mit contact_id
|
||||||
* @throws PluginException Wenn der API-Aufruf fehlschlägt
|
* @throws PluginException Wenn der API-Aufruf fehlschlägt
|
||||||
*/
|
*/
|
||||||
public ZohoContact createContact(String companyName, String accessToken) throws PluginException {
|
public ZohoContact createContact(String companyName, String contactType, String accessToken)
|
||||||
|
throws PluginException {
|
||||||
logger.info("├── Zoho create contact '" + companyName + "'...");
|
logger.info("├── Zoho create contact '" + companyName + "'...");
|
||||||
try {
|
try {
|
||||||
// Contact-DTO vorbereiten
|
// Contact-DTO vorbereiten
|
||||||
ZohoContact newContact = new ZohoContact();
|
ZohoContact newContact = new ZohoContact();
|
||||||
newContact.setContactName(companyName); // Wir verwenden den Firmennamen auch als Contact Name
|
newContact.setContactName(companyName); // Wir verwenden den Firmennamen auch als Contact Name
|
||||||
newContact.setCompanyName(companyName);
|
newContact.setCompanyName(companyName);
|
||||||
|
newContact.setContactType(contactType);
|
||||||
|
|
||||||
// JSON serialisieren
|
// JSON serialisieren
|
||||||
String requestBody = jsonb.toJson(newContact);
|
String requestBody = jsonb.toJson(newContact);
|
||||||
|
|
@ -258,8 +401,7 @@ public class ZohoAPIService {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ZohoInvoice convertToZohoInvoice(ItemCollection invoice, String contactID, String accessToken)
|
private ZohoInvoice convertToZohoInvoice(ItemCollection invoice, String contactID) throws PluginException {
|
||||||
throws PluginException {
|
|
||||||
|
|
||||||
ZohoInvoice zohoInvoice = new ZohoInvoice();
|
ZohoInvoice zohoInvoice = new ZohoInvoice();
|
||||||
// Basisinformationen
|
// Basisinformationen
|
||||||
|
|
@ -290,6 +432,65 @@ public class ZohoAPIService {
|
||||||
return zohoInvoice;
|
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<ItemCollection> positionen = InvoiceUtil.explodeChildList(invoice);
|
||||||
|
// {amount=[11825.00], total=[11825.00], numpos=[1], name=[AB-DEFGHI-1234-567],
|
||||||
|
// tax=[0], category=[STORAGE], invoice.period=[]}
|
||||||
|
List<ZohoExpenseItem> 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)
|
||||||
|
throws PluginException {
|
||||||
|
|
||||||
|
ZohoBill zohoBill = new ZohoBill();
|
||||||
|
// Basisinformationen
|
||||||
|
|
||||||
|
zohoBill.setInvoiceNumber(invoice.getItemValueString("invoice.number"));
|
||||||
|
zohoBill.setDate(
|
||||||
|
LocalDate.ofInstant(invoice.getItemValueDate("invoice.date").toInstant(), ZoneId.systemDefault()));
|
||||||
|
|
||||||
|
zohoBill.setAmount(invoice.getItemValueDouble("invoice.total"));
|
||||||
|
// Kunden-ID (muss angepasst werden je nachdem wie du sie speicherst)
|
||||||
|
zohoBill.setVendorId(contactID);
|
||||||
|
// zohoBill.setPaid_through_account_id("1700");
|
||||||
|
List<ItemCollection> positionen = InvoiceUtil.explodeChildList(invoice);
|
||||||
|
// {amount=[11825.00], total=[11825.00], numpos=[1], name=[AB-DEFGHI-1234-567],
|
||||||
|
// tax=[0], category=[STORAGE], invoice.period=[]}
|
||||||
|
List<ZohoBillItem> lineItems = positionen.stream().map(item -> {
|
||||||
|
ItemCollection itemCol = (ItemCollection) item;
|
||||||
|
ZohoBillItem lineItem = new ZohoBillItem();
|
||||||
|
lineItem.setName(itemCol.getItemValueString("name"));
|
||||||
|
lineItem.setAccountId(accountID);
|
||||||
|
lineItem.setAmount(itemCol.getItemValueDouble("amount"));
|
||||||
|
|
||||||
|
return lineItem;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
zohoBill.setLineItems(lineItems);
|
||||||
|
return zohoBill;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method adds an attachment to an invoice
|
* This method adds an attachment to an invoice
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import java.util.logging.Logger;
|
||||||
import org.imixs.workflow.exceptions.PluginException;
|
import org.imixs.workflow.exceptions.PluginException;
|
||||||
import org.imixs.workflow.office.config.ConfigController;
|
import org.imixs.workflow.office.config.ConfigController;
|
||||||
|
|
||||||
import jakarta.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ConversationScoped;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.inject.Named;
|
import jakarta.inject.Named;
|
||||||
|
|
||||||
|
|
@ -42,7 +42,8 @@ import jakarta.inject.Named;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Named("zohoController")
|
@Named("zohoController")
|
||||||
@ApplicationScoped
|
// @ApplicationScoped
|
||||||
|
@ConversationScoped
|
||||||
public class ZohoController extends ConfigController {
|
public class ZohoController extends ConfigController {
|
||||||
|
|
||||||
public static final String ZOHO_CONFIGURATION = "ZOHO_CONFIGURATION";
|
public static final String ZOHO_CONFIGURATION = "ZOHO_CONFIGURATION";
|
||||||
|
|
@ -64,7 +65,7 @@ public class ZohoController extends ConfigController {
|
||||||
public void updateAccessToken() {
|
public void updateAccessToken() {
|
||||||
//
|
//
|
||||||
try {
|
try {
|
||||||
zohoOAuthManager.updateTokens(this.getWorkitem().getItemValueString("zoho.code"));
|
zohoOAuthManager.updateTokens(this.getWorkitem());
|
||||||
} catch (PluginException e) {
|
} catch (PluginException e) {
|
||||||
String message = "Failed to generate token: " + e.getMessage();
|
String message = "Failed to generate token: " + e.getMessage();
|
||||||
logger.warning(message);
|
logger.warning(message);
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import org.imixs.workflow.engine.WorkflowService;
|
||||||
import org.imixs.workflow.exceptions.AdapterException;
|
import org.imixs.workflow.exceptions.AdapterException;
|
||||||
import org.imixs.workflow.exceptions.PluginException;
|
import org.imixs.workflow.exceptions.PluginException;
|
||||||
|
|
||||||
|
import com.alexanderlogistics.zoho.dto.ZohoBill;
|
||||||
import com.alexanderlogistics.zoho.dto.ZohoInvoice;
|
import com.alexanderlogistics.zoho.dto.ZohoInvoice;
|
||||||
|
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
|
|
@ -37,6 +38,8 @@ public class ZohoExportAdapter implements SignalAdapter {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SnapshotService snapshotService;
|
SnapshotService snapshotService;
|
||||||
|
@Inject
|
||||||
|
ZohoOAuthManager zohoOAuthManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@ConfigProperty(name = ENV_ZOHO_EXPORT_MAX_ATTACHMENT_SIZE, defaultValue = "10485760")
|
@ConfigProperty(name = ENV_ZOHO_EXPORT_MAX_ATTACHMENT_SIZE, defaultValue = "10485760")
|
||||||
|
|
@ -50,21 +53,82 @@ public class ZohoExportAdapter implements SignalAdapter {
|
||||||
@Override
|
@Override
|
||||||
public ItemCollection execute(ItemCollection document, ItemCollection event)
|
public ItemCollection execute(ItemCollection document, ItemCollection event)
|
||||||
throws AdapterException, PluginException {
|
throws AdapterException, PluginException {
|
||||||
logger.info("├── Invoice Export");
|
|
||||||
|
|
||||||
// Load attachments
|
|
||||||
List<FileData> files = null;
|
|
||||||
ItemCollection snapshot = snapshotService.findSnapshot(document);
|
|
||||||
|
|
||||||
if (snapshot != null) {
|
|
||||||
files = snapshot.getFileData();
|
|
||||||
}
|
|
||||||
|
|
||||||
// read the cargosoft export options
|
// read the cargosoft export options
|
||||||
ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "zoho", document, false);
|
ItemCollection evalItemCollection = workflowService.evalWorkflowResult(event, "zoho", document, false);
|
||||||
|
|
||||||
ZohoInvoice zohoInvoice = zohoAPIService.exportInvoice(document, files);
|
// get access token
|
||||||
|
String accessToken = zohoOAuthManager.getValidAccessToken();
|
||||||
|
|
||||||
|
// Rechnungsausgang
|
||||||
|
if (document.getModelVersion().startsWith("rechnungsausgang-")) {
|
||||||
|
logger.info("├── Invoice Export");
|
||||||
|
exportRechnungsausgang(document, accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rechnungseingang
|
||||||
|
if (document.getModelVersion().startsWith("rechnungseingang-")) {
|
||||||
|
logger.info("├── Bill Export");
|
||||||
|
exportRechnungseingang(document, accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Help method, - finds/updates - contact, - export invoice, - change state,
|
||||||
|
* -attache files
|
||||||
|
*
|
||||||
|
* @param document
|
||||||
|
* @param accessToken
|
||||||
|
* @throws PluginException
|
||||||
|
*/
|
||||||
|
private void exportRechnungsausgang(ItemCollection document, String accessToken) throws PluginException {
|
||||||
|
// find companyID
|
||||||
|
String contactID = zohoAPIService.lookupContact(document.getItemValueString("dbtr.name"), "customer",
|
||||||
|
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) {
|
||||||
|
zohoAPIService.attacheFileData(zohoInvoice.getInvoiceId(), file, "invoices", accessToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Help method, - finds/updates - contact, - export invoice, - change state,
|
||||||
|
* -attache files
|
||||||
|
*
|
||||||
|
* @param document
|
||||||
|
* @param accessToken
|
||||||
|
* @throws PluginException
|
||||||
|
*/
|
||||||
|
private void exportRechnungseingang(ItemCollection document, String accessToken) throws PluginException {
|
||||||
|
// find companyID
|
||||||
|
String contactID = zohoAPIService.lookupContact(document.getItemValueString("cdtr.name"), "vendor",
|
||||||
|
accessToken);
|
||||||
|
|
||||||
|
String accountID = zohoOAuthManager.getAccountId();
|
||||||
|
|
||||||
|
ZohoBill zohoBill = zohoAPIService.exportBill(document, contactID, accountID, 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) {
|
||||||
|
zohoAPIService.attacheFileData(zohoBill.getBillId(), file, "bills", accessToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -85,6 +85,14 @@ public class ZohoOAuthManager {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAccountId() throws PluginException {
|
||||||
|
ItemCollection zohoConfig = configService.loadConfiguration(ZohoController.ZOHO_CONFIGURATION, false);
|
||||||
|
if (zohoConfig != null) {
|
||||||
|
return zohoConfig.getItemValueString("zoho.accountid");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public String getBaseURI() throws PluginException {
|
public String getBaseURI() throws PluginException {
|
||||||
String uri = "";
|
String uri = "";
|
||||||
ItemCollection zohoConfig = configService.loadConfiguration(ZohoController.ZOHO_CONFIGURATION, false);
|
ItemCollection zohoConfig = configService.loadConfiguration(ZohoController.ZOHO_CONFIGURATION, false);
|
||||||
|
|
@ -109,21 +117,27 @@ public class ZohoOAuthManager {
|
||||||
* @throws PluginException
|
* @throws PluginException
|
||||||
*/
|
*/
|
||||||
@Lock(LockType.WRITE)
|
@Lock(LockType.WRITE)
|
||||||
public void updateTokens(String code) throws PluginException {
|
public void updateTokens(ItemCollection zohoConfig) throws PluginException {
|
||||||
logger.info("├── update Zoho tokens");
|
logger.info("├── update Zoho tokens");
|
||||||
try {
|
try {
|
||||||
|
String code = zohoConfig.getItemValueString("zoho.code");
|
||||||
ItemCollection zohoConfig = configService.loadConfiguration(ZohoController.ZOHO_CONFIGURATION, false);
|
|
||||||
|
|
||||||
String clientID = zohoConfig.getItemValueString("zoho.clientid");
|
String clientID = zohoConfig.getItemValueString("zoho.clientid");
|
||||||
String clientSecret = zohoConfig.getItemValueString("zoho.clientsecret");
|
String clientSecret = zohoConfig.getItemValueString("zoho.clientsecret");
|
||||||
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" + "?code="
|
// String requestUrl = zohoConfig.getItemValueString("zoho.oauth.uri") +
|
||||||
|
// "?code="
|
||||||
|
// + URLEncoder.encode(code, StandardCharsets.UTF_8) + "&client_id="
|
||||||
|
// + URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
|
||||||
|
// + URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&redirect_uri="
|
||||||
|
// + URLEncoder.encode(redirectURI, StandardCharsets.UTF_8) +
|
||||||
|
// "&grant_type=authorization_code";
|
||||||
|
|
||||||
|
String requestUrl = zohoConfig.getItemValueString("zoho.oauth.uri") + "?code="
|
||||||
+ URLEncoder.encode(code, StandardCharsets.UTF_8) + "&client_id="
|
+ URLEncoder.encode(code, StandardCharsets.UTF_8) + "&client_id="
|
||||||
+ URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
|
+ URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
|
||||||
+ URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&redirect_uri="
|
+ URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&grant_type=authorization_code";
|
||||||
+ URLEncoder.encode(redirectURI, StandardCharsets.UTF_8) + "&grant_type=authorization_code";
|
|
||||||
|
|
||||||
logger.fine("│ ├── Request URI=" + requestUrl);
|
logger.info("│ ├── Request URI=" + requestUrl);
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(requestUrl))
|
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(requestUrl))
|
||||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
|
@ -133,10 +147,10 @@ public class ZohoOAuthManager {
|
||||||
HttpResponse<String> response;
|
HttpResponse<String> response;
|
||||||
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
|
||||||
logger.fine("│ ├── Response statusCode=" + response.statusCode());
|
logger.info("│ ├── Response statusCode=" + response.statusCode());
|
||||||
if (response.statusCode() == 200) {
|
if (response.statusCode() == 200) {
|
||||||
// 1. Response-Logging für Debugging
|
// 1. Response-Logging für Debugging
|
||||||
logger.fine("│ ├── Response Body=" + response.body());
|
logger.info("│ ├── Response Body=" + response.body());
|
||||||
|
|
||||||
if (response.body().contains("error")) {
|
if (response.body().contains("error")) {
|
||||||
throw new PluginException(ZohoOAuthManager.class.getSimpleName(), ZohoOAuthManager.ERROR_CONFIG,
|
throw new PluginException(ZohoOAuthManager.class.getSimpleName(), ZohoOAuthManager.ERROR_CONFIG,
|
||||||
|
|
@ -172,7 +186,7 @@ public class ZohoOAuthManager {
|
||||||
|
|
||||||
String refreshToken = zohoConfig.getItemValueString("zoho.refreshToken");
|
String refreshToken = zohoConfig.getItemValueString("zoho.refreshToken");
|
||||||
try {
|
try {
|
||||||
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" + "?refresh_token="
|
String requestUrl = zohoConfig.getItemValueString("zoho.oauth.uri") + "?refresh_token="
|
||||||
+ URLEncoder.encode(refreshToken, StandardCharsets.UTF_8) + "&client_id="
|
+ URLEncoder.encode(refreshToken, StandardCharsets.UTF_8) + "&client_id="
|
||||||
+ URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
|
+ URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
|
||||||
+ URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&grant_type=refresh_token";
|
+ URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&grant_type=refresh_token";
|
||||||
|
|
@ -218,33 +232,33 @@ public class ZohoOAuthManager {
|
||||||
|
|
||||||
String apiDomain = tokenResponse.getApi_domain();
|
String apiDomain = tokenResponse.getApi_domain();
|
||||||
if (apiDomain != null && !apiDomain.isEmpty()) {
|
if (apiDomain != null && !apiDomain.isEmpty()) {
|
||||||
logger.fine("│ ├── apiDomain=" + apiDomain);
|
logger.info("│ ├── apiDomain=" + apiDomain);
|
||||||
zohoConfig.setItemValue("zoho.apiDomain", apiDomain);
|
zohoConfig.setItemValue("zoho.apiDomain", apiDomain);
|
||||||
}
|
}
|
||||||
String scope = tokenResponse.getScope();
|
String scope = tokenResponse.getScope();
|
||||||
if (scope != null && !scope.isEmpty()) {
|
if (scope != null && !scope.isEmpty()) {
|
||||||
logger.fine("│ ├── scope=" + scope);
|
logger.info("│ ├── scope=" + scope);
|
||||||
zohoConfig.setItemValue("zoho.scope", scope);
|
zohoConfig.setItemValue("zoho.scope", scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
String accessToken = tokenResponse.getAccess_token();
|
String accessToken = tokenResponse.getAccess_token();
|
||||||
if (accessToken != null && !accessToken.isEmpty()) {
|
if (accessToken != null && !accessToken.isEmpty()) {
|
||||||
logger.fine("│ ├── accessToken=" + accessToken);
|
logger.info("│ ├── accessToken=" + accessToken);
|
||||||
zohoConfig.setItemValue("zoho.accessToken", accessToken);
|
zohoConfig.setItemValue("zoho.accessToken", accessToken);
|
||||||
}
|
}
|
||||||
String refreshToken = tokenResponse.getRefresh_token();
|
String refreshToken = tokenResponse.getRefresh_token();
|
||||||
if (refreshToken != null && !refreshToken.isEmpty()) {
|
if (refreshToken != null && !refreshToken.isEmpty()) {
|
||||||
logger.fine("│ ├── refreshToken=" + refreshToken);
|
logger.info("│ ├── refreshToken=" + refreshToken);
|
||||||
zohoConfig.setItemValue("zoho.refreshToken", refreshToken);
|
zohoConfig.setItemValue("zoho.refreshToken", refreshToken);
|
||||||
}
|
}
|
||||||
logger.fine("│ ├── expires_in=" + tokenResponse.getExpires_in());
|
logger.info("│ ├── expires_in=" + tokenResponse.getExpires_in());
|
||||||
// Expires-Zeit in Millisekunden berechnen
|
// Expires-Zeit in Millisekunden berechnen
|
||||||
long expiresInSeconds = tokenResponse.getExpires_in() - 60;
|
long expiresInSeconds = tokenResponse.getExpires_in() - 60;
|
||||||
long currentTimeMillis = System.currentTimeMillis();
|
long currentTimeMillis = System.currentTimeMillis();
|
||||||
long expiresTimeMillis = currentTimeMillis + (expiresInSeconds * 1000);
|
long expiresTimeMillis = currentTimeMillis + (expiresInSeconds * 1000);
|
||||||
// Expires-Zeit in ein Date-Objekt konvertieren
|
// Expires-Zeit in ein Date-Objekt konvertieren
|
||||||
Date expiresDate = new Date(expiresTimeMillis);
|
Date expiresDate = new Date(expiresTimeMillis);
|
||||||
logger.fine("│ ├── expire date=" + expiresDate);
|
logger.info("│ ├── expire date=" + expiresDate);
|
||||||
zohoConfig.setItemValue("zoho.expires", expiresDate);
|
zohoConfig.setItemValue("zoho.expires", expiresDate);
|
||||||
zohoConfig.setItemValue("message", "Access Token OK");
|
zohoConfig.setItemValue("message", "Access Token OK");
|
||||||
configService.save(zohoConfig);
|
configService.save(zohoConfig);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
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 ZohoBill {
|
||||||
|
|
||||||
|
@JsonbProperty("bill_id")
|
||||||
|
private String billId;
|
||||||
|
|
||||||
|
@JsonbProperty("vendor_id")
|
||||||
|
private String vendorId;
|
||||||
|
|
||||||
|
@JsonbDateFormat("yyyy-MM-dd")
|
||||||
|
private LocalDate date;
|
||||||
|
|
||||||
|
@JsonbProperty("due_date")
|
||||||
|
@JsonbDateFormat("yyyy-MM-dd")
|
||||||
|
private LocalDate dueDate;
|
||||||
|
|
||||||
|
@JsonbProperty("bill_number")
|
||||||
|
private String invoiceNumber;
|
||||||
|
|
||||||
|
@JsonbProperty("line_items")
|
||||||
|
private List<ZohoBillItem> lineItems;
|
||||||
|
|
||||||
|
private double amount;
|
||||||
|
|
||||||
|
// Getter und Setter
|
||||||
|
|
||||||
|
public String getBillId() {
|
||||||
|
return billId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBillId(String billId) {
|
||||||
|
this.billId = billId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVendorId() {
|
||||||
|
return vendorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVendorId(String vendorId) {
|
||||||
|
this.vendorId = vendorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 getInvoiceNumber() {
|
||||||
|
return invoiceNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInvoiceNumber(String invoiceNumber) {
|
||||||
|
this.invoiceNumber = invoiceNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ZohoBillItem> getLineItems() {
|
||||||
|
return lineItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLineItems(List<ZohoBillItem> lineItems) {
|
||||||
|
this.lineItems = lineItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(double amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.alexanderlogistics.zoho.dto;
|
||||||
|
|
||||||
|
import jakarta.json.bind.annotation.JsonbProperty;
|
||||||
|
|
||||||
|
public class ZohoBillCreateResponse {
|
||||||
|
@JsonbProperty("code")
|
||||||
|
private int code;
|
||||||
|
|
||||||
|
@JsonbProperty("message")
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
@JsonbProperty("bill")
|
||||||
|
private ZohoBill bill;
|
||||||
|
|
||||||
|
// 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 ZohoBill getBill() {
|
||||||
|
return bill;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBill(ZohoBill bill) {
|
||||||
|
this.bill = bill;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.alexanderlogistics.zoho.dto;
|
||||||
|
|
||||||
|
import jakarta.json.bind.annotation.JsonbProperty;
|
||||||
|
|
||||||
|
public class ZohoBillItem {
|
||||||
|
private String description;
|
||||||
|
private String name;
|
||||||
|
private double amount;
|
||||||
|
|
||||||
|
@JsonbProperty("account_id")
|
||||||
|
private String accountId;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getter und Setter
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccountId() {
|
||||||
|
return accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccountId(String accountId) {
|
||||||
|
this.accountId = accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(double amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,9 @@ public class ZohoContact {
|
||||||
@JsonbProperty("company_name")
|
@JsonbProperty("company_name")
|
||||||
private String companyName;
|
private String companyName;
|
||||||
|
|
||||||
|
@JsonbProperty("contact_type")
|
||||||
|
private String contactType;
|
||||||
|
|
||||||
// Weitere Felder nach Bedarf
|
// Weitere Felder nach Bedarf
|
||||||
|
|
||||||
// Getter und Setter
|
// Getter und Setter
|
||||||
|
|
@ -40,4 +43,12 @@ public class ZohoContact {
|
||||||
this.companyName = companyName;
|
this.companyName = companyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getContactType() {
|
||||||
|
return contactType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContactType(String contactType) {
|
||||||
|
this.contactType = contactType;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,32 +11,42 @@ public class ZohoExpense {
|
||||||
@JsonbProperty("expense_id")
|
@JsonbProperty("expense_id")
|
||||||
private String expenseId;
|
private String expenseId;
|
||||||
|
|
||||||
|
@JsonbProperty("account_id")
|
||||||
|
private String accountId;
|
||||||
|
|
||||||
|
@JsonbProperty("paid_through_account_id")
|
||||||
|
private String paid_through_account_id;
|
||||||
|
|
||||||
@JsonbProperty("customer_id")
|
@JsonbProperty("customer_id")
|
||||||
private String customerId;
|
private String customerId;
|
||||||
|
|
||||||
@JsonbDateFormat("yyyy-MM-dd")
|
@JsonbDateFormat("yyyy-MM-dd")
|
||||||
private LocalDate date;
|
private LocalDate date;
|
||||||
|
|
||||||
@JsonbProperty("due_date")
|
|
||||||
@JsonbDateFormat("yyyy-MM-dd")
|
|
||||||
private LocalDate dueDate;
|
|
||||||
|
|
||||||
@JsonbProperty("reference_number")
|
@JsonbProperty("reference_number")
|
||||||
private String invoiceNumber;
|
private String invoiceNumber;
|
||||||
|
|
||||||
@JsonbProperty("line_items")
|
@JsonbProperty("line_items")
|
||||||
private List<ZohoInvoiceItem> lineItems;
|
private List<ZohoExpenseItem> lineItems;
|
||||||
|
|
||||||
private double total;
|
private double amount;
|
||||||
|
|
||||||
// Getter und Setter
|
// Getter und Setter
|
||||||
|
|
||||||
public String getInvoiceId() {
|
public String getExpenseId() {
|
||||||
return invoiceId;
|
return expenseId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInvoiceId(String invoiceId) {
|
public void setExpenseId(String expenseId) {
|
||||||
this.invoiceId = invoiceId;
|
this.expenseId = expenseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccountId() {
|
||||||
|
return accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccountId(String accountId) {
|
||||||
|
this.accountId = accountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCustomerId() {
|
public String getCustomerId() {
|
||||||
|
|
@ -55,14 +65,6 @@ public class ZohoExpense {
|
||||||
this.date = date;
|
this.date = date;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate getDueDate() {
|
|
||||||
return dueDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDueDate(LocalDate duedate) {
|
|
||||||
this.dueDate = duedate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getInvoiceNumber() {
|
public String getInvoiceNumber() {
|
||||||
return invoiceNumber;
|
return invoiceNumber;
|
||||||
}
|
}
|
||||||
|
|
@ -71,19 +73,27 @@ public class ZohoExpense {
|
||||||
this.invoiceNumber = invoiceNumber;
|
this.invoiceNumber = invoiceNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ZohoInvoiceItem> getLineItems() {
|
public List<ZohoExpenseItem> getLineItems() {
|
||||||
return lineItems;
|
return lineItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLineItems(List<ZohoInvoiceItem> lineItems) {
|
public void setLineItems(List<ZohoExpenseItem> lineItems) {
|
||||||
this.lineItems = lineItems;
|
this.lineItems = lineItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getTotal() {
|
public double getAmount() {
|
||||||
return total;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTotal(double total) {
|
public void setAmount(double amount) {
|
||||||
this.total = total;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -42,12 +42,28 @@
|
||||||
<!-- API Tokens -->
|
<!-- API Tokens -->
|
||||||
<div class="imixs-form-section-2">
|
<div class="imixs-form-section-2">
|
||||||
|
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt>API OAuth URL <span class="imixs-required">*</span>
|
||||||
|
|
||||||
|
</dt>
|
||||||
|
<dd>
|
||||||
|
<h:inputText required="true"
|
||||||
|
value="#{zohoController.workitem.item['zoho.oauth.uri']}">
|
||||||
|
</h:inputText>
|
||||||
|
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
<dt>API Base URL <span class="imixs-required">*</span></dt>
|
<dt>API Base URL <span class="imixs-required">*</span></dt>
|
||||||
<dd>
|
<dd>
|
||||||
<h:inputText required="true"
|
<h:inputText required="true"
|
||||||
value="#{zohoController.workitem.item['zoho.uri']}">
|
value="#{zohoController.workitem.item['zoho.uri']}">
|
||||||
</h:inputText>
|
</h:inputText>
|
||||||
|
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
|
@ -60,6 +76,17 @@
|
||||||
</h:inputText>
|
</h:inputText>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt>Accountant ID <span class="imixs-required">*</span></dt>
|
||||||
|
<dd>
|
||||||
|
<h:inputText required="true"
|
||||||
|
value="#{zohoController.workitem.item['zoho.accountID']}">
|
||||||
|
</h:inputText>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Client ID <span class="imixs-required">*</span></dt>
|
<dt>Client ID <span class="imixs-required">*</span></dt>
|
||||||
<dd>
|
<dd>
|
||||||
|
|
@ -106,7 +133,7 @@
|
||||||
Generieren Sie einen neuen Access Code
|
Generieren Sie einen neuen Access Code
|
||||||
<br />
|
<br />
|
||||||
Scope:
|
Scope:
|
||||||
<code>ZohoBooks.contacts.ALL,ZohoBooks.invoices.CREATE,ZohoBooks.invoices.READ,ZohoBooks.invoices.UPDATE</code>
|
<code>ZohoBooks.contacts.ALL,ZohoBooks.invoices.ALL,ZohoBooks.bills.ALL</code>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
Code über den Button "Create" anfordern und in das Feld "Access Code"
|
Code über den Button "Create" anfordern und in das Feld "Access Code"
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,23 @@ public class TestUpdateTokens {
|
||||||
|
|
||||||
private String redirectURI = "https://alexander-logistics-dwc.office-workflow.de/api/zoho/grant";
|
private String redirectURI = "https://alexander-logistics-dwc.office-workflow.de/api/zoho/grant";
|
||||||
|
|
||||||
private String clientID = "1000.GR5FTPZYB06HEWSFSSX4DJU3OBD4EJ";
|
// private String clientID = "1000.GR5FTPZYB06HEWSFSSX4DJU3OBD4EJ";
|
||||||
private String clientSecret = "3f3e74c5212bbc924a7ebf77f887c6296db1106c47";
|
// private String clientSecret = "3f3e74c5212bbc924a7ebf77f887c6296db1106c47";
|
||||||
|
|
||||||
|
// forum
|
||||||
|
// private String clientID = "1000.ECQXCXYOTQ9LGLRK2V4PYU94OORJKR";
|
||||||
|
// private String clientSecret = "ce93df3860fc3d804cd015a0bec9b92dcfcf6329b8";
|
||||||
|
|
||||||
|
// DWC
|
||||||
|
// private String clientID = "1000.MQE1SU8UGY6F2PBPASOXGTLWYQD1FS";
|
||||||
|
// private String clientSecret = "1ca70e1ab803b3fed6b1b5e00858c316e2003d289b";
|
||||||
|
|
||||||
|
// Atari
|
||||||
|
private String clientID = "1000.86O4P321HDYDRX0Q0N1G7YOJRJ9D5W";
|
||||||
|
private String clientSecret = "2a67b6cfc364f5df27cc8eb33e9b0e4e8a0221ebc3";
|
||||||
|
|
||||||
|
// ROLES
|
||||||
|
// ZohoBooks.contacts.ALL,ZohoBooks.invoices.ALL,ZohoBooks.bills.ALL
|
||||||
|
|
||||||
private String code = null;
|
private String code = null;
|
||||||
private String accessToken = null;
|
private String accessToken = null;
|
||||||
|
|
@ -67,14 +82,20 @@ public class TestUpdateTokens {
|
||||||
logger.info("├── update Zoho tokens");
|
logger.info("├── update Zoho tokens");
|
||||||
refreshToken = null;
|
refreshToken = null;
|
||||||
accessToken = null;
|
accessToken = null;
|
||||||
code = "1000.48bd85a3965cf724f4691757cfd8d93b.8ae5e3ee7d70f90d307da4d289a9b067";
|
code = "1000.d2a4e3a9622fc4c5eebe1ae5ee1989b5.d6899d23da56e6d8f73125ebaa498a3e";
|
||||||
try {
|
try {
|
||||||
|
|
||||||
String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" + "?code="
|
// String requestUrl = "https://accounts.zoho.eu/oauth/v2/token" + "?code="
|
||||||
|
// + URLEncoder.encode(code, StandardCharsets.UTF_8) + "&client_id="
|
||||||
|
// + URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
|
||||||
|
// + URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&redirect_uri="
|
||||||
|
// + URLEncoder.encode(redirectURI, StandardCharsets.UTF_8) +
|
||||||
|
// "&grant_type=authorization_code";
|
||||||
|
|
||||||
|
String requestUrl = "https://accounts.zoho.com/oauth/v2/token" + "?code="
|
||||||
+ URLEncoder.encode(code, StandardCharsets.UTF_8) + "&client_id="
|
+ URLEncoder.encode(code, StandardCharsets.UTF_8) + "&client_id="
|
||||||
+ URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
|
+ URLEncoder.encode(clientID, StandardCharsets.UTF_8) + "&client_secret="
|
||||||
+ URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&redirect_uri="
|
+ URLEncoder.encode(clientSecret, StandardCharsets.UTF_8) + "&grant_type=authorization_code";
|
||||||
+ URLEncoder.encode(redirectURI, StandardCharsets.UTF_8) + "&grant_type=authorization_code";
|
|
||||||
|
|
||||||
logger.info("│ ├── Request URI=" + requestUrl);
|
logger.info("│ ├── Request URI=" + requestUrl);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue