{
	"info": {
		"_postman_id": "e4a9a92e-da6c-4e52-abf8-919d03a2acec",
		"name": "EKKO_ticket_ENG382-94",
		"description": "Keobiz regroupe un ensemble de services englobant l’expertise comptable, la création d’entreprise, la domiciliation, l’annonce légale, le business plan, le juridique et l’administratif pour les petites entreprises, artisans, professions libérales et commerçants.\r\n\r\nKeobiz a la volonté d’apporter aux chefs d’entreprises un service complet et de qualité avec des tarifs compétitifs pour leur permettre de se concentrer sur leur métier tout en gagnant du temps et en réalisant des économies.",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
	},
	"item": [
		{
			"name": "SFDC Connector",
			"item": [
				{
					"name": "Modules",
					"item": [
						{
							"name": "clean up",
							"item": [
								{
									"name": "Client",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										},
										{
											"listen": "prerequest",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "DELETE",
										"header": [],
										"body": {
											"mode": "raw",
											"raw": "",
											"options": {
												"raw": {
													"language": "json"
												}
											}
										},
										"url": {
											"raw": "{{opencell.url}}/account/businessAccountModel/{{request.label}}",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"account",
												"businessAccountModel",
												"{{request.label}}"
											]
										}
									},
									"response": []
								},
								{
									"name": "SalesforceConnectorModule",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										},
										{
											"listen": "prerequest",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "DELETE",
										"header": [],
										"body": {
											"mode": "raw",
											"raw": "",
											"options": {
												"raw": {
													"language": "json"
												}
											}
										},
										"url": {
											"raw": "{{opencell.url}}/module/{{request.label}}",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"module",
												"{{request.label}}"
											]
										}
									},
									"response": []
								},
								{
									"name": "BusinessAccountModelModule",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "DELETE",
										"header": [],
										"body": {
											"mode": "raw",
											"raw": "",
											"options": {
												"raw": {
													"language": "json"
												}
											}
										},
										"url": {
											"raw": "{{opencell.url}}/module/{{request.label}}",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"module",
												"{{request.label}}"
											]
										}
									},
									"response": []
								}
							],
							"event": [
								{
									"listen": "prerequest",
									"script": {
										"type": "text/javascript",
										"exec": [
											"pm.collectionVariables.set('skipTest', true);"
										]
									}
								},
								{
									"listen": "test",
									"script": {
										"type": "text/javascript",
										"exec": [
											""
										]
									}
								}
							]
						},
						{
							"name": "Client",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											"pm.collectionVariables.unset('skipTest');"
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"code\": \"{{request.label}}\",\r\n    \"license\": \"COM\",\r\n    \"description\": \"SFDC customer\",\r\n\t\"hierarchyType\": \"C_UA\",\r\n\t \"moduleItems\": []\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{opencell.url}}/account/businessAccountModel",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"account",
										"businessAccountModel"
									]
								}
							},
							"response": []
						},
						{
							"name": "SalesforceConnectorModule",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "PUT",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n\t\"code\": \"{{request.label}}\",\r\n\t\"description\": \"Salesforce Object Syncing\",\r\n\t\"license\": \"COM\",\r\n\t\"moduleItems\": [\r\n\t\t{\r\n\t\t\t\"script\": {\r\n\t\t\t\t\"description\": \"Salesforce object syncing script\",\r\n\t\t\t\t\"script\": \"package org.opencell.eeko.service.script.syncing;\\n\\nimport java.text.MessageFormat;\\nimport java.util.ArrayList;\\nimport java.util.Date;\\nimport java.util.HashMap;\\nimport java.util.List;\\nimport java.util.Map;\\nimport java.util.Base64;\\nimport javax.persistence.Query;\\nimport javax.persistence.EntityManager;\\nimport javax.ws.rs.HttpMethod;\\nimport javax.ws.rs.ProcessingException;\\nimport javax.ws.rs.client.Entity;\\nimport javax.ws.rs.client.Invocation;\\nimport javax.ws.rs.core.Form;\\nimport javax.ws.rs.core.HttpHeaders;\\nimport javax.ws.rs.core.MultivaluedMap;\\nimport javax.ws.rs.core.Response;\\n\\nimport org.apache.commons.lang3.builder.ToStringBuilder;\\nimport org.apache.commons.lang3.builder.ToStringStyle;\\nimport org.hibernate.proxy.HibernateProxy;\\nimport org.jboss.resteasy.client.jaxrs.ResteasyClient;\\nimport org.meveo.commons.utils.ResteasyClientProxyBuilder;\\nimport org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;\\nimport org.json.simple.JSONArray;\\nimport org.meveo.admin.exception.BusinessException;\\nimport org.meveo.api.exception.MeveoApiException;\\nimport org.meveo.commons.utils.JsonUtils;\\nimport org.meveo.commons.utils.ParamBean;\\nimport org.meveo.commons.utils.ParamBeanFactory;\\nimport org.meveo.commons.utils.ReflectionUtils;\\nimport org.meveo.commons.utils.StringUtils;\\nimport org.meveo.model.BaseEntity;\\nimport org.meveo.model.BusinessEntity;\\nimport org.meveo.model.ICustomFieldEntity;\\nimport org.meveo.model.IEntity;\\nimport org.meveo.model.billing.Invoice;\\nimport org.meveo.model.crm.Customer;\\nimport org.meveo.model.billing.Subscription;\\nimport org.meveo.model.payments.AccountOperation;\\nimport org.meveo.model.payments.MatchingAmount;\\nimport org.meveo.model.payments.MatchingCode;\\nimport org.meveo.model.payments.OtherCreditAndCharge;\\nimport org.meveo.model.payments.Payment;\\nimport org.meveo.model.payments.RecordedInvoice;\\nimport org.meveo.model.payments.RejectedPayment;\\nimport org.meveo.model.shared.DateUtils;\\nimport org.meveo.service.base.BaseEntityService;\\nimport org.meveo.service.billing.impl.InvoiceService;\\nimport org.meveo.service.script.Script;\\nimport org.slf4j.Logger;\\nimport org.slf4j.LoggerFactory;\\n\\nimport com.google.gson.JsonObject;\\nimport com.google.gson.annotations.SerializedName;\\n\\n/**\\n * \\n * This script allows to send the object available in the context param to its equivalent on the SFDC side The process is using the oauth2 with refresh based on the global system\\n * properties provided by the SFDC env\\n * \\n * @author Youssef IZEM\\n * @lastModifiedVersion 1.0\\n */\\npublic class SObjectSyncingScript extends Script {\\n\\n\\tprivate static final long serialVersionUID = 1L;\\n\\n\\t/**\\n\\t * Salesforce resources path\\n\\t */\\n\\tprivate static final String END_POINT_API_VERSION = \\\"v50.0\\\";\\n\\tprivate static final String END_POINT_TOKEN_REQUEST = \\\"/services/oauth2/token\\\";\\n\\tprivate static final String END_POINT_SOBJECT_INVOICE = \\\"/services/data/{{version}}/sobjects/opencell__invoice__c\\\";\\n\\tprivate static final String END_POINT_SOBJECT_ATTACHMENT = \\\"/services/data/{{version}}/sobjects/Attachment\\\";\\n\\tprivate static final String END_POINT_RESOURCE_COMPOSITE = \\\"/services/data/{{version}}/composite/\\\";\\n\\tprivate static final String END_POINT_SOBJECT_SUBSCRIPTION = \\\"/services/data/{{version}}/sobjects/opencell__Subscription__c\\\";\\n\\tprivate static final String END_POINT_SOBJECT_ACCOUNT_OPERATION = \\\"/services/data/{{version}}/sobjects/opencell__AccountOperation__c\\\";\\n\\n\\t/**\\n\\t * Global properties credentials for Salesforce authent\\n\\t */\\n\\tprivate static final String PROPERTY_KEY_SALESFORCE_URL = \\\"salesforce.url\\\";\\n\\tprivate static final String PROPERTY_KEY_SALESFORCE_USERNAME = \\\"salesforce.username\\\";\\n\\tprivate static final String PROPERTY_KEY_SALESFORCE_PASSWORD = \\\"salesforce.password\\\";\\n\\tprivate static final String PROPERTY_KEY_SALESFORCE_CLIENT_ID = \\\"salesforce.clientId\\\";\\n\\tprivate static final String PROPERTY_KEY_SALESFORCE_CLIENT_SECRET = \\\"salesforce.clientSecret\\\";\\n\\n\\t/**\\n\\t * Salesforce oAuth2 request params\\n\\t */\\n\\tprivate static final String TOKEN_REQUEST_PARAM_USERNAME = \\\"username\\\";\\n\\tprivate static final String TOKEN_REQUEST_PARAM_PASSWORD = \\\"password\\\";\\n\\tprivate static final String TOKEN_REQUEST_PARAM_CLIENT_ID = \\\"client_id\\\";\\n\\tprivate static final String TOKEN_REQUEST_PARAM_GRANT_TYPE = \\\"grant_type\\\";\\n\\tprivate static final String TOKEN_REQUEST_PARAM_CLIENT_SECRET = \\\"client_secret\\\";\\n\\tprivate static final String TOKEN_REQUEST_PARAM_REFRESH_TOKEN = \\\"refresh_token\\\";\\n\\tprivate static final String TOKEN_REQUEST_PARAM_GRANT_TYPE_REFRESH = \\\"refresh_token\\\";\\n\\tprivate static final String TOKEN_REQUEST_RESPONSE_INVALID_SESSION = \\\"INVALID_SESSION_ID\\\";\\n\\tprivate static final String TOKEN_REQUEST_PARAM_GRANT_TYPE_PASSWORD = \\\"password\\\";\\n\\tprivate static final String TOKEN_REQUEST_RESPONSE_AUTHENTICATION_ERROR = \\\"Authentication error\\\";\\n\\n\\t/**\\n\\t * Salesforce oAuth2 timeout\\n\\t */\\n\\tpublic static final Integer OAUTH_TOKEN_RETRY_TIMES = 3;\\n\\tpublic static final Integer OAUTH_TOKEN_REFRESH_IN_MINUTES = 15;\\n\\tpublic static final Integer OAUTH_READ_TIMEOUT_IN_SECONDS = 10;\\n\\tpublic static final Integer OAUTH_SOCKET_TIMEOUT_IN_SECONDS = 5;\\n\\tpublic static final Integer OAUTH_CONNECT_TIMEOUT_IN_SECONDS = 5;\\n\\n\\t/**\\n\\t * Constants\\n\\t */\\n\\tprivate static final String SFDC_REFERENCE_ID = \\\"referenceId\\\";\\n\\tprivate static final String CF_IS_SYNCED_NAME = \\\"CF_ENTITY_IS_SYNCED\\\";\\n\\tprivate static final String CF_SFDC_INVOICE_ID = \\\"CF_SFDC_INVOICE_ID\\\";\\n\\tprivate static final String CF_SFDC_ATTACHMENT_ID = \\\"CF_SFDC_ATTACHMENT_ID\\\";\\n\\n\\t/**\\n\\t * Syncing erros custom table SQL requests\\n\\t */\\n\\tprivate static final String DELETE_ERRORS_QUERY = \\\"DELETE FROM SYNCING_ERRORS WHERE entity_type='%s' AND entity_id = '%s'\\\";\\n\\tprivate static final String INSERT_ERRORS_QUERY = \\\"INSERT INTO SYNCING_ERRORS (entity_id, entity_code, entity_type, syncing_date, request_path_info, request_body, response_status, response_message, response_body) \\\"\\n\\t\\t\\t+ \\\"VALUES ('%s','%s', '%s', '%s','%s', '%s','%s','%s', '%s');\\\";\\n\\n\\t/**\\n\\t * Salesforce oAuth2 token\\n\\t */\\n\\tprivate static Token token;\\n\\n\\t/**\\n\\t * All core services used in the syncing process\\n\\t */\\n\\tprivate transient ParamBean paramBean = ((ParamBeanFactory) getServiceInterface(ParamBeanFactory.class.getSimpleName())).getInstance();\\n\\tprivate transient InvoiceService invoiceService = (InvoiceService) getServiceInterface(InvoiceService.class.getSimpleName());\\n\\tprivate transient BaseEntityService baseEntityService = (BaseEntityService) getServiceInterface(BaseEntityService.class.getSimpleName());\\n\\tprivate transient EntityManager em = invoiceService.getEntityManager();\\n\\tprivate static final ResteasyClient client = new ResteasyClientProxyBuilder().build();\\n\\n\\t/**\\n\\t * The main method called by the object updating/creating notifications\\n\\t */\\n\\t@Override\\n\\tpublic void execute(Map<String, Object> context) {\\n\\t\\tObject object = context.get(Script.CONTEXT_ENTITY);\\n\\t\\tif (!(object instanceof IEntity)) {\\n\\t\\t\\tlog.warn(\\\"<======== This object isn't configured to be synced : {}\\\", object);\\n\\t\\t\\treturn;\\n\\t\\t}\\n\\t\\tIEntity entity = (IEntity) object;\\n\\t\\tClass clazz = ReflectionUtils.getClassBySimpleNameAndParentClass(entity.getClass().getSimpleName(), BaseEntity.class);\\n\\t\\tbaseEntityService.setEntityClass(clazz);\\n\\t\\t\\n\\t\\tentity = baseEntityService.retrieveIfNotManaged(entity);\\n\\t\\tlog.info(\\\"========> Start syncing the entity : {}[id={}]  ...............\\\", entity.getClass().getSimpleName(), ((IEntity) entity).getId());\\n\\n\\t\\ttry {\\n\\t\\t\\tif (entity instanceof Invoice) {\\n\\t\\t\\t\\tsendInvoice((Invoice) entity);\\n\\t\\t\\t\\tsendPDF((Invoice) entity);\\n\\t\\t\\t} else if (entity instanceof Subscription) {\\n\\t\\t\\t\\tsendSubscription((Subscription) entity);\\n\\t\\t\\t} else if (entity instanceof MatchingCode) {\\n\\t\\t\\t\\tsendMatchingCode((MatchingCode) entity);\\n\\t\\t\\t} else if (entity instanceof AccountOperation) {\\n\\t\\t\\t\\tsendAccountOperation((AccountOperation) entity);\\n\\t\\t\\t} else {\\n\\t\\t\\t\\tlog.warn(\\\"<======== This entity isn't configured to be synced : {}\\\", entity);\\n\\t\\t\\t\\treturn;\\n\\t\\t\\t}\\n\\t\\t\\tlog.info(\\\"<======== This entity has successfully been synced : {}\\\", entity);\\n\\n\\t\\t} catch (SObjectSyncingException ex) {\\n\\t\\t\\tlog.error(\\\"<======== \\\" + ex.getMessage());\\n\\t\\t} catch (Exception ex) {\\n\\t\\t\\tregisterResult(entity, null, null, null, ex.getMessage(), false);\\n\\t\\t\\tlog.error(\\\"<======== Generic error thrown during entity sending : {} => {} \\\", entity, ex.getMessage());\\n\\t\\t} finally {\\n\\t\\t\\tentity = this.baseEntityService.updateNoCheck(entity);\\n\\t\\t}\\n\\n\\t}\\n\\n\\t/**\\n\\t * Sends Subscription object to SFDC\\n\\t * \\n\\t * @param subscription\\n\\t */\\n\\tprivate void sendSubscription(Subscription subscription) {\\n\\n\\t\\tCompositeSubRequestDto subscriptionReq = new CompositeSubRequestDto();\\n\\t\\tsubscriptionReq.setMethod(HttpMethod.PATCH);\\n\\t\\tsubscriptionReq.setReferenceId(SFDC_REFERENCE_ID);\\n\\t\\tsubscriptionReq.setBody(toSubscriptionJson(subscription));\\n\\t\\tsubscriptionReq.setUrl(getEndPoint(END_POINT_SOBJECT_SUBSCRIPTION, \\\"OCCode\\\", subscription.getCode()));\\n\\n\\t\\tCompositeRequestDto request = new CompositeRequestDto();\\n\\t\\trequest.setAllOrNone(true);\\n\\t\\trequest.addSubRequest(subscriptionReq);\\n\\t\\trequest.setCollateSubrequests(true);\\n\\n\\t\\tsendRequest(request, subscription, null);\\n\\t}\\n\\n\\t/**\\n\\t * Sends invoice object to SFDC\\n\\t * \\n\\t * @param invoice\\n\\t */\\n\\tprivate void sendInvoice(Invoice invoice) {\\n\\n\\t\\tCompositeSubRequestDto invoiceReq = new CompositeSubRequestDto();\\n\\t\\tinvoiceReq.setMethod(HttpMethod.PATCH);\\n\\t\\tinvoiceReq.setReferenceId(SFDC_REFERENCE_ID);\\n\\t\\tinvoiceReq.setBody(toInvoiceJson(invoice));\\n\\t\\tinvoiceReq.setUrl(getEndPoint(END_POINT_SOBJECT_INVOICE, \\\"Id\\\", invoice.getId()));\\n\\n\\t\\tCompositeRequestDto request = new CompositeRequestDto();\\n\\t\\trequest.setAllOrNone(true);\\n\\t\\trequest.addSubRequest(invoiceReq);\\n\\t\\trequest.setCollateSubrequests(false);\\n\\n\\t\\tsendRequest(request, invoice, CF_SFDC_INVOICE_ID);\\n\\t}\\n\\n\\t/**\\n\\t * Sends invoice pdf to SFDC, we start by deleting old pdf because the patch based on the external id is not working with the attachment object\\n\\t * \\n\\t * @param invoice\\n\\t */\\n\\tprivate void sendPDF(Invoice invoice) {\\n\\n\\t\\tif (invoiceService.isInvoicePdfExist(invoice)) {\\n\\t\\t\\tCompositeRequestDto request = new CompositeRequestDto();\\n\\t\\t\\tObject invoiceId = invoice.getCfValue(CF_SFDC_INVOICE_ID);\\n\\t\\t\\tif (invoiceId instanceof String) {\\n\\t\\t\\t\\tObject attachmentId = invoice.getCfValue(CF_SFDC_ATTACHMENT_ID);\\n//\\t\\t\\t\\tif (attachmentId instanceof String) {\\n//\\t\\t\\t\\t\\tCompositeSubRequestDto delAttachmentReq = new CompositeSubRequestDto();\\n//\\t\\t\\t\\t\\tdelAttachmentReq.setMethod(HttpMethod.DELETE);\\n//\\t\\t\\t\\t\\tdelAttachmentReq.setReferenceId(\\\"refDelAttachment\\\");\\n//\\t\\t\\t\\t\\tdelAttachmentReq.setUrl(getEndPoint(END_POINT_SOBJECT_ATTACHMENT) + \\\"/\\\" + attachmentId);\\n//\\t\\t\\t\\t\\trequest.addSubRequest(delAttachmentReq);\\n//\\t\\t\\t\\t}\\n\\t\\t\\t\\tif (!(attachmentId instanceof String)) {\\n\\t\\t\\t\\t\\tCompositeSubRequestDto attachmentReq = new CompositeSubRequestDto();\\n\\t\\t\\t\\t\\tattachmentReq.setMethod(HttpMethod.POST);\\n\\t\\t\\t\\t\\tattachmentReq.setReferenceId(SFDC_REFERENCE_ID);\\n\\t\\t\\t\\t\\tattachmentReq.setUrl(getEndPoint(END_POINT_SOBJECT_ATTACHMENT));\\n\\t\\t\\t\\t\\tattachmentReq.setBody(toAttachmentJson(invoice, (String) invoiceId));\\n\\t\\t\\t\\t\\trequest.addSubRequest(attachmentReq);\\n\\n\\t\\t\\t\\t\\trequest.setAllOrNone(false);\\n\\t\\t\\t\\t\\trequest.setCollateSubrequests(false);\\n\\t\\t\\t\\t\\tsendRequest(request, invoice, CF_SFDC_ATTACHMENT_ID);\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\n\\t\\t}\\n\\t}\\n\\n\\t/**\\n\\t * Sends an accountOperation object to SFDC\\n\\t * \\n\\t * @param accountOperation\\n\\t */\\n\\tprivate void sendAccountOperation(AccountOperation accountOperation) {\\n\\n\\t\\tCompositeSubRequestDto paymentReq = new CompositeSubRequestDto();\\n\\t\\tpaymentReq.setUrl(getEndPoint(END_POINT_SOBJECT_ACCOUNT_OPERATION, \\\"Id\\\", accountOperation.getId()));\\n\\t\\tpaymentReq.setMethod(HttpMethod.PATCH);\\n\\t\\tpaymentReq.setReferenceId(SFDC_REFERENCE_ID);\\n\\t\\tpaymentReq.setBody(toAccountOperationJson(accountOperation));\\n\\n\\t\\tCompositeRequestDto request = new CompositeRequestDto();\\n\\t\\trequest.setAllOrNone(true);\\n\\t\\trequest.addSubRequest(paymentReq);\\n\\t\\trequest.setCollateSubrequests(true);\\n\\n\\t\\tsendRequest(request, accountOperation, null);\\n\\t}\\n\\n\\t/**\\n\\t * Updates the AO already sent to SFDC after been matched on OC\\n\\t * \\n\\t * @param matchingCode\\n\\t */\\n\\tprivate void sendMatchingCode(MatchingCode matchingCode) {\\n\\t\\tif (matchingCode.getMatchingAmounts() != null && !matchingCode.getMatchingAmounts().isEmpty()) {\\n\\t\\t\\tfor (MatchingAmount matchingAmount : matchingCode.getMatchingAmounts()) {\\n\\t\\t\\t\\tif (matchingAmount != null && matchingAmount.getAccountOperation() != null) {\\n\\t\\t\\t\\t\\tAccountOperation accountOperation = matchingAmount.getAccountOperation();\\n\\t\\t\\t\\t\\taccountOperation = (AccountOperation) baseEntityService.retrieveIfNotManaged(accountOperation);\\n\\t\\t\\t\\t\\tlog.info(\\\" --- [MatchingCode] : syncing the AO : {}  ...............\\\", accountOperation);\\n\\t\\t\\t\\t\\tsendAccountOperation(accountOperation);\\n\\t\\t\\t\\t\\tif (accountOperation instanceof RecordedInvoice && ((RecordedInvoice) accountOperation).getInvoice() != null) {\\n\\t\\t\\t\\t\\t\\tInvoice invoice = ((RecordedInvoice) accountOperation).getInvoice();\\n\\t\\t\\t\\t\\t\\tinvoice = (Invoice) baseEntityService.retrieveIfNotManaged(invoice);\\n\\t\\t\\t\\t\\t\\tlog.info(\\\" --- [Matched invoice] : syncing the matched invoice : {}  ...............\\\", invoice);\\n\\t\\t\\t\\t\\t\\tsendInvoice(invoice);\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\t/**\\n\\t * Send composite request to salesforce\\n\\t * \\n\\t * @param request\\n\\t * @param entity\\n\\t * @param cfName\\n\\t */\\n\\tprivate void sendRequest(CompositeRequestDto request, IEntity entity, String cfName) {\\n\\n\\t\\tint cp = 1;\\n\\t\\tString targetUri = \\\"\\\";\\n\\t\\tString instanceUrl = \\\"\\\";\\n\\t\\tString authorization = \\\"\\\";\\n\\t\\tResponse response = null;\\n\\t\\tboolean isAuthenticated = false;\\n\\t\\tString exceptionMessage = \\\"\\\";\\n\\n\\t\\tdo {\\n\\t\\t\\ttry {\\n\\t\\t\\t\\tif (token == null) {\\n\\t\\t\\t\\t\\tisAuthenticated = this.authenticate();\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tif (token != null) {\\n\\t\\t\\t\\t\\tinstanceUrl = token.getInstanceUrl();\\n\\t\\t\\t\\t\\tauthorization = token.getAuth();\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\ttargetUri = instanceUrl + getEndPoint(END_POINT_RESOURCE_COMPOSITE);\\n\\t\\t\\t\\tlogRequest(targetUri, request);\\n\\t\\t\\t\\tResteasyWebTarget target = client.target(targetUri);\\n\\t\\t\\t\\tInvocation.Builder requestBuilder = target.request();\\n\\t\\t\\t\\trequestBuilder = requestBuilder.header(HttpHeaders.AUTHORIZATION, authorization);\\n\\t\\t\\t\\tresponse = requestBuilder.post((Entity.json(JsonUtils.toJson(request, false))));\\n\\t\\t\\t\\tprocessResponse(entity, cfName, request, response);\\n\\t\\t\\t\\tisAuthenticated = true;\\n\\t\\t\\t} catch (ProcessingException ex) {\\n\\t\\t\\t\\texceptionMessage = ex.getMessage();\\n\\t\\t\\t\\tlog.error(\\\"Error invoking target {} with request {} =>  {}\\\", targetUri, request, exceptionMessage);\\n\\t\\t\\t\\tisAuthenticated = this.authenticate();\\n\\t\\t\\t} catch (SObjectSyncingException ex) {\\n\\t\\t\\t\\tif (ex.getMessage() != null && ex.getMessage().contains(TOKEN_REQUEST_RESPONSE_AUTHENTICATION_ERROR)) {\\n\\t\\t\\t\\t\\ttoken = null;\\n\\t\\t\\t\\t\\tcontinue;\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\tthrow ex;\\n\\t\\t\\t} catch (Exception ex) {\\n\\t\\t\\t\\tlog.error(\\\"Error invoking target {} with request {} =>  {}\\\", targetUri, request, ex.getMessage());\\n\\t\\t\\t\\tregisterResult(entity, request, null, response, ex.getMessage(), false);\\n\\t\\t\\t\\tthrow new SObjectSyncingException(ErrorMessage.ENTITY_SYNCING_ERROR, entity, ex.getMessage());\\n\\t\\t\\t}\\n\\n\\t\\t} while (!isAuthenticated && cp++ < OAUTH_TOKEN_RETRY_TIMES);\\n\\n\\t\\tif (!isAuthenticated) {\\n\\t\\t\\tlog.error(\\\"Failed to invoke target {} with request {} After {} attempts  =>  {}\\\", targetUri, request, OAUTH_TOKEN_RETRY_TIMES, exceptionMessage);\\n\\t\\t\\tregisterResult(entity, request, null, response, exceptionMessage, false);\\n\\t\\t\\tthrow new SObjectSyncingException(ErrorMessage.ENTITY_SYNCING_ERROR, entity, exceptionMessage);\\n\\t\\t}\\n\\t}\\n\\n\\t/**\\n\\t * Process the Salesforce syncing response\\n\\t * \\n\\t * @param entity\\n\\t * @param cfName to store the SF id on Opencell\\n\\t * @param request\\n\\t * @param response\\n\\t */\\n\\tprivate void processResponse(IEntity entity, String cfName, CompositeRequestDto request, Response response) {\\n\\n\\t\\tString jsonResponse = response.readEntity(String.class);\\n\\t\\tif (log.isDebugEnabled()) {\\n\\t\\t\\tlog.debug(\\\"Json Response : [{}:{}] => {}\\\", response.getStatus(), response.getStatusInfo().getReasonPhrase(), jsonResponse);\\n\\t\\t}\\n\\n\\t\\tif (isSuccessResponse(response)) {\\n\\t\\t\\tResponseDto result = JsonUtils.toObject(jsonResponse, ResponseDto.class);\\n\\t\\t\\tboolean isSuccess = result.isRequestSuccess(SFDC_REFERENCE_ID);\\n\\t\\t\\tregisterResult(entity, request, null, response, jsonResponse, isSuccess);\\n\\t\\t\\tif (!isSuccess) {\\n\\t\\t\\t\\tif (jsonResponse.contains(TOKEN_REQUEST_RESPONSE_INVALID_SESSION)) {\\n\\t\\t\\t\\t\\tthrow new SObjectSyncingException(ErrorMessage.AUTHENTICATION_ERROR, response.getStatus(), response.getStatusInfo().getReasonPhrase(), jsonResponse);\\n\\t\\t\\t\\t} else {\\n\\t\\t\\t\\t\\t  throw new SObjectSyncingException(ErrorMessage.ENTITY_SYNCING_ERROR, entity, result);\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\tif (cfName != null && entity instanceof ICustomFieldEntity) {\\n\\t\\t\\t\\t((ICustomFieldEntity) entity).setCfValue(cfName, result.getSObjectId(SFDC_REFERENCE_ID));\\n\\t\\t\\t}\\n\\t\\t} else {\\n\\t\\t\\tJSONArray errorResponse = JsonUtils.toObject(jsonResponse, JSONArray.class);\\n\\t\\t\\tregisterResult(entity, request, null, response, jsonResponse, false);\\n\\t\\t\\tif (jsonResponse.contains(TOKEN_REQUEST_RESPONSE_INVALID_SESSION)) {\\n\\t\\t\\t\\tthrow new SObjectSyncingException(ErrorMessage.AUTHENTICATION_ERROR, response.getStatus(), response.getStatusInfo().getReasonPhrase(), jsonResponse);\\n\\t\\t\\t} else {\\n\\t\\t\\t  throw new SObjectSyncingException(ErrorMessage.ENTITY_SYNCING_ERROR, entity, errorResponse);\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\t/**\\n\\t * Allows to register the syncing process result on the system espacially the syncing status to avoid to resync the objects already synced next iteration.\\n\\t * \\n\\t * @param service\\n\\t * @param entity\\n\\t * @param isSynced\\n\\t */\\n\\tprivate void registerResult(IEntity entity, CompositeRequestDto request, String jsonRequest, Response response, String jsonResponse, boolean isSynced) {\\n\\n\\t\\tif (entity instanceof ICustomFieldEntity) {\\n\\t\\t\\t((ICustomFieldEntity) entity).setCfValue(CF_IS_SYNCED_NAME, isSynced);\\n\\t\\t}\\n\\n\\t\\tString entityId = \\\"-\\\";\\n\\t\\tString entityType = \\\"-\\\";\\n\\t\\tString queryToExecute = null;\\n\\t\\tString endPoint = (token != null ? token.getInstanceUrl() : \\\"\\\") + getEndPoint(END_POINT_RESOURCE_COMPOSITE);\\n\\n\\t\\tif (entity == null) { // Token case\\n\\t\\t\\tentityType = \\\"Token\\\";\\n\\t\\t} else {\\n\\t\\t\\tentityType = entity.getClass().getName();\\n\\t\\t\\tentityId = entity.getId() + \\\"\\\";\\n\\t\\t}\\n\\n\\t\\tif (isSynced) {\\n\\t\\t\\tqueryToExecute = String.format(DELETE_ERRORS_QUERY, entityType, entityId);\\n\\t\\t} else {\\n\\n\\t\\t\\tString entityCode = \\\"-\\\";\\n\\t\\t\\tString requestBody = \\\"-\\\";\\n\\t\\t\\tString responseBody = \\\"-\\\";\\n\\t\\t\\tString responseStatus = \\\"-\\\";\\n\\t\\t\\tString responseMessage = \\\"-\\\";\\n\\t\\t\\tString requestEndPoint = endPoint;\\n\\t\\t\\tString lastSyncingDate = this.formatAsTime(new Date());\\n\\n\\t\\t\\tif (entity instanceof BusinessEntity) {\\n\\t\\t\\t\\tentityCode = ((BusinessEntity) entity).getCode();\\n\\t\\t\\t}\\n\\t\\t\\tif (entity instanceof Invoice) {\\n\\t\\t\\t\\tentityCode = ((Invoice) entity).getInvoiceNumber();\\n\\t\\t\\t}\\n\\t\\t\\tif (request != null) {\\n\\t\\t\\t\\trequestBody = JsonUtils.toJson(request, false);\\n\\t\\t\\t}\\n\\t\\t\\tif (jsonRequest != null) {\\n\\t\\t\\t\\trequestBody = jsonRequest;\\n\\t\\t\\t}\\n\\t\\t\\tif (response != null) {\\n\\t\\t\\t\\tresponseStatus = response.getStatus() + \\\"\\\";\\n\\t\\t\\t\\tresponseMessage = response.getStatusInfo() == null ? responseMessage : response.getStatusInfo().getReasonPhrase();\\n\\t\\t\\t}\\n\\t\\t\\tif (jsonResponse != null) {\\n\\t\\t\\t\\tresponseBody = jsonResponse;\\n\\t\\t\\t}\\n\\n\\t\\t\\tqueryToExecute = String.format(INSERT_ERRORS_QUERY, entityId, entityCode, entityType, lastSyncingDate, requestEndPoint, requestBody, responseStatus, responseMessage,\\n\\t\\t\\t\\tresponseBody);\\n\\t\\t}\\n\\n\\t\\tif (queryToExecute != null) {\\n\\t\\t\\t/*Query query = em.createNativeQuery(queryToExecute);\\n\\t\\t\\tif (query != null) {\\n\\t\\t\\t\\tquery.executeUpdate();\\n\\t\\t\\t}*/\\n\\t\\t}\\n\\t}\\n\\n\\t/**\\n\\t * Logs the request sent to SFDC\\n\\t * \\n\\t * @param endPoint\\n\\t * @param request\\n\\t */\\n\\tprivate void logRequest(String endPoint, CompositeRequestDto request) {\\n\\t\\tif (log.isDebugEnabled()) {\\n\\t\\t\\tString jsonBody = JsonUtils.toJson(request, false);\\n\\t\\t\\tlog.debug(\\\"Calling target=[{}] with request=[{}]\\\", endPoint, jsonBody);\\n\\t\\t}\\n\\t}\\n\\n\\t/**\\n\\t * Checks if is success response.\\n\\t *\\n\\t * @param response the response\\n\\t * @return true, if is success response\\n\\t */\\n\\tprivate boolean isSuccessResponse(Response response) {\\n\\t\\treturn Response.Status.Family.SUCCESSFUL == response.getStatusInfo().getFamily();\\n\\t}\\n\\n\\t/**\\n\\t * Put the right version & the external ID in the endPoint param\\n\\t * \\n\\t * @param endPoint\\n\\t * @return\\n\\t */\\n\\tprivate String getEndPoint(String endPoint, String fieldName, Object fieldValue) {\\n\\t\\treturn this.getEndPoint(endPoint) + \\\"/opencell__\\\" + fieldName + \\\"__c/\\\" + fieldValue;\\n\\t}\\n\\n\\tprivate String getEndPoint(String endPoint) {\\n\\t\\treturn endPoint.replace(\\\"{{version}}\\\", END_POINT_API_VERSION);\\n\\t}\\n\\n\\t/**\\n\\t * All the oAuth2 process is done in this method\\n\\t */\\n\\tprivate boolean authenticate() {\\n\\t\\ttry {\\n\\t\\t\\tfinal String tokenRequetsUrl = this.getMandatoryParam(PROPERTY_KEY_SALESFORCE_URL) + END_POINT_TOKEN_REQUEST;\\n\\t\\t\\tResteasyWebTarget resourceTarget = client.target(tokenRequetsUrl);\\n\\n\\t\\t\\tForm form = buildTokenRequest();\\n\\t\\t\\tif (log.isDebugEnabled()) {\\n\\t\\t\\t\\tlog.debug(\\\"A token request will be sent... {}\\\", securedLog(form));\\n\\t\\t\\t}\\n\\n\\t\\t\\tResponse response = resourceTarget.request().post(Entity.form(form), Response.class);\\n\\t\\t\\tString jsonResponse = response.readEntity(String.class);\\n\\n\\t\\t\\tboolean isSuccess = isSuccessResponse(response);\\n\\t\\t\\tregisterResult(null, null, securedLog(form), response, jsonResponse, isSuccess);\\n\\t\\t\\tif (isSuccess) {\\n\\t\\t\\t\\ttoken = JsonUtils.toObject(jsonResponse, Token.class);\\n\\t\\t\\t\\tif (log.isDebugEnabled()) {\\n\\t\\t\\t\\t\\tlog.debug(\\\"A new token has successfully been obtained : {}\\\", token);\\n\\t\\t\\t\\t}\\n\\t\\t\\t\\treturn true;\\n\\t\\t\\t} else {\\n\\t\\t\\t\\tthrow new SObjectSyncingException(ErrorMessage.AUTHENTICATION_ERROR, response.getStatus(), response.getStatusInfo().getReasonPhrase(), jsonResponse);\\n\\t\\t\\t}\\n\\n\\t\\t} catch (SObjectSyncingException e) {\\n\\t\\t\\tthrow e;\\n\\t\\t} catch (Exception e) {\\n\\t\\t\\tregisterResult(null, null, null, null, e.getMessage(), false);\\n\\t\\t\\tthrow new SObjectSyncingException(ErrorMessage.AUTHENTICATION_ERROR_UNKNOWN, e.getMessage());\\n\\t\\t}\\n\\t}\\n\\n\\t/**\\n\\t * Secures Request form params to log them\\n\\t * \\n\\t * @param form\\n\\t * @return\\n\\t */\\n\\tprivate String securedLog(Form form) {\\n\\t\\tif (form == null || form.asMap() == null) {\\n\\t\\t\\treturn \\\"\\\";\\n\\t\\t}\\n\\n\\t\\tMap<String, String> result = new HashMap<>();\\n\\t\\tMultivaluedMap<String, String> map = form.asMap();\\n\\t\\tfor (Map.Entry<String, List<String>> entry : map.entrySet()) {\\n\\t\\t\\tif (entry.getValue() != null && !entry.getValue().isEmpty()) {\\n\\t\\t\\t\\tresult.put(entry.getKey(), maskString(entry.getValue().get(0)));\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\treturn result.toString();\\n\\t}\\n\\n\\t/**\\n\\t * Masks a part of the string param\\n\\t * \\n\\t * @param stringToMask\\n\\t * @return\\n\\t */\\n\\tprivate static String maskString(String stringToMask) {\\n\\t\\tif (stringToMask != null && stringToMask.length() >= 8) {\\n\\t\\t\\treturn new StringBuilder(stringToMask.substring(0, 4)).append(org.apache.commons.lang3.StringUtils.repeat('*', stringToMask.length() - 8))\\n\\t\\t\\t\\t.append(stringToMask.substring(stringToMask.length() - 4)).toString();\\n\\t\\t}\\n\\t\\treturn \\\"\\\";\\n\\t}\\n\\n\\t/**\\n\\t * Reads the configuration from the system properties and builds the token request based on.\\n\\t * \\n\\t * @return\\n\\t */\\n\\tprivate Form buildTokenRequest() {\\n\\t\\tfinal String username = this.getMandatoryParam(PROPERTY_KEY_SALESFORCE_USERNAME);\\n\\t\\tfinal String password = this.getMandatoryParam(PROPERTY_KEY_SALESFORCE_PASSWORD);\\n\\t\\tfinal String clientId = this.getMandatoryParam(PROPERTY_KEY_SALESFORCE_CLIENT_ID);\\n\\t\\tfinal String clientSecret = this.getMandatoryParam(PROPERTY_KEY_SALESFORCE_CLIENT_SECRET);\\n\\n\\t\\tForm request = new Form();\\n\\t\\trequest.param(TOKEN_REQUEST_PARAM_USERNAME, username);\\n\\t\\trequest.param(TOKEN_REQUEST_PARAM_PASSWORD, password);\\n\\t\\trequest.param(TOKEN_REQUEST_PARAM_CLIENT_ID, clientId);\\n\\t\\trequest.param(TOKEN_REQUEST_PARAM_CLIENT_SECRET, clientSecret);\\n\\t\\trequest.param(TOKEN_REQUEST_PARAM_GRANT_TYPE, TOKEN_REQUEST_PARAM_GRANT_TYPE_PASSWORD);\\n\\n\\t\\treturn request;\\n\\t}\\n\\n\\t/**\\n\\t * Reads the configuration from the system properties and builds the refresh token request based on. NOT SUPPORTED YET BY SFDC\\n\\t * \\n\\t * @return\\n\\t */\\n\\tprivate Form buildTokenRefresh() {\\n\\t\\tfinal String clientId = this.getMandatoryParam(PROPERTY_KEY_SALESFORCE_CLIENT_ID);\\n\\t\\tfinal String clientSecret = this.getMandatoryParam(PROPERTY_KEY_SALESFORCE_CLIENT_SECRET);\\n\\n\\t\\tForm request = new Form();\\n\\t\\trequest.param(TOKEN_REQUEST_PARAM_CLIENT_ID, clientId);\\n\\t\\trequest.param(TOKEN_REQUEST_PARAM_CLIENT_SECRET, clientSecret);\\n\\t\\trequest.param(TOKEN_REQUEST_PARAM_REFRESH_TOKEN, token.getAccessToken());\\n\\t\\trequest.param(TOKEN_REQUEST_PARAM_GRANT_TYPE, TOKEN_REQUEST_PARAM_GRANT_TYPE_REFRESH);\\n\\n\\t\\treturn request;\\n\\t}\\n\\n\\t/**\\n\\t * Build the subscription json to send to SFDC\\n\\t * \\n\\t * @param subscription\\n\\t * @return\\n\\t */\\n\\tprivate JsonObject toSubscriptionJson(Subscription subscription) {\\n\\n\\t\\tJsonObject subscriptionJson = new JsonObject();\\n\\t\\tsubscriptionJson.addProperty(\\\"opencell__Id__c\\\", subscription.getId());\\n\\t\\tsubscriptionJson.addProperty(\\\"opencell__Code__c\\\", subscription.getCode());\\n\\t\\tsubscriptionJson.addProperty(\\\"opencell__Description__c\\\", subscription.getDescription());\\n\\n\\t\\tif (subscription.getOffer() != null) {\\n\\t\\t\\tsubscriptionJson.addProperty(\\\"opencell__OfferCode__c\\\", subscription.getOffer().getCode());\\n\\t\\t\\tsubscriptionJson.addProperty(\\\"opencell__OfferDescription__c\\\", subscription.getOffer().getDescription());\\n\\t\\t}\\n\\t\\tif (subscription.getStatus() != null) {\\n\\t\\t\\tsubscriptionJson.addProperty(\\\"opencell__Status__c\\\", subscription.getStatus().name());\\n\\t\\t}\\n\\t\\tif (subscription.getUserAccount() != null) {\\n\\t\\t\\tCustomer customer = subscription.getUserAccount().getBillingAccount().getCustomerAccount().getCustomer();\\n\\t\\t\\tif (customer != null && StringUtils.isNotBlank(customer.getExternalRef1())) {\\n\\t\\t\\t\\tsubscriptionJson.addProperty(\\\"opencell__AccountID__c\\\", customer.getExternalRef1());\\n\\t\\t\\t} else {\\n\\t\\t\\t\\tsubscriptionJson.addProperty(\\\"opencell__AccountID__c\\\", subscription.getUserAccount().getCode());\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\tif (subscription.getStatusDate() != null) {\\n\\t\\t\\tsubscriptionJson.addProperty(\\\"opencell__StatusDate__c\\\", this.formatAsDate(subscription.getStatusDate()));\\n\\t\\t}\\n\\t\\tif (subscription.getSubscriptionDate() != null) {\\n\\t\\t\\tsubscriptionJson.addProperty(\\\"opencell__subscriptionDate__c\\\", this.formatAsDate(subscription.getSubscriptionDate()));\\n\\t\\t}\\n\\t\\tif (subscription.getTerminationDate() != null) {\\n\\t\\t\\tsubscriptionJson.addProperty(\\\"opencell__TerminationDate__c\\\", this.formatAsDate(subscription.getTerminationDate()));\\n\\t\\t}\\n\\t\\tif (subscription.getEndAgreementDate() != null) {\\n\\t\\t\\tsubscriptionJson.addProperty(\\\"opencell__EndAgreementDate__c\\\", this.formatAsDate(subscription.getEndAgreementDate()));\\n\\t\\t}\\n\\t\\tif (subscription.getSubscribedTillDate() != null) {\\n\\t\\t\\tsubscriptionJson.addProperty(\\\"opencell__SubscribedTillDate__c\\\", this.formatAsDate(subscription.getSubscribedTillDate()));\\n\\t\\t}\\n\\t\\tif (subscription.getSubscriptionTerminationReason() != null) {\\n\\t\\t\\tsubscriptionJson.addProperty(\\\"opencell__SubscriptionTerminationReason__c\\\", subscription.getSubscriptionTerminationReason().getCode());\\n\\t\\t}\\n\\n\\t\\treturn subscriptionJson;\\n\\t}\\n\\n\\t/**\\n\\t * Build the invoice json to send to SFDC\\n\\t * \\n\\t * @param invoice\\n\\t * @return\\n\\t */\\n\\tprivate JsonObject toInvoiceJson(Invoice invoice) {\\n\\n\\t\\tJsonObject invoiceJson = new JsonObject();\\n\\t\\tinvoiceJson.addProperty(\\\"opencell__DueBalance__c\\\", invoice.getDueBalance());\\n\\t\\tinvoiceJson.addProperty(\\\"opencell__AmountTax__c\\\", invoice.getAmountTax());\\n\\t\\tinvoiceJson.addProperty(\\\"opencell__Amount_With_Tax__c\\\", invoice.getAmountWithTax());\\n\\t\\tinvoiceJson.addProperty(\\\"opencell__Amount_Without_Tax__c\\\", invoice.getAmountWithoutTax());\\n\\t\\tinvoiceJson.addProperty(\\\"opencell__InvoiceNumber__c\\\", invoice.getInvoiceNumber());\\n\\t\\t// Deprecated\\n\\t\\tinvoiceJson.addProperty(\\\"opencell__Invoice_Number_del__c\\\", invoice.getInvoiceNumber());\\n\\t\\tif (invoice.getStatus() != null) {\\n\\t\\t\\tinvoiceJson.addProperty(\\\"opencell__Status__c\\\", invoice.getStatus().name());\\n\\t\\t}\\n\\t\\tif (invoice.getSubscription() != null) {\\n\\t\\t\\tinvoiceJson.addProperty(\\\"opencell__SubscriptionId__c\\\", invoice.getSubscription().getId());\\n\\t\\t\\tinvoiceJson.addProperty(\\\"opencell__ExternalRef__c\\\", invoice.getSubscription().getCode());\\n\\t\\t}\\n\\t\\tif (invoice.getPaymentMethodType() != null) {\\n\\t\\t\\tinvoiceJson.addProperty(\\\"opencell__PaymentMethod__c\\\", invoice.getPaymentMethodType().name());\\n\\t\\t}\\n\\t\\tif (invoice.getBillingAccount() != null) {\\n\\t\\t\\tCustomer customer = invoice.getBillingAccount().getCustomerAccount().getCustomer();\\n\\t\\t\\tif (customer != null && StringUtils.isNotBlank(customer.getExternalRef1())) {\\n\\t\\t\\t\\tinvoiceJson.addProperty(\\\"opencell__Account_Name__c\\\", customer.getExternalRef1());\\n\\t\\t\\t} else {\\n\\t\\t\\t\\tinvoiceJson.addProperty(\\\"opencell__Account_Name__c\\\", invoice.getBillingAccount().getCode());\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\tif (invoice.getDueDate() != null) {\\n\\t\\t\\tinvoiceJson.addProperty(\\\"opencell__DueDate__c\\\", this.formatAsDate(invoice.getDueDate()));\\n\\t\\t}\\n\\t\\tif (invoice.getInvoiceDate() != null) {\\n\\t\\t\\tinvoiceJson.addProperty(\\\"opencell__Invoice_Date__c\\\", this.formatAsDate(invoice.getInvoiceDate()));\\n\\t\\t}\\n\\t\\tif (invoice.getInvoiceType() != null) {\\n\\t\\t\\tinvoiceJson.addProperty(\\\"opencell__InvoiceType__c\\\", invoice.getInvoiceType().getCode());\\n\\t\\t}\\n\\t\\tif (invoice.getCfValue(\\\"CF_COMMENT\\\") instanceof String) {\\n\\t\\t\\tinvoiceJson.addProperty(\\\"opencell__Comment__c\\\", (String) invoice.getCfValue(\\\"CF_COMMENT\\\"));\\n\\t\\t}\\n\\n\\t\\treturn invoiceJson;\\n\\t}\\n\\n\\t/**\\n\\t * Build the accountOperation json to send to SFDC\\n\\t * \\n\\t * @param accountOperation\\n\\t * @return\\n\\t */\\n\\tprivate JsonObject toAccountOperationJson(AccountOperation accountOperation) {\\n\\n\\t\\tJsonObject accountOperationJson = new JsonObject();\\n\\t\\taccountOperationJson.addProperty(\\\"opencell__Code__c\\\", accountOperation.getCode());\\n\\t\\taccountOperationJson.addProperty(\\\"opencell__Type__c\\\", accountOperation.getType());\\n\\t\\taccountOperationJson.addProperty(\\\"opencell__Amount__c\\\", accountOperation.getAmount());\\n\\t\\taccountOperationJson.addProperty(\\\"opencell__BankLot__c\\\", accountOperation.getBankLot());\\n\\t\\taccountOperationJson.addProperty(\\\"opencell__Reference__c\\\", accountOperation.getReference());\\n\\t\\taccountOperationJson.addProperty(\\\"opencell__TaxAmount__c\\\", accountOperation.getTaxAmount());\\n\\t\\taccountOperationJson.addProperty(\\\"opencell__Description__c\\\", accountOperation.getDescription());\\n\\t\\taccountOperationJson.addProperty(\\\"opencell__BankReference__c\\\", accountOperation.getBankReference());\\n\\t\\taccountOperationJson.addProperty(\\\"opencell__MatchedAmount__c\\\", accountOperation.getMatchingAmount());\\n\\t\\taccountOperationJson.addProperty(\\\"opencell__UnmatchedAmount__c\\\", accountOperation.getUnMatchingAmount());\\n\\t\\taccountOperationJson.addProperty(\\\"opencell__AmountWithoutTax__c\\\", accountOperation.getAmountWithoutTax());\\n\\t\\tif (accountOperation.getDueDate() != null) {\\n\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__DueDate__c\\\", this.formatAsDate(accountOperation.getDueDate()));\\n\\t\\t}\\n\\t\\tif (accountOperation.getDepositDate() != null) {\\n\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__DepositDate__c\\\", this.formatAsDate(accountOperation.getDepositDate()));\\n\\t\\t}\\n\\t\\tif (accountOperation.getTransactionDate() != null) {\\n\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__TransactionDate__c\\\", this.formatAsDate(accountOperation.getTransactionDate()));\\n\\t\\t}\\n\\t\\tif (accountOperation.getBankCollectionDate() != null) {\\n\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__BankCollectionDate__c\\\", this.formatAsDate(accountOperation.getBankCollectionDate()));\\n\\t\\t}\\n\\t\\tif (accountOperation.getPaymentMethod() != null) {\\n\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__PaymentMethod__c\\\", accountOperation.getPaymentMethod().name());\\n\\t\\t}\\n\\t\\tif (accountOperation.getAccountingCode() != null) {\\n\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__AccountingCode__c\\\", accountOperation.getAccountingCode().getCode());\\n\\t\\t}\\n\\t\\tif (accountOperation.getMatchingStatus() != null) {\\n\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__MatchingStatus__c\\\", accountOperation.getMatchingStatus().name());\\n\\t\\t}\\n\\t\\tif (accountOperation.getCustomerAccount() != null) {\\n\\t\\t\\tCustomer customer = accountOperation.getCustomerAccount().getCustomer();\\n\\t\\t\\tif (customer != null && StringUtils.isNotBlank(customer.getExternalRef1())) {\\n\\t\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__AccountId__c\\\", customer.getExternalRef1());\\n\\t\\t\\t} else {\\n\\t\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__AccountId__c\\\", accountOperation.getCustomerAccount().getCode());\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\tif (accountOperation.getTransactionCategory() != null) {\\n\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__Category__c\\\", accountOperation.getTransactionCategory().name());\\n\\t\\t}\\n\\n\\t\\tif (accountOperation instanceof Payment) {\\n\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__Fees__c\\\", ((Payment) accountOperation).getFees());\\n\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__Comment__c\\\", ((Payment) accountOperation).getComment());\\n\\t\\t}\\n\\t\\tif (accountOperation instanceof RejectedPayment) {\\n\\t\\t\\tRejectedPayment rejectedPayment = (RejectedPayment) accountOperation;\\n\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__RejectedCode__c\\\", rejectedPayment.getRejectedCode());\\n\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__RejectedDescription__c\\\", rejectedPayment.getRejectedDescription());\\n\\t\\t\\tif (rejectedPayment.getRejectedType() != null) {\\n\\t\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__RejectedType__c\\\", rejectedPayment.getRejectedType().name());\\n\\t\\t\\t}\\n\\t\\t\\tif (rejectedPayment.getRejectedDate() != null) {\\n\\t\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__RejectedDate__c\\\", this.formatAsDate(rejectedPayment.getRejectedDate()));\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\tif (accountOperation instanceof RecordedInvoice) {\\n\\t\\t\\tRecordedInvoice recordedInvoice = (RecordedInvoice) accountOperation;\\n\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__NetToPay__c\\\", recordedInvoice.getNetToPay());\\n\\t\\t\\tif (recordedInvoice.getInvoiceDate() != null) {\\n\\t\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__InvoiceDate__c\\\", this.formatAsDate(recordedInvoice.getInvoiceDate()));\\n\\t\\t\\t}\\n\\t\\t\\tif (recordedInvoice.getProductionDate() != null) {\\n\\t\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__ProductionDate__c\\\", this.formatAsDate(recordedInvoice.getProductionDate()));\\n\\t\\t\\t}\\n\\t\\t\\tif (recordedInvoice.getInvoice() != null) {\\n\\t\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__InvoiceId__c\\\", recordedInvoice.getInvoice().getId());\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\tif (accountOperation instanceof OtherCreditAndCharge) {\\n\\t\\t\\tOtherCreditAndCharge occ = (OtherCreditAndCharge) accountOperation;\\n\\t\\t\\tif (occ.getOperationDate() != null) {\\n\\t\\t\\t\\taccountOperationJson.addProperty(\\\"opencell__OperationDate__c\\\", this.formatAsDate(occ.getOperationDate()));\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\treturn accountOperationJson;\\n\\t}\\n\\n\\t/**\\n\\t * Build the invoice pdf json to send to SFDC\\n\\t * \\n\\t * @param invoice\\n\\t * @param invoiceId\\n\\t * @return\\n\\t */\\n\\tprivate JsonObject toAttachmentJson(Invoice invoice, String invoiceId) {\\n\\t\\tJsonObject invoiceJson = new JsonObject();\\n\\t\\tinvoiceJson.addProperty(\\\"Name\\\", invoice.getInvoiceNumber() + \\\"_PDF\\\");\\n\\t\\tinvoiceJson.addProperty(\\\"ParentId\\\", invoiceId);\\n\\t\\tinvoiceJson.addProperty(\\\"Description\\\", \\\"INVOICE\\\");\\n\\t\\tinvoiceJson.addProperty(\\\"ContentType\\\", \\\"application/pdf\\\");\\n\\t\\tinvoiceJson.addProperty(\\\"Body\\\", Base64.getEncoder().encodeToString(invoiceService.getInvoicePdf(invoice)));\\n\\t\\t//invoiceJson.addProperty(\\\"Body\\\", Base64.encodeBase64String(invoiceService.getInvoicePdf(invoice)));\\n\\t\\treturn invoiceJson;\\n\\t}\\n\\n\\t/**\\n\\t * Format date to yyyy-MM-dd pattern\\n\\t * \\n\\t * @param date Date to format\\n\\t * @return Date as yyyy-MM-dd string\\n\\t */\\n\\tprivate String formatAsDate(Date date) {\\n\\t\\treturn DateUtils.formatDateWithPattern(date, DateUtils.DATE_PATTERN);\\n\\t}\\n\\n\\t/**\\n\\t * Format date to yyyy-MM-dd'T'hh:mm:ssXXX pattern\\n\\t * \\n\\t * @param date Date to format\\n\\t * @return Date as yyyy-MM-dd'T'hh:mm:ssXXX string\\n\\t */\\n\\tprivate String formatAsTime(Date date) {\\n\\t\\treturn DateUtils.formatDateWithPattern(date, DateUtils.DATE_TIME_PATTERN);\\n\\t}\\n\\n\\t/**\\n\\t * Gets the mondatory param.\\n\\t *\\n\\t * @param paramKey the param key\\n\\t * @return the mondatory yousign param\\n\\t * @throws MeveoApiException the meveo api exception\\n\\t */\\n\\tprivate String getMandatoryParam(String paramKey) throws MeveoApiException {\\n\\t\\treturn this.getParam(paramKey, true);\\n\\t}\\n\\n\\tprivate String getParam(String paramKey, boolean isMandatory) throws MeveoApiException {\\n\\t\\treturn this.getParam(paramKey, isMandatory, \\\"\\\");\\n\\t}\\n\\n\\tprivate String getParam(String paramKey, boolean isMandatory, String defaultValue) throws MeveoApiException {\\n\\t\\tString paramValue = paramBean.getProperty(paramKey, defaultValue);\\n\\t\\tif (isMandatory && StringUtils.isBlank(paramValue)) {\\n\\t\\t\\tthrow new MeveoApiException(\\\" Mandatory param not configured : \\\" + paramKey);\\n\\t\\t}\\n\\t\\treturn paramValue;\\n\\t}\\n\\n\\tpublic IEntity updateNoCheck(IEntity entity) throws BusinessException {\\n\\t\\tlog.info(\\\"start of update {} entity (id={}) ..\\\", entity.getClass().getSimpleName(), entity.getId());\\n\\t\\treturn em.merge(entity);\\n\\t}\\n\\n\\tprivate IEntity retrieveIfNotManaged(IEntity entity) {\\n\\n\\t\\tif (entity.getId() == null) {\\n\\t\\t\\treturn entity;\\n\\t\\t}\\n\\t\\t// Entity is managed already\\n\\t\\tif (!em.contains(entity)) {\\n\\t\\t\\tClass<? extends IEntity> entityClass = entity.getClass();\\n\\t\\t\\tlog.trace(\\\"Find {}/{} by id\\\", entityClass.getSimpleName(), entity.getId());\\n\\t\\t\\tentity = em.find(entityClass, entity.getId());\\n\\t\\t}\\n\\t\\tif (entity instanceof HibernateProxy) {\\n\\t\\t\\tentity = (IEntity) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();\\n\\t\\t}\\n\\n\\t\\treturn entity;\\n\\t}\\n\\n\\t/**********************************************************************************\\n\\t * \\n\\t * \\n\\t * All The composite request/response classes to interact with salesforce\\n\\t * \\n\\t * @author Youssef IZEM\\n\\t * @lastModifiedVersion 1.0\\n\\t **********************************************************************************/\\n\\n\\tclass CompositeRequestDto {\\n\\n\\t\\tprivate boolean allOrNone = true;\\n\\t\\tprivate boolean collateSubrequests = true;\\n\\t\\tprivate List<CompositeSubRequestDto> compositeRequest = new ArrayList<>();\\n\\n\\t\\tpublic boolean isAllOrNone() {\\n\\t\\t\\treturn allOrNone;\\n\\t\\t}\\n\\n\\t\\tpublic void setAllOrNone(boolean allOrNone) {\\n\\t\\t\\tthis.allOrNone = allOrNone;\\n\\t\\t}\\n\\n\\t\\tpublic boolean isCollateSubrequests() {\\n\\t\\t\\treturn collateSubrequests;\\n\\t\\t}\\n\\n\\t\\tpublic void setCollateSubrequests(boolean collateSubrequests) {\\n\\t\\t\\tthis.collateSubrequests = collateSubrequests;\\n\\t\\t}\\n\\n\\t\\tpublic List<CompositeSubRequestDto> getCompositeRequest() {\\n\\t\\t\\treturn compositeRequest;\\n\\t\\t}\\n\\n\\t\\tpublic void addSubRequest(CompositeSubRequestDto subRequest) {\\n\\t\\t\\tthis.compositeRequest.add(subRequest);\\n\\t\\t}\\n\\n\\t\\tpublic CompositeSubRequestDto getSubRequest(String reference) {\\n\\t\\t\\tif (compositeRequest == null || reference == null) {\\n\\t\\t\\t\\treturn null;\\n\\t\\t\\t}\\n\\t\\t\\tfor (CompositeSubRequestDto request : compositeRequest) {\\n\\t\\t\\t\\tif (reference.equals(request.getReferenceId())) {\\n\\t\\t\\t\\t\\treturn request;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\treturn null;\\n\\t\\t}\\n\\n\\t\\t@Override\\n\\t\\tpublic String toString() {\\n\\t\\t\\treturn ToStringBuilder.reflectionToString(this, ToStringStyle.NO_CLASS_NAME_STYLE);\\n\\t\\t}\\n\\t}\\n\\n\\tclass CompositeSubRequestDto {\\n\\n\\t\\tprivate String url;\\n\\t\\tprivate JsonObject body;\\n\\t\\tprivate String method;\\n\\t\\tprivate String referenceId;\\n\\n\\t\\tpublic String getUrl() {\\n\\t\\t\\treturn url;\\n\\t\\t}\\n\\n\\t\\tpublic void setUrl(String url) {\\n\\t\\t\\tthis.url = url;\\n\\t\\t}\\n\\n\\t\\tpublic JsonObject getBody() {\\n\\t\\t\\treturn body;\\n\\t\\t}\\n\\n\\t\\tpublic void setBody(JsonObject body) {\\n\\t\\t\\tthis.body = body;\\n\\t\\t}\\n\\n\\t\\tpublic String getMethod() {\\n\\t\\t\\treturn method;\\n\\t\\t}\\n\\n\\t\\tpublic void setMethod(String method) {\\n\\t\\t\\tthis.method = method;\\n\\t\\t}\\n\\n\\t\\tpublic String getReferenceId() {\\n\\t\\t\\treturn referenceId;\\n\\t\\t}\\n\\n\\t\\tpublic void setReferenceId(String referenceId) {\\n\\t\\t\\tthis.referenceId = referenceId;\\n\\t\\t}\\n\\n\\t\\t@Override\\n\\t\\tpublic String toString() {\\n\\t\\t\\treturn ToStringBuilder.reflectionToString(this, ToStringStyle.NO_CLASS_NAME_STYLE);\\n\\t\\t}\\n\\t}\\n\\n\\tclass ResponseDto {\\n\\n\\t\\tprivate List<CompositeSubRequestResponse> compositeResponse = new ArrayList<>();\\n\\n\\t\\tpublic List<CompositeSubRequestResponse> getSubCompositeResponse() {\\n\\t\\t\\treturn compositeResponse;\\n\\t\\t}\\n\\n\\t\\tpublic void setCompositeResponse(List<CompositeSubRequestResponse> compositeResponse) {\\n\\t\\t\\tthis.compositeResponse = compositeResponse;\\n\\t\\t}\\n\\n\\t\\t/**\\n\\t\\t * Get the id for the created SOBJECT\\n\\t\\t * \\n\\t\\t * @param reference\\n\\t\\t * @return\\n\\t\\t */\\n\\t\\tpublic Object getSObjectId(String reference) {\\n\\t\\t\\tif (compositeResponse == null || reference == null) {\\n\\t\\t\\t\\treturn null;\\n\\t\\t\\t}\\n\\t\\t\\tfor (CompositeSubRequestResponse response : compositeResponse) {\\n\\t\\t\\t\\tif (reference.equals(response.getReferenceId()) && response.getBody() instanceof Map) {\\n\\t\\t\\t\\t\\treturn ((Map) response.getBody()).get(\\\"id\\\");\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\treturn null;\\n\\t\\t}\\n\\n\\t\\t/**\\n\\t\\t * Get the subResponse for the created SOBJECT\\n\\t\\t * \\n\\t\\t * @param reference\\n\\t\\t * @return\\n\\t\\t */\\n\\t\\tpublic CompositeSubRequestResponse getSubResponse(String reference) {\\n\\t\\t\\tif (compositeResponse == null || reference == null) {\\n\\t\\t\\t\\treturn null;\\n\\t\\t\\t}\\n\\t\\t\\tfor (CompositeSubRequestResponse response : compositeResponse) {\\n\\t\\t\\t\\tif (reference.equals(response.getReferenceId())) {\\n\\t\\t\\t\\t\\treturn response;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t\\treturn null;\\n\\t\\t}\\n\\n\\t\\t/**\\n\\t\\t * Get the Error code for specific request\\n\\t\\t * \\n\\t\\t * @param reference\\n\\t\\t * @return\\n\\t\\t */\\n\\t\\tpublic Object getErrorCode(String reference) {\\n\\t\\t\\tif (compositeResponse == null || reference == null) {\\n\\t\\t\\t\\treturn null;\\n\\t\\t\\t}\\n\\t\\t\\tfor (CompositeSubRequestResponse response : compositeResponse) {\\n\\t\\t\\t\\treturn response.getBody().getClass().getSimpleName();\\n\\t\\t\\t}\\n\\t\\t\\treturn null;\\n\\t\\t}\\n\\n\\t\\t/**\\n\\t\\t * Checks if all requests have successfully executed\\n\\t\\t * \\n\\t\\t * @return\\n\\t\\t */\\n\\t\\tprivate boolean areAllRequestsSuccess() {\\n\\t\\t\\tif (compositeResponse == null) {\\n\\t\\t\\t\\treturn false;\\n\\t\\t\\t}\\n\\n\\t\\t\\tfor (CompositeSubRequestResponse response : compositeResponse) {\\n\\t\\t\\t\\tif (!response.isSuccess()) {\\n\\t\\t\\t\\t\\treturn false;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\n\\t\\t\\treturn true;\\n\\t\\t}\\n\\n\\t\\tprivate boolean isRequestSuccess(String referenceId) {\\n\\t\\t\\tif (compositeResponse == null || referenceId == null) {\\n\\t\\t\\t\\treturn false;\\n\\t\\t\\t}\\n\\n\\t\\t\\tfor (CompositeSubRequestResponse response : compositeResponse) {\\n\\t\\t\\t\\tif (referenceId.equals(response.getReferenceId()) && response.isSuccess()) {\\n\\t\\t\\t\\t\\treturn true;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\n\\t\\t\\treturn false;\\n\\t\\t}\\n\\n\\t\\t@Override\\n\\t\\tpublic String toString() {\\n\\t\\t\\treturn ToStringBuilder.reflectionToString(this, ToStringStyle.NO_CLASS_NAME_STYLE);\\n\\t\\t}\\n\\t}\\n\\n\\tclass CompositeSubRequestResponse {\\n\\n\\t\\tprivate String referenceId;\\n\\t\\tprivate String httpStatusCode;\\n\\t\\tprivate Object body = new ArrayList<>();\\n\\t\\tprivate Map<String, String> httpHeaders = new HashMap<>();\\n\\n\\t\\tpublic String getReferenceId() {\\n\\t\\t\\treturn referenceId;\\n\\t\\t}\\n\\n\\t\\tpublic void setReferenceId(String referenceId) {\\n\\t\\t\\tthis.referenceId = referenceId;\\n\\t\\t}\\n\\n\\t\\tpublic String getHttpStatusCode() {\\n\\t\\t\\treturn httpStatusCode;\\n\\t\\t}\\n\\n\\t\\tpublic void setHttpStatusCode(String httpStatusCode) {\\n\\t\\t\\tthis.httpStatusCode = httpStatusCode;\\n\\t\\t}\\n\\n\\t\\tpublic boolean isSuccess() {\\n\\t\\t\\treturn Response.Status.Family.SUCCESSFUL == Response.Status.Family.familyOf(Integer.parseInt(httpStatusCode));\\n\\t\\t}\\n\\n\\t\\tpublic Object getBody() {\\n\\t\\t\\treturn body;\\n\\t\\t}\\n\\n\\t\\tpublic void setBody(List<Body> body) {\\n\\t\\t\\tthis.body = body;\\n\\t\\t}\\n\\n\\t\\tpublic void setBody(Body body) {\\n\\t\\t\\tthis.body = body;\\n\\t\\t}\\n\\n\\t\\tpublic Map<String, String> getHttpHeaders() {\\n\\t\\t\\treturn httpHeaders;\\n\\t\\t}\\n\\n\\t\\tpublic void setHttpHeaders(Map<String, String> httpHeaders) {\\n\\t\\t\\tthis.httpHeaders = httpHeaders;\\n\\t\\t}\\n\\n\\t\\t@Override\\n\\t\\tpublic String toString() {\\n\\t\\t\\treturn ToStringBuilder.reflectionToString(this, ToStringStyle.NO_CLASS_NAME_STYLE);\\n\\t\\t}\\n\\t}\\n\\n\\tclass Body {\\n\\t\\tprivate String id;\\n\\t\\tprivate String message;\\n\\t\\tprivate String errorCode;\\n\\t\\tprivate boolean success;\\n\\t\\tprivate List<String> erros;\\n\\t\\tprivate List<String> fields;\\n\\n\\t\\tpublic String getId() {\\n\\t\\t\\treturn id;\\n\\t\\t}\\n\\n\\t\\tpublic void setId(String id) {\\n\\t\\t\\tthis.id = id;\\n\\t\\t}\\n\\n\\t\\tpublic String getMessage() {\\n\\t\\t\\treturn message;\\n\\t\\t}\\n\\n\\t\\tpublic void setMessage(String message) {\\n\\t\\t\\tthis.message = message;\\n\\t\\t}\\n\\n\\t\\tpublic String getErrorCode() {\\n\\t\\t\\treturn errorCode;\\n\\t\\t}\\n\\n\\t\\tpublic void setErrorCode(String errorCode) {\\n\\t\\t\\tthis.errorCode = errorCode;\\n\\t\\t}\\n\\n\\t\\tpublic boolean isSuccess() {\\n\\t\\t\\treturn success;\\n\\t\\t}\\n\\n\\t\\tpublic void setSuccess(boolean success) {\\n\\t\\t\\tthis.success = success;\\n\\t\\t}\\n\\n\\t\\tpublic List<String> getErros() {\\n\\t\\t\\treturn erros;\\n\\t\\t}\\n\\n\\t\\tpublic void setErros(List<String> erros) {\\n\\t\\t\\tthis.erros = erros;\\n\\t\\t}\\n\\n\\t\\tpublic List<String> getFields() {\\n\\t\\t\\treturn fields;\\n\\t\\t}\\n\\n\\t\\tpublic void setFields(List<String> fields) {\\n\\t\\t\\tthis.fields = fields;\\n\\t\\t}\\n\\n\\t\\t@Override\\n\\t\\tpublic String toString() {\\n\\t\\t\\treturn ToStringBuilder.reflectionToString(this, ToStringStyle.NO_CLASS_NAME_STYLE);\\n\\t\\t}\\n\\n\\t}\\n\\n\\t/**\\n\\t * \\n\\t * Token class containing the access token infos got from SFDC\\n\\t * \\n\\t * @author Youssef IZEM\\n\\t * @lastModifiedVersion 1.0\\n\\t */\\n\\tstatic class Token {\\n\\t\\tprotected Logger log = LoggerFactory.getLogger(this.getClass());\\n\\n\\t\\t@SerializedName(value = \\\"issuedAt\\\", alternate = \\\"issued_at\\\")\\n\\t\\tprivate Date issuedAt;\\n\\t\\t@SerializedName(value = \\\"tokenType\\\", alternate = \\\"token_type\\\")\\n\\t\\tprivate String tokenType;\\n\\t\\t@SerializedName(value = \\\"accessToken\\\", alternate = \\\"access_token\\\")\\n\\t\\tprivate String accessToken;\\n\\t\\t@SerializedName(value = \\\"instanceUrl\\\", alternate = \\\"instance_url\\\")\\n\\t\\tprivate String instanceUrl;\\n\\n\\t\\tpublic void reset() {\\n\\t\\t\\tthis.issuedAt = new Date();\\n\\t\\t\\tthis.tokenType = StringUtils.EMPTY;\\n\\t\\t\\tthis.accessToken = StringUtils.EMPTY;\\n\\t\\t\\tthis.instanceUrl = StringUtils.EMPTY;\\n\\t\\t}\\n\\n\\t\\tpublic Date getIssuedAt() {\\n\\t\\t\\treturn issuedAt;\\n\\t\\t}\\n\\n\\t\\tpublic String getAuth() {\\n\\t\\t\\tif (StringUtils.isBlank(this.tokenType) || StringUtils.isBlank(this.accessToken)) {\\n\\t\\t\\t\\treturn StringUtils.EMPTY;\\n\\t\\t\\t}\\n\\t\\t\\treturn this.tokenType + \\\" \\\" + this.accessToken;\\n\\t\\t}\\n\\n\\t\\tpublic void setIssuedAt(String issuedAt) {\\n\\t\\t\\tthis.issuedAt = new Date(Long.parseLong(issuedAt));\\n\\t\\t}\\n\\n\\t\\tpublic String getTokenType() {\\n\\t\\t\\treturn tokenType;\\n\\t\\t}\\n\\n\\t\\tpublic void setTokenType(String tokenType) {\\n\\t\\t\\tthis.tokenType = tokenType;\\n\\t\\t}\\n\\n\\t\\tpublic String getAccessToken() {\\n\\t\\t\\treturn accessToken;\\n\\t\\t}\\n\\n\\t\\tpublic String getMaskedAccessToken() {\\n\\t\\t\\treturn SObjectSyncingScript.maskString(accessToken);\\n\\t\\t}\\n\\n\\t\\tpublic void setAccessToken(String accessToken) {\\n\\t\\t\\tthis.accessToken = accessToken;\\n\\t\\t}\\n\\n\\t\\tpublic String getInstanceUrl() {\\n\\t\\t\\treturn instanceUrl;\\n\\t\\t}\\n\\n\\t\\tpublic void setInstanceUrl(String instanceUrl) {\\n\\t\\t\\tthis.instanceUrl = instanceUrl;\\n\\t\\t}\\n\\n\\t\\t@Override\\n\\t\\tpublic String toString() {\\n\\t\\t\\treturn String.format(\\\"%s[instanceUrl=%s, tokenType=%s, issuedAt=%s, accessToken=%s]\\\", this.getClass().getSimpleName(), this.instanceUrl, this.tokenType, this.issuedAt,\\n\\t\\t\\t\\tthis.getMaskedAccessToken());\\n\\t\\t}\\n\\t}\\n\\n\\t/**********************************************************************************\\n\\t * \\n\\t * \\n\\t * All business error messages and exception for an object syncing\\n\\t * \\n\\t * @author Youssef IZEM\\n\\t * @lastModifiedVersion 1.0\\n\\t **********************************************************************************/\\n\\n\\t/**\\n\\t * \\n\\t * Keobiz business exception\\n\\t * \\n\\t * @author Youssef IZEM\\n\\t * @lastModifiedVersion 1.0\\n\\t */\\n\\tclass SObjectSyncingException extends BusinessException {\\n\\n\\t\\tprivate static final long serialVersionUID = 1L;\\n\\n\\t\\tprivate IEntity entity;\\n\\t\\tprivate CompositeRequestDto request;\\n\\t\\tprivate Response response;\\n\\t\\tprivate String jsonResponse;\\n\\t\\tprivate boolean isSynced;\\n\\n\\t\\tpublic SObjectSyncingException() {\\n\\t\\t\\tthis.entity = null;\\n\\t\\t\\tthis.request = null;\\n\\t\\t\\tthis.isSynced = false;\\n\\t\\t\\tthis.response = null;\\n\\t\\t\\tthis.jsonResponse = null;\\n\\t\\t}\\n\\n\\t\\tpublic SObjectSyncingException(ErrorMessage errorMessage, Object... args) {\\n\\t\\t\\tsuper(MessageFormat.format(errorMessage.getMessage(), args));\\n\\t\\t}\\n\\n\\t\\tpublic SObjectSyncingException(IEntity entity, CompositeRequestDto request, Response response, String jsonResponse, boolean isSynced, ErrorMessage errorMessage,\\n\\t\\t\\t\\tObject... args) {\\n\\t\\t\\tsuper(MessageFormat.format(errorMessage.getMessage(), args));\\n\\t\\t\\tthis.entity = entity;\\n\\t\\t\\tthis.entity = entity;\\n\\t\\t}\\n\\n\\t}\\n\\n\\t/**\\n\\t * Business Error message list\\n\\t * \\n\\t * @author Youssef IZEM\\n\\t * @lastModifiedVersion 1.0\\n\\t */\\n\\tenum ErrorMessage {\\n\\n\\t\\tENTITY_SYNCING_ERROR(\\\"Error occured during the syncing process of the {0} => {1}\\\"),\\n\\n\\t\\tAUTHENTICATION_ERROR(\\\"Authentication error occured while requesting new token : [{0}:{1}] ==> Response got : {2}\\\"),\\n\\n\\t\\tAUTHENTICATION_ERROR_UNKNOWN(\\\"Unknown Authentication error occured while requesting new token : {0}\\\"),\\n\\n\\t\\tPAGE_NOT_FOUND(\\\"Target resource not found : {0}\\\"),\\n\\n\\t\\tMETHOD_NOT_ALLOWED(\\\"Method not supported by this API\\\");\\n\\n\\t\\tprivate final String message;\\n\\n\\t\\tErrorMessage(String message) {\\n\\t\\t\\tthis.message = message;\\n\\t\\t}\\n\\n\\t\\tpublic String getMessage(Object... args) {\\n\\t\\t\\treturn MessageFormat.format(message, args);\\n\\t\\t}\\n\\n\\t}\\n\\n}\\n\",\r\n\t\t\t\t\"type\": \"JAVA\"\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"notification\": {\r\n\t\t\t\t\"code\": \"SalesforceInvoiceSyncing\",\r\n\t\t\t\t\"runAsync\": false,\r\n\t\t\t\t\"description\": \"Invoice syncing with Salesforce\",\r\n\t\t\t\t\"classNameFilter\": \"org.meveo.model.billing.Invoice\",\r\n\t\t\t\t\"eventTypeFilter\": \"UPDATED\",\r\n\t\t\t\t\"elFilter\": \"#{event.invoiceNumber != null}\",\r\n\t\t\t\t\"disabled\": false,\r\n\t\t\t\t\"saveSuccessfulNotifications\": false,\r\n\t\t\t\t\"scriptInstanceCode\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"notification\": {\r\n\t\t\t\t\"code\": \"SalesforceAccountOperationSyncing\",\r\n\t\t\t\t\"runAsync\": false,\r\n\t\t\t\t\"description\": \"AO syncing with Salesforce\",\r\n\t\t\t\t\"classNameFilter\": \"org.meveo.model.payments.AccountOperation\",\r\n\t\t\t\t\"eventTypeFilter\": \"CREATED\",\r\n\t\t\t\t\"disabled\": false,\r\n\t\t\t\t\"saveSuccessfulNotifications\": false,\r\n\t\t\t\t\"scriptInstanceCode\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"notification\": {\r\n\t\t\t\t\"code\": \"SalesforceMatchedAccountOperationSyncing\",\r\n\t\t\t\t\"runAsync\": false,\r\n\t\t\t\t\"description\": \"Update AO already sent to SFDC after being matched on OC\",\r\n\t\t\t\t\"classNameFilter\": \"org.meveo.model.payments.MatchingCode\",\r\n\t\t\t\t\"eventTypeFilter\": \"CREATED\",\r\n\t\t\t\t\"disabled\": false,\r\n\t\t\t\t\"saveSuccessfulNotifications\": false,\r\n\t\t\t\t\"scriptInstanceCode\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"notification\": {\r\n\t\t\t\t\"code\": \"SalesforceCreatedSubscriptionSyncing\",\r\n\t\t\t\t\"runAsync\": false,\r\n\t\t\t\t\"description\": \"Subscription syncing with Salesforce\",\r\n\t\t\t\t\"classNameFilter\": \"org.meveo.model.billing.Subscription\",\r\n\t\t\t\t\"eventTypeFilter\": \"CREATED\",\r\n\t\t\t\t\"disabled\": false,\r\n\t\t\t\t\"saveSuccessfulNotifications\": false,\r\n\t\t\t\t\"scriptInstanceCode\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"notification\": {\r\n\t\t\t\t\"code\": \"SalesforceUpdatedSubscriptionSyncing\",\r\n\t\t\t\t\"runAsync\": false,\r\n\t\t\t\t\"description\": \"Subscription syncing with Salesforce\",\r\n\t\t\t\t\"classNameFilter\": \"org.meveo.model.billing.Subscription\",\r\n\t\t\t\t\"eventTypeFilter\": \"UPDATED\",\r\n\t\t\t\t\"disabled\": false,\r\n\t\t\t\t\"saveSuccessfulNotifications\": false,\r\n\t\t\t\t\"scriptInstanceCode\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"filter\": {\r\n\t\t\t\t\"code\": \"SFDC_INVOICE_TO_SYNC_FILTER\",\r\n\t\t\t\t\"disabled\": false,\r\n\t\t\t\t\"shared\": false,\r\n\t\t\t\t\"pollingQuery\": \"select inv from Invoice inv where (inv.cfValues is not null and inv.cfValues like '%\\\"CF_ENTITY_IS_SYNCED\\\":[{\\\"boolean\\\":false}]%')\",\r\n\t\t\t\t\"inputXml\": \"<filter>\\r\\n   <disabled>false<\\/disabled><secondarySelectors\\/><\\/filter>\"\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"filter\": {\r\n\t\t\t\t\"code\": \"SFDC_SUBSCRIPTION_TO_SYNC_FILTER\",\r\n\t\t\t\t\"disabled\": false,\r\n\t\t\t\t\"shared\": false,\r\n\t\t\t\t\"pollingQuery\": \"select sub from Subscription sub where (sub.cfValues is not null and sub.cfValues like '%\\\"CF_ENTITY_IS_SYNCED\\\":[{\\\"boolean\\\":true}]%') AND (ao.cfValues is not null and ao.cfValues like '%\\\"CF_ENTITY_IS_SYNCED\\\":[{\\\"boolean\\\":false}]%')\",\r\n\t\t\t\t\"inputXml\": \"<filter>\\r\\n   <disabled>false<\\/disabled><secondarySelectors\\/><\\/filter>\"\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"filter\": {\r\n\t\t\t\t\"code\": \"SFDC_ACCOUNT_OPERATION_TO_SYNC_FILTER\",\r\n\t\t\t\t\"disabled\": false,\r\n\t\t\t\t\"shared\": false,\r\n\t\t\t\t\"pollingQuery\": \"select ao from AccountOperation ao where (ao.cfValues is not null and ao.cfValues like '%\\\"CF_ENTITY_IS_SYNCED\\\":[{\\\"boolean\\\":false}]%')\",\r\n\t\t\t\t\"inputXml\": \"<filter>\\r\\n   <disabled>false<\\/disabled><secondarySelectors\\/><\\/filter>\"\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"jobInstance\": {\r\n\t\t\t\t\"code\": \"SalesforceInvoiceSyncingJob\",\r\n\t\t\t\t\"jobTemplate\": \"FilteringJob\",\r\n\t\t\t\t\"disabled\": true,\r\n\t\t\t\t\"customFields\": {\r\n\t\t\t\t\t\"customField\": [\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\"code\": \"FilteringJob_recordVariableName\",\r\n\t\t\t\t\t\t\t\"stringValue\": \"CONTEXT_ENTITY\"\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\"code\": \"FilteringJob_filter\",\r\n\t\t\t\t\t\t\t\"entityReferenceValue\": {\r\n\t\t\t\t\t\t\t\t\"classname\": \"org.meveo.model.filter.Filter\",\r\n\t\t\t\t\t\t\t\t\"code\": \"SFDC_INVOICE_TO_SYNC_FILTER\"\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\"code\": \"FilteringJob_script\",\r\n\t\t\t\t\t\t\t\"entityReferenceValue\": {\r\n\t\t\t\t\t\t\t\t\"classname\": \"org.meveo.model.scripts.ScriptInstance\",\r\n\t\t\t\t\t\t\t\t\"code\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t]\r\n\t\t\t\t},\r\n\t\t\t\t\"limitToSingleNode\": true,\r\n\t\t\t\t\"verboseReport\": true\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"jobInstance\": {\r\n\t\t\t\t\"code\": \"SalesforceSubscriptionSyncingJob\",\r\n\t\t\t\t\"jobTemplate\": \"FilteringJob\",\r\n\t\t\t\t\"disabled\": true,\r\n\t\t\t\t\"customFields\": {\r\n\t\t\t\t\t\"customField\": [\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\"code\": \"FilteringJob_recordVariableName\",\r\n\t\t\t\t\t\t\t\"stringValue\": \"CONTEXT_ENTITY\"\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\"code\": \"FilteringJob_filter\",\r\n\t\t\t\t\t\t\t\"entityReferenceValue\": {\r\n\t\t\t\t\t\t\t\t\"classname\": \"org.meveo.model.filter.Filter\",\r\n\t\t\t\t\t\t\t\t\"code\": \"SFDC_SUBSCRIPTION_TO_SYNC_FILTER\"\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\"code\": \"FilteringJob_script\",\r\n\t\t\t\t\t\t\t\"entityReferenceValue\": {\r\n\t\t\t\t\t\t\t\t\"classname\": \"org.meveo.model.scripts.ScriptInstance\",\r\n\t\t\t\t\t\t\t\t\"code\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t]\r\n\t\t\t\t},\r\n\t\t\t\t\"limitToSingleNode\": true,\r\n\t\t\t\t\"verboseReport\": true\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"jobInstance\": {\r\n\t\t\t\t\"code\": \"SalesforceAccountOperationSyncingJob\",\r\n\t\t\t\t\"jobTemplate\": \"FilteringJob\",\r\n\t\t\t\t\"disabled\": true,\r\n\t\t\t\t\"customFields\": {\r\n\t\t\t\t\t\"customField\": [\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\"code\": \"FilteringJob_filter\",\r\n\t\t\t\t\t\t\t\"entityReferenceValue\": {\r\n\t\t\t\t\t\t\t\t\"classname\": \"org.meveo.model.filter.Filter\",\r\n\t\t\t\t\t\t\t\t\"code\": \"SFDC_ACCOUNT_OPERATION_TO_SYNC_FILTER\"\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\"code\": \"FilteringJob_recordVariableName\",\r\n\t\t\t\t\t\t\t\"stringValue\": \"CONTEXT_ENTITY\"\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t\"code\": \"FilteringJob_script\",\r\n\t\t\t\t\t\t\t\"entityReferenceValue\": {\r\n\t\t\t\t\t\t\t\t\"classname\": \"org.meveo.model.scripts.ScriptInstance\",\r\n\t\t\t\t\t\t\t\t\"code\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t]\r\n\t\t\t\t},\r\n\t\t\t\t\"limitToSingleNode\": true,\r\n\t\t\t\t\"verboseReport\": true\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"customFieldTemplate\": {\r\n\t\t\t\t\"code\": \"CF_SFDC_ACCOUNT_FIELDS\",\r\n\t\t\t\t\"description\": \"Salesforce account fields\",\r\n\t\t\t\t\"disabled\": false,\r\n\t\t\t\t\"fieldType\": \"STRING\",\r\n\t\t\t\t\"appliesTo\": \"Customer\",\r\n\t\t\t\t\"useInheritedAsDefaultValue\": false,\r\n\t\t\t\t\"storageType\": \"MAP\",\r\n\t\t\t\t\"valueRequired\": false,\r\n\t\t\t\t\"uniqueConstraint\": false,\r\n\t\t\t\t\"versionable\": false,\r\n\t\t\t\t\"triggerEndPeriodEvent\": false,\r\n\t\t\t\t\"allowEdit\": true,\r\n\t\t\t\t\"hideOnNew\": false,\r\n\t\t\t\t\"maxValue\": 200\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"entityCustomAction\": {\r\n\t\t\t\t\"code\": \"INOICE_SYNCING_ACTION\",\r\n\t\t\t\t\"appliesTo\": \"Invoice\",\r\n\t\t\t\t\"label\": \"Synchronizer\",\r\n\t\t\t\t\"labelsTranslated\": [\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\"languageCode\": \"FRA\",\r\n\t\t\t\t\t\t\"description\": \"Synchronizer\"\r\n\t\t\t\t\t}\r\n\t\t\t\t],\r\n\t\t\t\t\"script\": {\r\n\t\t\t\t\t\"code\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"entityCustomAction\": {\r\n\t\t\t\t\"code\": \"ACCOUNT_OPERATION_SYNCING_ACTION\",\r\n\t\t\t\t\"appliesTo\": \"AccountOperation\",\r\n\t\t\t\t\"label\": \"Synchronizer\",\r\n\t\t\t\t\"labelsTranslated\": [\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\"languageCode\": \"FRA\",\r\n\t\t\t\t\t\t\"description\": \"Synchronizer\"\r\n\t\t\t\t\t}\r\n\t\t\t\t],\r\n\t\t\t\t\"script\": {\r\n\t\t\t\t\t\"code\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"entityCustomAction\": {\r\n\t\t\t\t\"code\": \"SUBSCRIPTION_SYNCING_ACTION\",\r\n\t\t\t\t\"appliesTo\": \"Subscription\",\r\n\t\t\t\t\"label\": \"Synchronizer\",\r\n\t\t\t\t\"labelsTranslated\": [\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\"languageCode\": \"FRA\",\r\n\t\t\t\t\t\t\"description\": \"Synchronizer\"\r\n\t\t\t\t\t}\r\n\t\t\t\t],\r\n\t\t\t\t\"script\": {\r\n\t\t\t\t\t\"code\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"customFieldTemplate\": {\r\n\t\t\t\t\"code\": \"CF_ENTITY_IS_SYNCED\",\r\n\t\t\t\t\"description\": \"Has this Subscription already been synced ?\",\r\n\t\t\t\t\"fieldType\": \"BOOLEAN\",\r\n\t\t\t\t\"appliesTo\": \"Subscription\",\r\n\t\t\t\t\"storageType\": \"SINGLE\",\r\n\t\t\t\t\"valueRequired\": \"false\",\r\n\t\t\t\t\"versionable\": \"false\",\r\n\t\t\t\t\"triggerEndPeriodEvent\": \"false\",\r\n\t\t\t\t\"allowEdit\": \"true\",\r\n\t\t\t\t\"hideOnNew\": \"true\",\r\n\t\t\t\t\"cacheValue\": \"false\"\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"customFieldTemplate\": {\r\n\t\t\t\t\"code\": \"CF_ENTITY_IS_SYNCED\",\r\n\t\t\t\t\"description\": \"Has this AO already been synced ?\",\r\n\t\t\t\t\"fieldType\": \"BOOLEAN\",\r\n\t\t\t\t\"appliesTo\": \"AccountOperation\",\r\n\t\t\t\t\"storageType\": \"SINGLE\",\r\n\t\t\t\t\"valueRequired\": \"false\",\r\n\t\t\t\t\"versionable\": \"false\",\r\n\t\t\t\t\"triggerEndPeriodEvent\": \"false\",\r\n\t\t\t\t\"allowEdit\": \"true\",\r\n\t\t\t\t\"hideOnNew\": \"true\",\r\n\t\t\t\t\"cacheValue\": \"false\"\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"customFieldTemplate\": {\r\n\t\t\t\t\"code\": \"CF_ENTITY_IS_SYNCED\",\r\n\t\t\t\t\"description\": \"Has this invoice already been synced ?\",\r\n\t\t\t\t\"fieldType\": \"BOOLEAN\",\r\n\t\t\t\t\"appliesTo\": \"Invoice\",\r\n\t\t\t\t\"storageType\": \"SINGLE\",\r\n\t\t\t\t\"valueRequired\": \"false\",\r\n\t\t\t\t\"versionable\": \"false\",\r\n\t\t\t\t\"triggerEndPeriodEvent\": \"false\",\r\n\t\t\t\t\"allowEdit\": \"true\",\r\n\t\t\t\t\"hideOnNew\": \"true\",\r\n\t\t\t\t\"cacheValue\": \"false\"\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"customFieldTemplate\": {\r\n\t\t\t\t\"code\": \"CF_SFDC_INVOICE_ID\",\r\n\t\t\t\t\"description\": \"SFDC Invoice ID\",\r\n\t\t\t\t\"fieldType\": \"STRING\",\r\n\t\t\t\t\"appliesTo\": \"Invoice\",\r\n\t\t\t\t\"storageType\": \"SINGLE\",\r\n\t\t\t\t\"valueRequired\": \"false\",\r\n\t\t\t\t\"versionable\": \"false\",\r\n\t\t\t\t\"triggerEndPeriodEvent\": \"false\",\r\n\t\t\t\t\"allowEdit\": \"false\",\r\n\t\t\t\t\"hideOnNew\": \"false\",\r\n\t\t\t\t\"cacheValue\": \"false\"\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"customFieldTemplate\": {\r\n\t\t\t\t\"code\": \"CF_SFDC_ATTACHMENT_ID\",\r\n\t\t\t\t\"description\": \"SFDC Attachment ID\",\r\n\t\t\t\t\"fieldType\": \"STRING\",\r\n\t\t\t\t\"appliesTo\": \"Invoice\",\r\n\t\t\t\t\"storageType\": \"SINGLE\",\r\n\t\t\t\t\"valueRequired\": \"false\",\r\n\t\t\t\t\"versionable\": \"false\",\r\n\t\t\t\t\"triggerEndPeriodEvent\": \"false\",\r\n\t\t\t\t\"allowEdit\": \"false\",\r\n\t\t\t\t\"hideOnNew\": \"false\",\r\n\t\t\t\t\"cacheValue\": \"false\"\r\n\t\t\t}\r\n\t\t},\r\n\t\t{\r\n\t\t\t\"customEntityTemplate\": {\r\n\t\t\t\t\"code\": \"SYNCING_ERRORS\",\r\n\t\t\t\t\"name\": \"SFDC Syncing errors\",\r\n\t\t\t\t\"storeAsTable\": true,\r\n\t\t\t\t\"fields\": [\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\"code\": \"entity_id\",\r\n\t\t\t\t\t\t\"description\": \"Entity id\",\r\n\t\t\t\t\t\t\"fieldType\": \"STRING\",\r\n\t\t\t\t\t\t\"appliesTo\": \"CE_SYNCING_ERRORS\",\r\n\t\t\t\t\t\t\"storageType\": \"SINGLE\",\r\n\t\t\t\t\t\t\"allowEdit\": false,\r\n\t\t\t\t\t\t\"maxValue\": 50\r\n\t\t\t\t\t},\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\"code\": \"entity_code\",\r\n\t\t\t\t\t\t\"description\": \"Entity code\",\r\n\t\t\t\t\t\t\"fieldType\": \"STRING\",\r\n\t\t\t\t\t\t\"appliesTo\": \"CE_SYNCING_ERRORS\",\r\n\t\t\t\t\t\t\"storageType\": \"SINGLE\",\r\n\t\t\t\t\t\t\"allowEdit\": false,\r\n\t\t\t\t\t\t\"maxValue\": 255\r\n\t\t\t\t\t},\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\"code\": \"entity_type\",\r\n\t\t\t\t\t\t\"description\": \"Entity type\",\r\n\t\t\t\t\t\t\"fieldType\": \"STRING\",\r\n\t\t\t\t\t\t\"appliesTo\": \"CE_SYNCING_ERROS\",\r\n\t\t\t\t\t\t\"storageType\": \"SINGLE\",\r\n\t\t\t\t\t\t\"allowEdit\": false,\r\n\t\t\t\t\t\t\"maxValue\": 50\r\n\t\t\t\t\t},\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\"code\": \"syncing_date\",\r\n\t\t\t\t\t\t\"description\": \"Syncing date\",\r\n\t\t\t\t\t\t\"fieldType\": \"STRING\",\r\n\t\t\t\t\t\t\"appliesTo\": \"CE_SYNCING_ERROS\",\r\n\t\t\t\t\t\t\"storageType\": \"SINGLE\",\r\n\t\t\t\t\t\t\"allowEdit\": false,\r\n\t\t\t\t\t\t\"maxValue\": 50\r\n\t\t\t\t\t},\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\"code\": \"request_path_info\",\r\n\t\t\t\t\t\t\"description\": \"Request path info\",\r\n\t\t\t\t\t\t\"fieldType\": \"STRING\",\r\n\t\t\t\t\t\t\"appliesTo\": \"CE_SYNCING_ERROS\",\r\n\t\t\t\t\t\t\"storageType\": \"SINGLE\",\r\n\t\t\t\t\t\t\"allowEdit\": false,\r\n\t\t\t\t\t\t\"maxValue\": 255\r\n\t\t\t\t\t},\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\"code\": \"request_body\",\r\n\t\t\t\t\t\t\"description\": \"Request body\",\r\n\t\t\t\t\t\t\"fieldType\": \"STRING\",\r\n\t\t\t\t\t\t\"appliesTo\": \"CE_SYNCING_ERROS\",\r\n\t\t\t\t\t\t\"storageType\": \"SINGLE\",\r\n\t\t\t\t\t\t\"allowEdit\": false,\r\n\t\t\t\t\t\t\"maxValue\": 1024\r\n\t\t\t\t\t},\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\"code\": \"response_status\",\r\n\t\t\t\t\t\t\"description\": \"Response status\",\r\n\t\t\t\t\t\t\"fieldType\": \"STRING\",\r\n\t\t\t\t\t\t\"appliesTo\": \"CE_SYNCING_ERROS\",\r\n\t\t\t\t\t\t\"storageType\": \"SINGLE\",\r\n\t\t\t\t\t\t\"allowEdit\": false,\r\n\t\t\t\t\t\t\"maxValue\": 100\r\n\t\t\t\t\t},\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\"code\": \"response_message\",\r\n\t\t\t\t\t\t\"description\": \"Response message\",\r\n\t\t\t\t\t\t\"fieldType\": \"STRING\",\r\n\t\t\t\t\t\t\"appliesTo\": \"CE_SYNCING_ERROS\",\r\n\t\t\t\t\t\t\"storageType\": \"SINGLE\",\r\n\t\t\t\t\t\t\"allowEdit\": false,\r\n\t\t\t\t\t\t\"maxValue\": 255\r\n\t\t\t\t\t},\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\"code\": \"response_body\",\r\n\t\t\t\t\t\t\"description\": \"Response body\",\r\n\t\t\t\t\t\t\"fieldType\": \"STRING\",\r\n\t\t\t\t\t\t\"appliesTo\": \"CE_SYNCING_ERROS\",\r\n\t\t\t\t\t\t\"storageType\": \"SINGLE\",\r\n\t\t\t\t\t\t\"allowEdit\": false,\r\n\t\t\t\t\t\t\"maxValue\": 1024\r\n\t\t\t\t\t}\r\n\t\t\t\t]\r\n\t\t\t}\r\n\t\t}\r\n\t]\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{opencell.url}}/module/install",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"module",
										"install"
									]
								}
							},
							"response": []
						},
						{
							"name": "BusinessAccountModelModule",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "PUT",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"code\": \"{{request.label}}\",\r\n    \"description\": \"Gets all BAM modules\",\r\n    \"license\": \"COM\",\r\n    \"moduleItems\": [\r\n    \t{\r\n    \t\t\"script\": {\r\n                \"description\": \"API allowing to get all BAM modules\",\r\n                \"script\": \"package org.opencell.eeko.service.script;\\n\\nimport java.util.ArrayList;\\nimport java.util.List;\\nimport java.util.Map;\\n\\nimport org.apache.http.HttpStatus;\\nimport org.meveo.api.dto.ActionStatus;\\nimport org.meveo.api.dto.ActionStatusEnum;\\nimport org.meveo.api.dto.account.BusinessAccountModelDto;\\nimport org.meveo.api.dto.module.MeveoModuleDto;\\nimport org.meveo.api.dto.response.module.MeveoModuleDtosResponse;\\nimport org.meveo.api.exception.MeveoApiException;\\nimport org.meveo.api.module.MeveoModuleApi;\\nimport org.meveo.commons.utils.MillisDate;\\nimport org.meveo.model.crm.BusinessAccountModel;\\nimport org.meveo.model.notification.InboundRequest;\\nimport org.meveo.service.script.Script;\\n\\nimport com.google.gson.Gson;\\nimport com.google.gson.GsonBuilder;\\nimport com.google.gson.JsonArray;\\nimport com.google.gson.JsonObject;\\n\\n\\/**\\n * Api permettant de récupérer la liste des BusinessAccountModel \\n * => En attendant de corriger le bug core #5203\\n * \\n * @author Youssef IZEM\\n * @lastModifiedVersion 1.0\\n *\\/\\npublic class BusinessAccountModelScript extends Script {\\n\\n\\tprivate static final long serialVersionUID = 1L;\\n\\n\\tprivate transient MeveoModuleApi meveoModuleApi = (MeveoModuleApi) getServiceInterface(\\\"MeveoModuleApi\\\");\\n\\n\\t@Override\\n\\tpublic void execute(Map<String, Object> context) {\\n\\n\\t\\tlog.info(\\\">>>>>  BusinessAccountModelScript is running <<<<<<<\\\");\\n\\n\\t\\tInboundRequest inboundRequest = (InboundRequest) context.get(\\\"entityOrEvent\\\");\\n\\t\\tString httpPath = inboundRequest.getPathInfo();\\n\\t\\tString httpMethod = inboundRequest.getMethod();\\n\\t\\tString jsonContent = inboundRequest.getBody();\\n\\t\\tMap<String, String> parameters = inboundRequest.getParameters();\\n\\n\\t\\tlog.info(\\\"Http Call Detail : [Method={}, path={},QueryParams={}, body={}]\\\", httpMethod, httpPath, parameters, jsonContent);\\n\\n\\t\\tint httpStatus = HttpStatus.SC_OK;\\n\\t\\tActionStatus actionStatus = new ActionStatus();\\n\\t\\tString jsonResponse = \\\"\\\";\\n\\n\\t\\ttry {\\n\\n\\t\\t\\tjsonResponse = listModules();\\n\\n\\t\\t} catch (Exception ex) {\\n\\t\\t\\thttpStatus = HttpStatus.SC_BAD_REQUEST;\\n\\t\\t\\tactionStatus.setStatus(ActionStatusEnum.FAIL);\\n\\t\\t\\tactionStatus.setMessage(ex.getMessage());\\n\\t\\t\\tif (ex instanceof MeveoApiException) {\\n\\t\\t\\t\\tactionStatus.setErrorCode(((MeveoApiException) ex).getErrorCode());\\n\\t\\t\\t}\\n\\t\\t}\\n\\n\\t\\ttry {\\n\\t\\t\\tinboundRequest.setResponseStatus(httpStatus);\\n\\t\\t\\tinboundRequest.setResponseBody(jsonResponse);\\n\\n\\t\\t} catch (Exception e) {\\n\\t\\t\\tinboundRequest.setResponseStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);\\n\\t\\t\\tinboundRequest.setResponseBody(\\\"Error writing response to inboundRequest response. reason:\\\" + e.getMessage());\\n\\t\\t}\\n\\n\\t\\tlog.info(\\\">>>>>  BusinessAccountModelScript has been successfully completed <<<<<<<\\\");\\n\\t}\\n\\n\\t\\/**\\n\\t * Gets BAM modules list\\n\\t * \\n\\t * @return\\n\\t *\\/\\n\\tprivate String listModules() {\\n\\t\\tlog.info(\\\">>>>>>>  listModules method is running <<<<<<<\\\");\\n\\n\\t\\tMeveoModuleDtosResponse result = meveoModuleApi.list(BusinessAccountModel.class);\\n\\t\\tJsonArray jsonModules = new JsonArray();\\n\\n\\t\\tfor (MeveoModuleDto module : result.getModules()) {\\n\\t\\t\\tif (module instanceof BusinessAccountModelDto) {\\n\\t\\t\\t\\tJsonObject object = new JsonObject();\\n\\t\\t\\t\\tobject.add(\\\"businessAccountModel\\\", gson.toJsonTree(module));\\n\\t\\t\\t\\tjsonModules.add(object);\\n\\t\\t\\t}\\n\\t\\t}\\n\\t\\tJsonObject response = new JsonObject();\\n\\t\\tJsonObject status = new JsonObject();\\n\\n\\t\\tActionStatus actionStatus = new ActionStatus();\\n\\t\\tactionStatus.setStatus(ActionStatusEnum.SUCCESS);\\n\\t\\tstatus.add(\\\"status\\\", gson.toJsonTree(\\\"SUCCESS\\\"));\\n\\n\\t\\tresponse.add(\\\"actionStatus\\\", status);\\n\\t\\tresponse.add(\\\"modules\\\", jsonModules);\\n\\n\\t\\tlog.info(\\\">>>>>>>  findInvoice method  has been successfully completed <<<<<<<\\\");\\n\\t\\treturn gson.toJson(response);\\n\\t}\\n\\n\\t\\/**\\n\\t * Gets BAM modules list\\n\\t * \\n\\t * @return\\n\\t *\\/\\n\\tprivate List<MeveoModuleDto> listModules_v1() {\\n\\t\\tlog.info(\\\">>>>>>>  listModules method is running <<<<<<<\\\");\\n\\n\\t\\tList<MeveoModuleDto> modules = new ArrayList<>();\\n\\t\\tMeveoModuleDtosResponse result = meveoModuleApi.list(BusinessAccountModel.class);\\n\\n\\t\\tfor (MeveoModuleDto module : result.getModules()) {\\n\\t\\t\\tif (module instanceof BusinessAccountModelDto) {\\n\\t\\t\\t\\tmodules.add(module);\\n\\t\\t\\t}\\n\\t\\t}\\n\\n\\t\\tlog.info(\\\">>>>>>>  findInvoice method  has been successfully completed <<<<<<<\\\");\\n\\t\\treturn modules;\\n\\t}\\n\\n\\tstatic Gson gson = null;\\n\\tstatic {\\n\\t\\tGsonBuilder builder = new GsonBuilder();\\n\\t\\tbuilder.setVersion(1.0);\\n\\t\\tgson = builder.setPrettyPrinting().registerTypeAdapter(java.util.Date.class, new MillisDate()).create();\\n\\t}\\n\\n}\\n\",\r\n                \"type\": \"JAVA\"\r\n            }\r\n        },\r\n        {\r\n        \t\"notification\" : {\r\n\t\t\t    \"code\": \"BusinessAccountModelInbound\",\r\n\t\t\t    \"description\": \"API allowing to get all BAM modules\",\r\n\t\t\t    \"classNameFilter\": \"org.meveo.model.notification.InboundRequest\",\r\n\t\t\t    \"eventTypeFilter\": \"INBOUND_REQ\",\r\n\t\t\t    \"elFilter\": \"#{event.pathInfo.equals(\\\"/account/businessAccountModel/list\\\")}\",\r\n\t\t\t    \"scriptInstanceCode\": \"org.opencell.eeko.service.script.BusinessAccountModelScript\"\r\n        \t}\r\n        }\r\n        \r\n    ]\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{opencell.url}}/module/install",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"module",
										"install"
									]
								}
							},
							"response": []
						}
					]
				}
			],
			"event": [
				{
					"listen": "prerequest",
					"script": {
						"type": "text/javascript",
						"exec": [
							""
						]
					}
				},
				{
					"listen": "test",
					"script": {
						"type": "text/javascript",
						"exec": [
							"let skipTest = pm.collectionVariables.get('skipTest');",
							"",
							"(skipTest ? pm.test.skip : pm.test('Status code is ' + pm.response.code, function() {",
							"    pm.expect(pm.response.code).to.be.oneOf([200, 201]);",
							"}));",
							"",
							"(skipTest ? pm.test.skip : pm.test(\"Successful request\", function () {",
							"    var jsonData = pm.response.json();",
							"    if (responseBody.has(\"actionStatus\")) {",
							"        pm.expect(jsonData.actionStatus.status).to.eql(\"SUCCESS\");",
							"    } else {",
							"        pm.expect(jsonData.status).to.eql(\"SUCCESS\");",
							"    }",
							"}));"
						]
					}
				}
			]
		}
	],
	"auth": {
		"type": "basic",
		"basic": [
			{
				"key": "password",
				"value": "{{opencell.password}}",
				"type": "string"
			},
			{
				"key": "username",
				"value": "{{opencell.username}}",
				"type": "string"
			},
			{
				"key": "saveHelperData",
				"type": "any"
			},
			{
				"key": "showPassword",
				"value": false,
				"type": "boolean"
			}
		]
	},
	"event": [
		{
			"listen": "prerequest",
			"script": {
				"type": "text/javascript",
				"exec": [
					"var now=new Date();",
					"pm.globals.set(\"timestamp.iso\", now.toISOString());",
					"pm.globals.set(\"request.label\", pm.info.requestName);",
					"var parts = pm.info.requestName.split(\"|\");",
					"for(let i=0; i<parts.length; i++) {",
					"    pm.globals.set(\"wait\", 0);",
					"    pm.globals.set(\"request.label.\"+i, parts[i]);",
					"    if(parts[i].indexOf(\"=\") != -1 ){",
					"        propName = parts[i].split(\"=\")[0].trim();",
					"        propValue = parts[i].split(\"=\")[1];",
					"        pm.globals.set(propName, propValue);",
					"    }",
					"}"
				]
			}
		},
		{
			"listen": "test",
			"script": {
				"type": "text/javascript",
				"exec": [
					"let skipTest = pm.environment.get('skipTest');",
					"",
					"(skipTest ? pm.test.skip : pm.test('Status code is ' + pm.response.code, function() {",
					"    pm.expect(pm.response.code).to.be.oneOf([200, 201]);",
					"}));",
					"",
					"(skipTest ? pm.test.skip : pm.test(\"Successful request\", function () {",
					"    var jsonData = pm.response.json();",
					"    if (responseBody.has(\"actionStatus\")) {",
					"        pm.expect(jsonData.actionStatus.status).to.eql(\"SUCCESS\");",
					"    } else {",
					"        pm.expect(jsonData.status).to.eql(\"SUCCESS\");",
					"    }",
					"}));"
				]
			}
		}
	],
	"variable": [
		{
			"key": "skipTest",
			"value": ""
		}
	]
}