{
	"info": {
		"_postman_id": "16351268-83b9-42e8-821a-0aceead21baf",
		"name": "EKKO",
		"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": "Scripts",
			"item": [
				{
					"name": "Rating",
					"item": [
						{
							"name": "EkkoRatingScript",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/xml"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "<ScriptInstance code=\"com.opencellsoft.service.ekko.rating.EkkoRatingScript\" description=\"Ekko Rating Script\">\r\n            <type>JAVA</type>\r\n            <script>\r\n            <![CDATA[package com.opencellsoft.service.ekko.rating;\r\n\r\nimport java.math.BigDecimal;\r\nimport java.util.Map;\r\n\r\nimport org.meveo.admin.exception.BusinessException;\r\nimport org.meveo.model.billing.WalletOperation;\r\nimport org.meveo.model.shared.DateUtils;\r\nimport org.meveo.service.script.Script;\r\n\r\n\r\n\r\n/**\r\n * \r\n * @author anasseh\r\n *\r\n */\r\npublic class EkkoRatingScript extends Script {\r\n\r\n\tprivate static final long serialVersionUID = 1L;\r\n\r\n\t@Override\r\n\tpublic void execute(Map<String, Object> context) throws BusinessException {\r\n\r\n\t\tWalletOperation wo = (WalletOperation) context.get(Script.CONTEXT_ENTITY);\r\n\r\n\t\tif (wo.getSubscription() == null) {\r\n\t\t\tthrow new BusinessException(\"wo.subscription is null\");\r\n\t\t}\r\n\t\tMap<String, Double> prices = (Map<String, Double>) wo.getSubscription().getCfValue(\"CF_SUB_PRICES\");\r\n\t\tMap<String, String> labels = (Map<String, String>) wo.getSubscription().getCfValue(\"CF_SUB_LABELS\");\r\n\r\n\t\tlog.info(\"woCode:{}, operationDate:{}, subscriptionDate:{}, CF prices:{} \", wo.getCode(),DateUtils.formatAsDate(wo.getOperationDate()),DateUtils.formatAsDate(wo.getSubscriptionDate()), prices);\r\n\r\n\t\two.setDescription(labels.get(wo.getCode()));\r\n\t\t\t\t\r\n\t\tif (wo.getCode().startsWith(\"CH_REC\") && DateUtils.getMonthFromDate(wo.getOperationDate()).intValue() == DateUtils.getMonthFromDate(wo.getSubscriptionDate()).intValue()\r\n\t\t\t\t&& DateUtils.getYearFromDate(wo.getOperationDate()).intValue() == DateUtils.getYearFromDate(wo.getSubscriptionDate()).intValue()) {\r\n\r\n\t\t\two.setAmountTax(BigDecimal.ZERO);\r\n\t\t\two.setAmountWithoutTax(BigDecimal.ZERO);\r\n\t\t\two.setAmountWithTax(BigDecimal.ZERO);\r\n\r\n\t\t\two.setUnitAmountTax(BigDecimal.ZERO);\r\n\t\t\two.setUnitAmountWithoutTax(BigDecimal.ZERO);\r\n\t\t\two.setUnitAmountWithTax(BigDecimal.ZERO);\r\n\t\t} else {\r\n\r\n\t\t\two.setAmountTax(new BigDecimal(prices.get(wo.getCode() + \"_T\")));\r\n\t\t\two.setAmountWithoutTax(new BigDecimal(prices.get(wo.getCode() + \"_HT\")));\r\n\t\t\two.setAmountWithTax(new BigDecimal(prices.get(wo.getCode() + \"_TTC\")));\r\n\r\n\t\t\two.setUnitAmountTax(new BigDecimal(prices.get(wo.getCode() + \"_T\")));\r\n\t\t\two.setUnitAmountWithoutTax(new BigDecimal(prices.get(wo.getCode() + \"_HT\")));\r\n\t\t\two.setUnitAmountWithTax(new BigDecimal(prices.get(wo.getCode() + \"_TTC\")));\r\n\t\t}\r\n\t}\r\n}\r\n\r\n]]>\r\n            </script>\r\n         </ScriptInstance>\r\n\r\n",
									"options": {
										"raw": {
											"language": "xml"
										}
									}
								},
								"url": {
									"raw": "{{opencell.url}}/scriptInstance/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"scriptInstance",
										"createOrUpdate"
									]
								}
							},
							"response": []
						}
					]
				},
				{
					"name": "Invoicing",
					"item": [
						{
							"name": "EkkoBillingCycleScript",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/xml"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "<ScriptInstance code=\"com.opencellsoft.service.ekko.invoicing.EkkoBillingCycleScript\" description=\"Ekko Invoicing Script\">\r\n            <type>JAVA</type>\r\n            <script>\r\n            <![CDATA[package com.opencellsoft.service.ekko.invoicing;\r\n\r\nimport java.util.ArrayList;\r\nimport java.util.Calendar;\r\nimport java.util.Date;\r\nimport java.util.List;\r\nimport java.util.Map;\r\n\r\nimport org.meveo.admin.exception.BusinessException;\r\nimport org.meveo.model.billing.InvoiceType;\r\nimport org.meveo.model.billing.RatedTransaction;\r\nimport org.meveo.model.billing.RatedTransactionGroup;\r\nimport org.meveo.model.billing.Subscription;\r\nimport org.meveo.model.shared.DateUtils;\r\nimport org.meveo.service.billing.impl.InvoiceTypeService;\r\nimport org.meveo.service.catalog.impl.CalendarBankingService;\r\nimport org.meveo.service.script.Script;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n\r\n/**\r\n * \r\n * @author anasseh\r\n *  26/01/2022  : invoice amount zero\r\n */\r\npublic class EkkoBillingCycleScript extends Script {\r\n\r\n\tprivate static final long serialVersionUID = 1L;\r\n\tprivate static final String INV_TYPE_REC = \"REC\";\r\n\tprivate static final String INV_TYPE_UPF = \"UPF\";\r\n\tprivate static final String CF_SEL_INV_NB_BUSI_DAYS = \"CF_SEL_INV_NB_BUSI_DAYS\";\r\n\t\r\n\r\n\tprivate static final Logger log = LoggerFactory.getLogger(EkkoBillingCycleScript.class);\r\n\tprivate InvoiceTypeService invoiceTypeService = (InvoiceTypeService) getServiceInterface(InvoiceTypeService.class.getSimpleName());\r\n\tprivate CalendarBankingService calendarBankingService = (CalendarBankingService) getServiceInterface(CalendarBankingService.class.getSimpleName());\r\n\r\n\t@Override\r\n\tpublic void execute(Map<String, Object> context) throws BusinessException {\r\n\t\tlog.info(\"Execute context : {} \",context);\r\n\t\tList<RatedTransactionGroup> listGroupRts = new ArrayList<RatedTransactionGroup>();\r\n\r\n\t\tif (calendarBankingService.isBankWorkingDate(new Date())) {\r\n\t\t\tcontext.put(Script.RESULT_VALUE, listGroupRts);\r\n\t\t}\r\n\r\n\t\tList<RatedTransaction> ratedTransactions = (List<RatedTransaction>) context.get(\"ratedTransactions\");\r\n\r\n\t\tSubscription subscription = (Subscription) context.get(Script.CONTEXT_ENTITY);\r\n\r\n\t\tRatedTransactionGroup rtGroupRec = new RatedTransactionGroup();\r\n\t\tRatedTransactionGroup rtGroupUpfront = new RatedTransactionGroup();\r\n\t\tInvoiceType recInvoiceType = invoiceTypeService.findByCode(INV_TYPE_REC);\r\n\t\tInvoiceType upfInvoiceType = invoiceTypeService.findByCode(INV_TYPE_UPF);\r\n\r\n\t\trtGroupRec.setInvoiceType(recInvoiceType);\r\n\t\trtGroupRec.setInvoiceKey(recInvoiceType.getCode());\r\n\t\trtGroupRec.setBillingAccount(subscription.getUserAccount().getBillingAccount());\r\n\t\trtGroupRec.setSeller(subscription.getSeller());\r\n\t\trtGroupRec.setBillingCycle(subscription.getBillingCycle());\r\n\r\n\t\trtGroupUpfront.setInvoiceType(upfInvoiceType);\r\n\t\trtGroupUpfront.setInvoiceKey(upfInvoiceType.getCode());\r\n\t\trtGroupUpfront.setBillingAccount(subscription.getUserAccount().getBillingAccount());\r\n\t\trtGroupUpfront.setSeller(subscription.getSeller());\r\n\t\trtGroupUpfront.setBillingCycle(subscription.getBillingCycle());\r\n\r\n\t\tfor (RatedTransaction rt : ratedTransactions) {\r\n\t\t\tlog.info(\"rt  Code:{} UsageDate:{} \" ,rt.getCode(),DateUtils.formatAsDate(rt.getUsageDate()));\r\n\t\t\tif (rt.getCode().startsWith(\"CH_REC\") ||rt.getCode().indexOf(\"ABO\") >-1 ) {\r\n\t\t\t\t//La facture de récurrent est envoyée et reçue le 1er jour ouvré de chaque mois.\r\n\t\t\t\tlog.info(\"isTheFirstbusinesDay(now):\"+isTheFirstbusinesDay(new Date()));\r\n\t\t\t\tlog.info(\"isTheFirstbusinesDay(DateUtils.addDaysToDate(new Date(), 1)):\"+isTheFirstbusinesDay(DateUtils.addDaysToDate(new Date(), 1)));\r\n\t\t\t\tif (isTheFirstbusinesDay(new Date()) ||isTheFirstbusinesDay(DateUtils.addDaysToDate(new Date(), 1)) ) {\r\n\t\t\t\t\trtGroupRec.getRatedTransactions().add(rt);\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\t\t\t\t//La facture d’upfront est envoyée au client et reçue 5 jours ouvrés après son installation.\r\n\t\t\t\t//Et dans le cas d’une installation dans les 6 derniers jours du mois,\r\n\t\t\t\t//la première facture de récurrent est envoyée en même temps que l’upfront.\r\n              \t\t\t\t\r\n\t\t\t\tlog.info(\"usageDate:{} addBusinessDays(rt.getUsageDate():{}  CF_SEL_INV_NB_BUSI_DAYS:{}):\",rt.getUsageDate(),addBusinessDays(rt.getUsageDate(), (Long)subscription.getSeller().getCfValue(CF_SEL_INV_NB_BUSI_DAYS)));\r\n\t\t\t\tlog.info(\"DateUtils.getDayFromDate(rt.getUsageDate():\"+DateUtils.getDayFromDate(rt.getUsageDate()));\r\n\t\t\t\tif(DateUtils.getDayFromDate(rt.getUsageDate())> 25) {\r\n\t\t\t\t\tlog.info(\"isTheFirstbusinesDay(new Date())=\"+isTheFirstbusinesDay(new Date()));\r\n\t\t\t\t\tlog.info(\"getFirstBusinessDayInMonth(date)=\"+getFirstBusinessDayInMonth(new Date()));\r\n\t\t\t\t\t\r\n\t\t\t\t\tif (isTheFirstbusinesDay(new Date()) ||isTheFirstbusinesDay(DateUtils.addDaysToDate(new Date(), 1)) ) {\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tlog.info(\"RT taken1\");\r\n\t\t\t\t\t\trtGroupUpfront.getRatedTransactions().add(rt);\r\n\t\t\t\t\t}else {\r\n\t\t\t\t\t\tlog.info(\"RT skiped1\");\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif(DateUtils.getDayFromDate(rt.getUsageDate())<= 25) {\r\n\t\t\t\t\tif((addBusinessDays(rt.getUsageDate(), (Long)subscription.getSeller().getCfValue(CF_SEL_INV_NB_BUSI_DAYS)).before(DateUtils.setDateToStartOfDay(new Date())))) {\r\n\t\t\t\t\t\tlog.info(\"RT taken2\");\r\n\t\t\t\t\t\trtGroupUpfront.getRatedTransactions().add(rt);\r\n\t\t\t\t\t}else {\r\n\t\t\t\t\t\tlog.info(\"RT skiped2\");\r\n\t\t\t\t\t}\r\n\t\t\t\t}\t\r\n\t\t\t}\r\n\t\t}\r\n\t\tif(!rtGroupRec.getRatedTransactions().isEmpty()) {\r\n\t\t\tlistGroupRts.add(rtGroupRec);\r\n\t\t}\r\n\t\t\r\n\t\tif(!rtGroupUpfront.getRatedTransactions().isEmpty()) {\r\n\t\t\tlistGroupRts.add(rtGroupUpfront);\r\n\t\t}\r\n\r\n\t\t\r\n\t\t\r\n\t\tcontext.put(Script.RESULT_VALUE, listGroupRts);\r\n\r\n\t}\r\n\r\n\tprivate boolean isTheFirstbusinesDay(Date date) {\r\n\t\t\r\n\t\tDate firstBusinessDay = getFirstBusinessDayInMonth(date);\r\n\t\tdate = DateUtils.setDateToStartOfDay(date);\r\n\t\tfirstBusinessDay = DateUtils.setDateToStartOfDay(firstBusinessDay);\r\n\t\t\r\n\t\tif(date.compareTo(firstBusinessDay) >= 0) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\treturn false;\r\n\t}\r\n\r\n\tprivate Date getFirstBusinessDayInMonth(Date dateMonth) {\r\n\r\n\t\tCalendar calendar = Calendar.getInstance();\r\n\t\tcalendar.setTime(dateMonth);\r\n\t\tcalendar.set(Calendar.DAY_OF_MONTH, 1);\r\n\r\n\t\tDate firstBusinessDay = calendar.getTime();\r\n\t\tif (calendarBankingService.isBankWorkingDate(firstBusinessDay)) {\r\n\t\t\treturn firstBusinessDay;\r\n\r\n\t\t}\r\n\r\n\t\twhile (!calendarBankingService.isBankWorkingDate(firstBusinessDay)) {\r\n\t\t\tfirstBusinessDay = DateUtils.addDaysToDate(firstBusinessDay, 1);\r\n\t\t}\r\n\r\n\t\treturn firstBusinessDay;\r\n\t}\r\n\t\r\n\tprivate Date  addBusinessDays(Date dateStart, Long nbDays) {\r\n\t\t\r\n\t\tint daysAdded = 0;\r\n\t\tDate endDate = dateStart;\r\n\t\twhile (daysAdded != nbDays.intValue()) {\r\n\t\t\tendDate = DateUtils.addDaysToDate(endDate, 1);\r\n\t\t\tif (calendarBankingService.isBankWorkingDate(endDate)) {\r\n\t\t\t\tdaysAdded++;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn DateUtils.setDateToEndOfDay(endDate);\r\n\t}\r\n\t\t\r\n\t\r\n}\r\n\r\n\r\n]]>\r\n            </script>\r\n</ScriptInstance>\r\n"
								},
								"url": {
									"raw": "{{opencell.url}}/scriptInstance/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"scriptInstance",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "InvoiceXmlScript",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/xml"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "<ScriptInstance code=\"com.opencellsoft.service.ekko.invoicing.InvoiceXmlScript\" description=\"Ekko Invoice Xml Script\">\r\n            <type>JAVA</type>\r\n            <script>\r\n            <![CDATA[ \r\npackage com.opencellsoft.service.ekko.invoicing;\r\n\r\nimport java.io.File;\r\nimport java.math.BigDecimal;\r\nimport java.math.RoundingMode;\r\nimport java.text.SimpleDateFormat;\r\nimport java.util.ArrayList;\r\nimport java.util.Comparator;\r\nimport java.util.Date;\r\nimport java.util.HashMap;\r\nimport java.util.List;\r\nimport java.util.Locale;\r\nimport java.util.Map;\r\nimport java.util.regex.Matcher;\r\nimport java.util.regex.Pattern;\r\n\r\nimport org.meveo.admin.exception.BusinessException;\r\nimport org.meveo.commons.utils.StringUtils;\r\nimport org.meveo.model.billing.Invoice;\r\nimport org.meveo.model.billing.InvoiceAgregate;\r\nimport org.meveo.model.billing.RatedTransaction;\r\nimport org.meveo.model.billing.SubCategoryInvoiceAgregate;\r\nimport org.meveo.model.billing.Subscription;\r\nimport org.meveo.model.billing.TaxInvoiceAgregate;\r\nimport org.meveo.model.payments.PaymentMethodEnum;\r\nimport org.meveo.model.shared.DateUtils;\r\nimport org.meveo.service.billing.impl.EkkoXMLInvoiceCreator;\r\nimport org.meveo.service.billing.impl.InvoiceAgregateService;\r\nimport org.meveo.service.billing.impl.InvoiceService;\r\nimport org.meveo.service.billing.impl.RatedTransactionService;\r\nimport org.meveo.service.script.Script;\r\nimport org.w3c.dom.Document;\r\nimport org.w3c.dom.Element;\r\n\r\n/**\r\n * Generate custom Xml Invoice Execute Context Variable :\r\n * <li>CONTEXT_ENTITY : the invoice\r\n * <li>isVirtual : invoicing mode\r\n * <li>XMLInvoiceCreator : XMLInvoiceCreator std service\r\n *\r\n * @author anasseh\r\n */\r\npublic class InvoiceXmlScript extends Script {\r\n\r\n\tprivate static final long serialVersionUID = 1L;\r\n\tprivate EkkoXMLInvoiceCreator xmlInvoiceCreatorScript = (EkkoXMLInvoiceCreator) getServiceInterface(EkkoXMLInvoiceCreator.class.getSimpleName());\r\n\tprivate InvoiceService invoiceService = (InvoiceService) getServiceInterface(InvoiceService.class.getSimpleName());\r\n\tprivate RatedTransactionService ratedTransactionService = (RatedTransactionService) getServiceInterface(RatedTransactionService.class.getSimpleName());\r\n\tprivate InvoiceAgregateService invoiceAgregateService = (InvoiceAgregateService) getServiceInterface(InvoiceAgregateService.class.getSimpleName());\r\n\tprivate SimpleDateFormat dateFormat = new SimpleDateFormat(\"MMMM\", Locale.FRENCH);\r\n\tprivate static final String CF_SUB_PAY_METHOD = \"CF_SUB_PAY_METHOD\";\r\n\tprivate static final String SHIPPING_ADDRESS = \"ShippingAddress\";\r\n\tprivate static final String CF_NbrOfRadiator = \"EK_OPP_NofRadiator__c\";\r\n\tprivate static final String CF_NbrOfRooms = \"EK_OPP_Number_Rooms__c\";\r\n\tprivate Long nbrOfRadiotor = 0L;\r\n\tprivate Long nbrOfRooms = 0L;\r\n\r\n\t@Override\r\n\tpublic void execute(Map<String, Object> methodContext) throws BusinessException {\r\n\t\tlog.debug(\"EXECUTE methodContext {}\", methodContext);\r\n\t\ttry {\r\n\r\n\t\t\tInvoice invoice = (Invoice) methodContext.get(Script.CONTEXT_ENTITY);\r\n\t\t\tString fullXmlFilePath = invoiceService.getFullXmlFilePath(invoice, true);\r\n\t\t\tBoolean isVirtual = (Boolean) methodContext.get(\"isVirtual\");\r\n\t\t\tDocument document = xmlInvoiceCreatorScript.createDocument(invoice, isVirtual, true);\r\n\t\t\tadditionalInfos(document, invoice, \"CF_SUB_SF_DATA\");\r\n\t\t\tif (\"REC\".equals(invoice.getInvoiceType().getCode())) {\r\n\t\t\t\taddDetailREC(document, invoice);\r\n\t\t\t}\r\n\t\t\tif (\"UPF\".equals(invoice.getInvoiceType().getCode())) {\r\n\t\t\t\taddDetailUPF(document, invoice);\r\n\t\t\t\taddRefsMats(document);\r\n\t\t\t}\r\n\t\t\taddTotalLInes(document, invoice);\r\n\r\n\t\t\tFile file = xmlInvoiceCreatorScript.createFile(document, invoice, fullXmlFilePath);\r\n\t\t\tmethodContext.put(Script.RESULT_VALUE, file);\r\n\t\t} catch (Exception e) {\r\n\t\t\te.printStackTrace();\r\n\t\t\tthrow new BusinessException(e.getMessage());\r\n\t\t}\r\n\t}\r\n\r\n\tprivate void addTotalLInes(Document document, Invoice invoice) {\r\n\t\tElement totauxElement = document.createElement(\"totauxElement\");\r\n\r\n\t\tBigDecimal netToPay = invoice.getAmountWithoutTax();\r\n\r\n\t\tElement totalHTLineElem = document.createElement(\"totalLine\");\r\n\r\n\t\ttotalHTLineElem.setAttribute(\"name\", \"Total HT\");\r\n\t\ttotalHTLineElem.setAttribute(\"amount\", roundFormat(invoice.getAmountWithoutTax()));\r\n\t\ttotauxElement.appendChild(totalHTLineElem);\r\n\r\n\t\tList<TaxInvoiceAgregate> taxInvoiceAgregates = new ArrayList<TaxInvoiceAgregate>();\r\n\t\tfor (InvoiceAgregate invoiceAgregate : invoice.getInvoiceAgregates()) {\r\n\t\t\tif (invoiceAgregate instanceof TaxInvoiceAgregate) {\r\n\t\t\t\ttaxInvoiceAgregates.add((TaxInvoiceAgregate) invoiceAgregate);\r\n\t\t\t}\r\n\t\t}\r\n\t\ttaxInvoiceAgregates.sort(Comparator.comparing(ta -> ta.getTax().getPercent()));\r\n\t\tfor (TaxInvoiceAgregate taxInvoiceAgregate : taxInvoiceAgregates) {\r\n\r\n\t\t\tElement taxElem = document.createElement(\"totalLine\");\r\n\r\n\t\t\ttaxElem.setAttribute(\"name\", \"TVA (\" + roundFormat(taxInvoiceAgregate.getTaxPercent(), true) + \"%)\");\r\n\t\t\ttaxElem.setAttribute(\"amount\", roundFormat(taxInvoiceAgregate.getAmountTax()));\r\n\t\t\ttotauxElement.appendChild(taxElem);\r\n\r\n\t\t\tnetToPay = netToPay.add(round(taxInvoiceAgregate.getAmountTax()));\r\n\r\n\t\t}\r\n\r\n\t\tMap<String, Object> params = new HashMap<String, Object>();\r\n\t\tparams.put(\"dueDateIN\", new Date());\r\n\t\tList<Invoice> unPaidInvoices = (List<Invoice>) invoiceService.executeSelectQuery(\"select inv from Invoice inv where inv.id != \" + invoice.getId()\r\n\t\t\t\t+ \" and inv.recordedInvoice != null and  inv.recordedInvoice.matchingStatus != 'L'  and inv.dueDate <:dueDateIN  and inv.billingAccount.id = \"\r\n\t\t\t\t+ invoice.getBillingAccount().getId() + \" order by inv.id\", params);\r\n\r\n\t\tfor (Invoice inv : unPaidInvoices) {\r\n\t\t\tElement invElem = document.createElement(\"totalLine\");\r\n\r\n\t\t\tinvElem.setAttribute(\"name\", \"Facture impay\\u00E9e N\\u00B0 \" + inv.getInvoiceNumber() + \" du \" + DateUtils.formatDateWithPattern(inv.getInvoiceDate(), \"dd/MM/yyyy\"));\r\n\t\t\tinvElem.setAttribute(\"amount\", roundFormat(inv.getAmountWithTax()));\r\n\t\t\ttotauxElement.appendChild(invElem);\r\n\t\t\tnetToPay = netToPay.add(round(inv.getAmountWithTax()));\r\n\r\n\t\t}\r\n\r\n\t\tElement totalLineElem = document.createElement(\"totalLine\");\r\n\r\n\t\ttotalLineElem.setAttribute(\"name\", \"Total \\u00E0 payer TTC\");\r\n\t\ttotalLineElem.setAttribute(\"amount\", roundFormat(netToPay));\r\n\t\ttotauxElement.appendChild(totalLineElem);\r\n\r\n\t\tdocument.getElementsByTagName(\"invoice\").item(0).appendChild(totauxElement);\r\n\r\n\t}\r\n\r\n//\tprivate void addUnPaidInvoices(Document document, Invoice invoice) {\r\n//\t\tElement unPaidInvElement = document.createElement(\"unPaidInvoices\");\r\n//\r\n//\t\tList<Invoice> unPaidInvoices = (List<Invoice>) invoiceService\r\n//\t\t\t\t.executeSelectQuery(\"select inv from Invoice inv where inv.id != \" + invoice.getId() + \" and inv.recordedInvoice != null and  inv.recordedInvoice.matchingStatus != 'L'  order by inv.id\", null);\r\n//\t\tfor (Invoice inv : unPaidInvoices) {\r\n//\t\t\tElement invElem = document.createElement(\"unPaidInvoice\");\r\n//\r\n//\t\t\tinvElem.setAttribute(\"invoiceNumber\", inv.getInvoiceNumber());\r\n//\t\t\tinvElem.setAttribute(\"invoiceDate\", DateUtils.formatDateWithPattern(inv.getInvoiceDate(), \"dd/MM/yyyy\"));\r\n//\t\t\tinvElem.setAttribute(\"dueDate\", DateUtils.formatDateWithPattern(inv.getDueDate(), \"dd/MM/yyyy\"));\r\n//\t\t\tinvElem.setAttribute(\"amountWithTax\", roundFormat(inv.getAmountWithTax()));\r\n//\t\t\tinvElem.setAttribute(\"amountWithoutTax\", roundFormat(inv.getAmountWithoutTax()));\r\n//\t\t\tinvElem.setAttribute(\"amountTax\", roundFormat(inv.getAmountTax()));\r\n//\t\t\tunPaidInvElement.appendChild(invElem);\r\n//\t\t}\r\n//\r\n//\t\tdocument.getElementsByTagName(\"invoice\").item(0).appendChild(unPaidInvElement);\r\n//\r\n//\t}\r\n\r\n\tprivate void addDetailREC(Document document, Invoice invoice) {\r\n\r\n\t\tElement detailREC = document.createElement(\"detailREC\");\r\n\t\tif (getPaymentMethodType(invoice) != null) {\r\n\t\t\tdetailREC.setAttribute(\"paymentMethod\", getPaymentMethodType(invoice).name());\r\n\t\t}\r\n\t\tList<RatedTransaction> rts = (List<RatedTransaction>) ratedTransactionService\r\n\t\t\t\t.executeSelectQuery(\"select rt from RatedTransaction rt where rt.invoice.id=\" + invoice.getId(), null);\r\n\t\tfor (RatedTransaction rt : rts) {\r\n\t\t\tElement linElem = document.createElement(\"lineREC\");\r\n\t\t\tif (rt.getCode().startsWith(\"CH_REC\")) {\r\n\t\t\t\tlinElem.setAttribute(\"label\",\r\n\t\t\t\t\t\trt.getDescription() + \" du \" + dateFormat.format(rt.getStartDate()) + \" \" + DateUtils.formatDateWithPattern(rt.getStartDate(), \"dd/MM/yyyy\") + \" au \"\r\n\t\t\t\t\t\t\t\t+ DateUtils.formatDateWithPattern(DateUtils.addDaysToDate(rt.getEndDate(), -1), \"dd/MM/yyyy\"));\r\n\t\t\t} else {\r\n\t\t\t\tlinElem.setAttribute(\"label\", rt.getDescription());\r\n\t\t\t}\r\n\t\t\tlinElem.setAttribute(\"unitAmountWithoutTax\", roundFormat(rt.getUnitAmountWithoutTax()));\r\n\t\t\tlinElem.setAttribute(\"taxPercent\", roundFormat(rt.getTaxPercent(), true) + \" %\");\r\n\t\t\tlinElem.setAttribute(\"unitAmountWithTax\", roundFormat(rt.getUnitAmountWithTax()));\r\n\t\t\tlinElem.setAttribute(\"quantity\", roundFormat(rt.getQuantity()));\r\n\t\t\tlinElem.setAttribute(\"amountWithTax\", roundFormat(rt.getAmountWithTax()));\r\n\t\t\tdetailREC.appendChild(linElem);\r\n\t\t}\r\n\r\n\t\tdocument.getElementsByTagName(\"invoice\").item(0).appendChild(detailREC);\r\n\r\n\t}\r\n\r\n\tprivate BigDecimal[] computeAmounts(List<RatedTransaction> rts, String subCatCode) {\r\n\r\n\t\tBigDecimal[] amounts = new BigDecimal[3];\r\n\t\tamounts[0] = BigDecimal.ZERO;\r\n\t\tamounts[1] = BigDecimal.ZERO;\r\n\t\tamounts[2] = BigDecimal.ZERO;\r\n\t\t\t\t\r\n\t\tfor(RatedTransaction rt : rts) {\r\n\t\t\tif(subCatCode.equals(rt.getInvoiceSubCategory().getCode())) {\r\n\t\t\t\tamounts[0] = amounts[0].add(round(rt.getAmountWithoutTax()));\r\n\t\t\t\tamounts[1] = amounts[1].add(round(rt.getAmountTax()));\r\n\t\t\t\tamounts[2] = amounts[2].add(round(rt.getAmountWithTax()));\r\n\t\t\t}\r\n\t\t}\t\t\r\n\r\n\t\treturn amounts;\r\n\t}\r\n\r\n\tprivate Element addLineUPF(Document document, String label, String taxPercent, BigDecimal unitHt, BigDecimal unitTtc, BigDecimal quantity, BigDecimal ttc) {\r\n\t\tElement linElem = document.createElement(\"lineUPF\");\r\n\r\n\t\tlinElem.setAttribute(\"label\", label);\r\n\r\n\t\tlinElem.setAttribute(\"unitAmountWithoutTax\", unitHt == null ? \"-\" : roundFormat(unitHt));\r\n\t\tlinElem.setAttribute(\"taxPercent\", taxPercent == null ? \"-\" : (taxPercent + \" %\"));\r\n\t\tlinElem.setAttribute(\"unitAmountWithTax\", unitTtc == null ? \"-\" : roundFormat(unitTtc));\r\n\t\tlinElem.setAttribute(\"quantity\", quantity == null ? \"-\" : roundFormat(quantity));\r\n\t\tlinElem.setAttribute(\"amountWithTax\", ttc == null ? \"-\" : roundFormat(ttc));\r\n\t\treturn linElem;\r\n\r\n\t}\r\n\r\n\tprivate void addDetailUPF(Document document, Invoice invoice) {\r\n\t\tElement detailUPF = document.createElement(\"detailUPF\");\r\n\t\tif (getPaymentMethodType(invoice) != null) {\r\n\t\t\tdetailUPF.setAttribute(\"paymentMethod\", getPaymentMethodType(invoice).name());\r\n\t\t}\r\n\t\tList<RatedTransaction> rts  = ratedTransactionService.getRatedTransactionsByInvoice(invoice, true);\r\n\r\n\t\tBigDecimal[] amountsInstall = computeAmounts(rts, \"ISCAT_EKKO_INSTALL\");\r\n\t\tBigDecimal[] amountsMat = computeAmounts(rts, \"ISCAT_EKKO_MAT_VENTE\");\r\n\t\tBigDecimal[] amountsDEEE = computeAmounts(rts, \"ISCAT_EKKO_DEEE\");\r\n\t\tBigDecimal[] amountsDEEERemise = computeAmounts(rts, \"ISCAT_EKKO_DEEE_REMISE\");\r\n\t\tBigDecimal[] amountsRemiseInstal = computeAmounts(rts, \"ISCAT_EKKO_INSTALL_REMISE\");\r\n\t\tBigDecimal[] amountsRemiseMat = computeAmounts(rts, \"ISCAT_EKKO_MAT_REMISE\");\r\n\t\tBigDecimal[] amountsGest = computeAmounts(rts, \"ISCAT_EKKO_INSTALL_GEST\");\r\n\r\n\t\tBigDecimal total = round(amountsInstall[2]).add(round(amountsMat[2]).add(round(amountsDEEE[2])));\r\n\t\tif (total.compareTo(BigDecimal.ZERO) != 0) {\r\n\t\t\tdetailUPF.appendChild(addLineUPF(document, \"Fourniture et pose de programmateurs d’intermittence de marque ENGIE sur \" + nbrOfRadiotor + \" radiateurs existants \", null,\r\n\t\t\t\t\tnull, round(total), BigDecimal.ONE, round(total)));\r\n\t\t\tdetailUPF.appendChild(addLineUPF(document, \"\\tdont mat&eacute;riel¹\", \"5,5\", amountsMat[0], amountsMat[2], BigDecimal.ONE, amountsMat[2]));\r\n\t\t\tdetailUPF.appendChild(addLineUPF(document, \"\\tdont &eacute;co-participation \\tDEEE\", \"20\", amountsDEEE[0], amountsDEEE[2], BigDecimal.ONE, amountsDEEE[2]));\r\n\t\t\tdetailUPF.appendChild(addLineUPF(document, \"\\tdont installation\", \"5,5\", amountsInstall[0], amountsInstall[2], BigDecimal.ONE, amountsInstall[2]));\r\n\t\t}\r\n\r\n\t\tBigDecimal totalRemise = round(amountsRemiseInstal[2]).add(round(amountsRemiseMat[2])).add(round(amountsDEEERemise[2]));\r\n\t\tif (totalRemise.compareTo(BigDecimal.ZERO) != 0) {\r\n\t\t\tdetailUPF.appendChild(addLineUPF(document, \"Remise\", null, null, round(totalRemise), BigDecimal.ONE, round(totalRemise)));\r\n\t\t\tdetailUPF.appendChild(addLineUPF(document, \"\\tsur mat&eacute;riel\", \"5,5\", amountsRemiseMat[0], amountsRemiseMat[2], BigDecimal.ONE, amountsRemiseMat[2]));\r\n\t\t\tdetailUPF.appendChild(addLineUPF(document, \"\\tsur installation\", \"5,5\", amountsRemiseInstal[0], amountsRemiseInstal[2], BigDecimal.ONE, amountsRemiseInstal[2]));\r\n\t\t\tdetailUPF.appendChild(addLineUPF(document, \"\\tsur &eacute;co-participation DEEE\", \"20\", amountsDEEERemise[0], amountsDEEERemise[2], BigDecimal.ONE, amountsDEEERemise[2]));\r\n\r\n\t\t}\r\n\r\n\t\tif (amountsGest[0].compareTo(BigDecimal.ZERO) != 0) {\r\n\t\t\tdetailUPF.appendChild(addLineUPF(document, \"Geste commercial\", \"5,5\", amountsGest[0], amountsGest[2], BigDecimal.ONE, amountsGest[2]));\r\n\r\n\t\t}\r\n\r\n\t\tdocument.getElementsByTagName(\"invoice\").item(0).appendChild(detailUPF);\r\n\r\n\t}\r\n\r\n\tpublic Element addMaterielLine(Document document, String name, String reference) {\r\n\t\tElement linElem = document.createElement(\"mat\");\r\n\t\tlinElem.setAttribute(\"name\", name);\r\n\t\tlinElem.setAttribute(\"reference\", reference);\r\n\t\treturn linElem;\r\n\t}\r\n\r\n\tprivate void addRefsMats(Document document) {\r\n\t\tElement refsMats = document.createElement(\"refsMats\");\r\n\t\trefsMats.appendChild(addMaterielLine(document, \"1 prise communicante « Mbox »\", \"(référence K02-GM-01.0013E-C-ETH)\"));\r\n\t\trefsMats.appendChild(addMaterielLine(document, nbrOfRadiotor + \" modules de pilotage « Dbox »\", \"(référence K01-CDK-01.1016-01-P1/TIK)\"));\r\n\t\trefsMats.appendChild(addMaterielLine(document, nbrOfRooms + \" capteurs de température « Sense-3 »\", \"(référence K02-CASTH-01.1004-01/TIK-WH)\"));\r\n\t\trefsMats.appendChild(addMaterielLine(document, \"1 câble Ethernet de longueur 5m\", \"(référence CA-ETHC2)\"));\r\n\r\n\t\tdocument.getElementsByTagName(\"invoice\").item(0).appendChild(refsMats);\r\n\t}\r\n\r\n\tprivate void additionalInfos(Document document, Invoice invoice, String cfName) {\r\n\r\n\t\tElement additionalFields = document.createElement(\"additionalFields\");\r\n\r\n\t\tSubscription sub = invoice.getSubscription();\r\n\t\tMap<String, String> sfDataMap = (Map<String, String>) sub.getCfValue(cfName);\r\n\t\tif (sfDataMap != null) {\r\n\t\t\tfor (Map.Entry<String, String> entry : sfDataMap.entrySet()) {\r\n\t\t\t\tif (SHIPPING_ADDRESS.equals(entry.getKey())) {\r\n\t\t\t\t\textractShippingAddress(document, additionalFields, entry.getValue());\r\n\t\t\t\t} else {\r\n\t\t\t\t\tElement entryElem = document.createElement(entry.getKey());\r\n\t\t\t\t\tentryElem.setTextContent(entry.getValue());\r\n\t\t\t\t\tadditionalFields.appendChild(entryElem);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (sfDataMap.get(CF_NbrOfRadiator) != null) {\r\n\t\t\t\tnbrOfRadiotor = Long.valueOf(sfDataMap.get(CF_NbrOfRadiator));\r\n\t\t\t}\r\n\t\t\tif (sfDataMap.get(CF_NbrOfRooms) != null) {\r\n\t\t\t\tnbrOfRooms = Long.valueOf(sfDataMap.get(CF_NbrOfRooms));\r\n\t\t\t}\r\n\t\t}\r\n\t\tElement dateInsElem = document.createElement(\"CF_SUB_DATE_INSTALL\");\r\n\t\tdateInsElem.setTextContent(DateUtils.formatDateWithPattern((Date) sub.getCfValue(\"CF_SUB_DATE_INSTALL\"), \"dd/MM/yyyy\"));\r\n\t\tadditionalFields.appendChild(dateInsElem);\r\n\r\n\t\tElement nbDaysElem = document.createElement(\"CF_SEL_PAY_NB_BUSI_DAYS\");\r\n\t\tnbDaysElem.setTextContent(\"\" + (Long) sub.getSeller().getCfValue(\"CF_SEL_PAY_NB_BUSI_DAYS\"));\r\n\t\tadditionalFields.appendChild(nbDaysElem);\r\n\r\n\t\tdocument.getElementsByTagName(\"invoice\").item(0).appendChild(additionalFields);\r\n\t}\r\n\r\n\tprivate BigDecimal round(BigDecimal amount) {\r\n\t\treturn round(amount, false);\r\n\t}\r\n\r\n\tprivate BigDecimal round(BigDecimal amount, boolean stripTrailingZeros) {\r\n\t\tif (amount == null) {\r\n\t\t\tamount = BigDecimal.ZERO;\r\n\t\t}\r\n\t\tint scale = 2;\r\n\r\n\t\tamount = amount.setScale(scale, RoundingMode.HALF_UP);\r\n\t\tif (stripTrailingZeros) {\r\n\t\t\tamount = amount.stripTrailingZeros();\r\n\t\t}\r\n\t\treturn amount;\r\n\t}\r\n\r\n\tprivate String roundFormat(BigDecimal amount) {\r\n\t\treturn String.valueOf(round(amount, false).toPlainString()).replaceAll(\"\\\\.\", \",\");\r\n\t}\r\n\r\n\tprivate String roundFormat(BigDecimal amount, boolean stripTrailingZeros) {\r\n\t\treturn String.valueOf(round(amount, stripTrailingZeros).toPlainString()).replaceAll(\"\\\\.\", \",\");\r\n\t}\r\n\r\n\tprivate PaymentMethodEnum getPaymentMethodType(Invoice invoice) {\r\n\t\tString paymentMethod = (String) invoice.getSubscription().getCfValue(CF_SUB_PAY_METHOD);\r\n\t\tPaymentMethodEnum paymentMethodEnumCommande = null;\r\n\t\tif (paymentMethod != null) {\r\n\t\t\tpaymentMethodEnumCommande = PaymentMethodEnum.valueOf(paymentMethod);\r\n\t\t}\r\n\t\tPaymentMethodEnum paymentMethodEnumCustomer = invoice.getBillingAccount().getCustomerAccount().getPreferredPaymentMethodType();\r\n\r\n\t\tif (paymentMethodEnumCommande == PaymentMethodEnum.DIRECTDEBIT && paymentMethodEnumCustomer != PaymentMethodEnum.DIRECTDEBIT) {\r\n\t\t\treturn PaymentMethodEnum.CARD;\r\n\t\t}\r\n\t\treturn paymentMethodEnumCommande;\r\n\r\n\t}\r\n\r\n\tprivate void extractShippingAddress(Document document, Element additionalFields, String shippingAddress) {\r\n\r\n\t\tif (!StringUtils.isBlank(shippingAddress)) {\r\n\t\t\tMatcher m = Pattern.compile(\"\\\\d{5}\\\\S+\").matcher(shippingAddress);\r\n\t\t\tString address = null;\r\n\t\t\tString zipAndCity = null;\r\n\t\t\tif (m.find()) {\r\n\t\t\t\tzipAndCity = m.group(0);\r\n\t\t\t}\r\n\t\t\tif (zipAndCity != null) {\r\n\t\t\t\taddress = shippingAddress.substring(0, (shippingAddress.length() - zipAndCity.length()));\r\n\t\t\t\tElement addressElement = document.createElement(SHIPPING_ADDRESS);\r\n\t\t\t\taddressElement.setTextContent(address);\r\n\t\t\t\tadditionalFields.appendChild(addressElement);\r\n\r\n\t\t\t\tElement zipCodeElement = document.createElement(\"zipcode_and_city\");\r\n\t\t\t\tzipCodeElement.setTextContent(zipAndCity);\r\n\t\t\t\tadditionalFields.appendChild(zipCodeElement);\r\n\t\t\t} else {\r\n\t\t\t\tElement shippingAddressElement = document.createElement(SHIPPING_ADDRESS);\r\n\t\t\t\tshippingAddressElement.setTextContent(shippingAddress);\r\n\t\t\t\tadditionalFields.appendChild(shippingAddressElement);\r\n\t\t\t}\r\n\r\n\t\t}\r\n\t}\r\n\r\n}\r\n\r\n]]>\r\n            </script>\r\n</ScriptInstance>\r\n\r\n"
								},
								"url": {
									"raw": "{{opencell.url}}/scriptInstance/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"scriptInstance",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "DueDateScript",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/xml"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "<ScriptInstance code=\"com.opencellsoft.service.ekko.invoicing.DueDateScript\" description=\"Ekko DueDateScript\">\r\n            <type>JAVA</type>\r\n            <script>\r\n            <![CDATA[ package com.opencellsoft.service.ekko.invoicing;\r\n\r\nimport java.util.Date;\r\n\r\nimport java.util.Map;\r\n\r\nimport org.meveo.admin.exception.BusinessException;\r\nimport org.meveo.model.admin.Seller;\r\nimport org.meveo.model.shared.DateUtils;\r\nimport org.meveo.service.admin.impl.SellerService;\r\nimport org.meveo.service.catalog.impl.CalendarBankingService;\r\nimport org.meveo.service.script.Script;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n\r\n/**\r\n * \r\n * @author anasseh\r\n *\r\n */\r\n\r\npublic class DueDateScript extends Script {\r\n\r\n\tprivate static final long serialVersionUID = 1L;\r\n\tprivate static final String CF_SEL_PAY_NB_BUSI_DAYS = \"CF_SEL_PAY_NB_BUSI_DAYS\";\r\n\r\n\tprivate static final Logger log = LoggerFactory.getLogger(DueDateScript.class);\r\n\tprivate CalendarBankingService calendarBankingService = (CalendarBankingService) getServiceInterface(CalendarBankingService.class.getSimpleName());\r\n\tprivate SellerService sellerService = (SellerService) getServiceInterface(SellerService.class.getSimpleName());\r\n\r\n\t@Override\r\n\tpublic void execute(Map<String, Object> context) throws BusinessException {\r\n\t\tlog.info(\"Execute context : {} \", context);\r\n\t\tSeller seller = sellerService.findByCode(\"EKKO\");\r\n\t\tLong nbDaysDue = (Long) seller.getCfValue(CF_SEL_PAY_NB_BUSI_DAYS);\r\n\t\t\r\n\t\tDate dueDate = null;\r\n\t\tDate today = DateUtils.setDateToStartOfDay(new Date());\r\n\r\n\t\tdueDate = addBusinessDays(new Date(), nbDaysDue);\r\n\t\tDouble daysbetween = DateUtils.daysBetween(today, dueDate);\r\n\t\tlog.info(\"today:{} dueDate:{} \", today, dueDate, daysbetween.intValue());\r\n\r\n\t\tcontext.put(Script.RESULT_VALUE, daysbetween.intValue());\r\n\t}\r\n\r\n\tprivate Date addBusinessDays(Date dateStart, Long nbDays) {\r\n\r\n\t\tint daysAdded = 0;\r\n\t\tDate endDate = dateStart;\r\n\t\twhile (daysAdded != nbDays.intValue()) {\r\n\t\t\tendDate = DateUtils.addDaysToDate(endDate, 1);\r\n\t\t\tif (calendarBankingService.isBankWorkingDate(endDate)) {\r\n\t\t\t\tdaysAdded++;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn DateUtils.setDateToEndOfDay(endDate);\r\n\t}\r\n\r\n}\r\n]]>\r\n            </script>\r\n</ScriptInstance>\r\n\r\n"
								},
								"url": {
									"raw": "{{opencell.url}}/scriptInstance/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"scriptInstance",
										"createOrUpdate"
									]
								}
							},
							"response": []
						}
					]
				},
				{
					"name": "compta",
					"item": [
						{
							"name": "ExportRapsodieScript",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/xml"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "<ScriptInstance code=\"com.opencellsoft.service.ekko.compta.ExportRapsodieScript\" description=\"Ekko Export Rapsodie Script\">\r\n            <type>JAVA</type>\r\n            <script>\r\n            <![CDATA[package com.opencellsoft.service.ekko.compta;\r\n\r\n\r\nimport static org.apache.commons.lang.StringUtils.leftPad;\r\nimport static org.apache.commons.lang.StringUtils.rightPad;\r\n\r\nimport java.io.File;\r\nimport java.io.IOException;\r\nimport java.math.BigDecimal;\r\nimport java.math.RoundingMode;\r\nimport java.text.DecimalFormat;\r\nimport java.time.LocalDate;\r\nimport java.util.ArrayList;\r\nimport java.util.Arrays;\r\nimport java.util.Date;\r\nimport java.util.HashMap;\r\nimport java.util.List;\r\nimport java.util.Locale;\r\nimport java.util.Map;\r\nimport java.util.Map.Entry;\r\nimport java.util.TreeMap;\r\n\r\nimport javax.persistence.NoResultException;\r\nimport javax.persistence.Query;\r\n\r\nimport org.meveo.admin.exception.BusinessException;\r\nimport org.meveo.commons.utils.ParamBean;\r\nimport org.meveo.commons.utils.QueryBuilder;\r\nimport org.meveo.commons.utils.StringUtils;\r\nimport org.meveo.model.billing.AccountingCode;\r\nimport org.meveo.model.billing.Invoice;\r\nimport org.meveo.model.billing.SubCategoryInvoiceAgregate;\r\nimport org.meveo.model.billing.Tax;\r\nimport org.meveo.model.billing.TaxInvoiceAgregate;\r\nimport org.meveo.model.crm.Provider;\r\nimport org.meveo.model.finance.AccountingEntry;\r\nimport org.meveo.model.jobs.JobInstance;\r\nimport org.meveo.model.payments.AccountOperation;\r\nimport org.meveo.model.payments.MatchingAmount;\r\nimport org.meveo.model.payments.MatchingCode;\r\nimport org.meveo.model.payments.OCCTemplate;\r\nimport org.meveo.model.shared.DateUtils;\r\nimport org.meveo.model.tax.TaxClass;\r\nimport org.meveo.service.billing.impl.AccountingCodeService;\r\nimport org.meveo.service.billing.impl.InvoiceService;\r\nimport org.meveo.service.crm.impl.ProviderService;\r\nimport org.meveo.service.finance.AccountingWritingService;\r\nimport org.meveo.service.job.JobInstanceService;\r\nimport org.meveo.service.payments.impl.OCCTemplateService;\r\nimport org.meveo.service.script.Script;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport com.google.common.base.Charsets;\r\nimport com.google.common.collect.Maps;\r\nimport com.google.common.io.Files;\r\nimport org.meveo.service.catalog.impl.InvoiceSubCategoryService;\r\nimport org.meveo.model.billing.InvoiceSubCategory;\r\nimport org.meveo.model.billing.InvoiceCategory;\r\nimport org.meveo.service.catalog.impl.InvoiceCategoryService;\r\n\r\n/**\r\n/**\r\n * @author myPower team , from dump PP 19/05/2021\r\n * \r\n * @author anasseh update for OC 11 and EKKO\r\n *\r\n */\r\n\r\npublic class ExportRapsodieScript extends Script {\r\n\r\n    private static final Logger log = LoggerFactory.getLogger(ExportRapsodieScript.class);\r\n\r\n    private static final String JOB_CODE = \"EkkoExportRapsodieJob\";\r\n    private static final String PREFIX = \"EKK\";\r\n    private static final String FOLDER_ID = \"G\";\r\n    private static final String ORGA_CODE = \"9856\";\r\n    private static final String OC_CODE = \"OCE\";\r\n    private static final String MANDANT = \"500\";\r\n    private static final String DEBIT = \"40\";\r\n    private static final String CREDIT = \"50\";\r\n    private static final String CAT_VENDING_CODE = \"ICAT_EKKO_INSTALL\";\r\n    private static final String CAT_VENDING_CODE_2 = \"ICAT_EKKO_ABO\";\r\n\r\n    \r\n    private static final String CAT_SERVICE_PROVISION_CODE = \"ICAT_EKKO_MATERIEL\";\r\n    private static final String CAT_PAY_CODE = \"PAY_FF\";\r\n\r\n    private static final String COSTL_MPM = \"VCA-AU-MPM\";\r\n    private static final String COSTL_MPI = \"VCA-AU-MPI\";\r\n    private static final String COSTL_PWBONIF = \"VM-PWBONIF\";\r\n    private static final String OCC_TEMP_CODE_REF_INV= \"REF_INV\";\r\n    private static final String OCC_TEMP_CODE_INV_STD= \"INV_STD\";\r\n    private static final String SKIP_CHAR = \"/\";\r\n    private static final String NEW_LINE = \"\\n\";\r\n    private static final String PAD_STR = \" \";\r\n    \r\n    private static final String  SELLER_CODE =\"EKKO\";\r\n    \r\n    private static final String SUB_CAT_DEE= \"ISCAT_EKKO_DEEE\";\r\n    private static final String COSTL_VCA_DE = \"VCA-DE-EKO\";\r\n    private static final String COSTL_VCA_MA = \"VCA-MA-EKO\";\r\n    private static final String COSTL_VCA_IN = \"VCA-IN-EKO\";\r\n    private static final String COSTL_VCA_SE = \"VCA-SE-EKO\";\r\n    private static final String ACCOUNT_1= \"706260\";\r\n    private static final String ACCOUNT_2= \"709300\";\r\n    private static final String ACCOUNT_3= \"706800\";\r\n\r\n    private enum EventEnum {\r\n        FACTURATION(\"Facturation\"),\r\n        ANNULATION_FACTURATION(\"Annulation Facturation\"),\r\n        PAY_DDT(\"Encaissement Prelevement\"),\r\n        PAY_CRD(\"Encaissement CB\"),\r\n        PAY_CHK(\"Encaissement Cheque\"),\r\n        PAY_TRF(\"Encaissement Virement\"),\r\n        PAY_FF(\"Bonifications d'interets - Autres Banques\"),\r\n        PAY_TIP(\"Encaissement Espece\"),\r\n        //REF_DDT(\"Décaissement Prelevement\"),\r\n        REF_DDT(\"Décaissement Virement\"),\r\n        REF_CHK(\"Décaissement Cheque\"),\r\n        REF_CRD(\"Décaissement CB\"),\r\n        REF_TRF(\"Décaissement Virement\"),\r\n        REF_TIP(\"Décaissement Espece\"),\r\n        REJ_DDT(\"Prelevement Rejeter\"),\r\n        REF_INV(\"Avoir sur Facturation\");\r\n        String label;\r\n\r\n        EventEnum(String label) {\r\n            this.label = label;\r\n        }\r\n\r\n        public String getLabel() {\r\n            return label;\r\n        }\r\n    }\r\n\r\n    private enum ZUONREnum {\r\n        INVOICE(\"FACTURE\"),\r\n        PAY_DDT(\"SDD\"),\r\n        REF_DDT(\"SDD\"),\r\n        PAY_CHK(\"CHQ\"),\r\n        REF_CHK(\"CHQ\"),\r\n        PAY_TIP(\"TIP\"),\r\n        REF_TIP(\"TIP\"),\r\n        PAY_CRD(\"CB\"),\r\n        PAY_TRF(\"TRF\"),\r\n        PAY_FF(\"FF\"),\r\n        REF_TRF(\"TRF\"),\r\n        REF_CRD(\"CB\"),\r\n        REF_INV(\"SDD\"),\r\n        REJ_DDT(\"SDD\");\r\n\r\n\r\n        String label;\r\n\r\n        ZUONREnum(String label) {\r\n            this.label = label;\r\n        }\r\n\r\n        public String getLabel() {\r\n            return label;\r\n        }\r\n    }\r\n\r\n\r\n    private InvoiceService invoiceService = (InvoiceService) getServiceInterface(\"InvoiceService\");\r\n    private JobInstanceService jobInstanceService = (JobInstanceService) getServiceInterface(\"JobInstanceService\");\r\n\r\n    private AccountingWritingService accountingWritingService = (AccountingWritingService) getServiceInterface(\"AccountingWritingService\");\r\n    private AccountingCodeService accountingCodeService = (AccountingCodeService) getServiceInterface(\"AccountingCodeService\");\r\n\r\n    private OCCTemplateService occTemplateService = (OCCTemplateService) getServiceInterface(\"OCCTemplateService\");\r\n    \r\n    private InvoiceSubCategoryService invoiceSubCategoryService = (InvoiceSubCategoryService) getServiceInterface(\"InvoiceSubCategoryService\");\r\n    private InvoiceCategoryService invoiceCategoryService = (InvoiceCategoryService) getServiceInterface(\"InvoiceCategoryService\");\r\n\r\n    private DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat.getInstance(Locale.FRENCH);\r\n    \r\n\r\n    private long coutJobExecution = 0l;\r\n\r\n    private StringBuilder contentBuilder = new StringBuilder();\r\n\r\n    private static class Zone {\r\n        int lg;\r\n        String value;\r\n        String padStr = PAD_STR;\r\n        boolean leftPad = false;\r\n\r\n        public Zone(int lg, String value) {\r\n            this.lg = lg;\r\n            this.value = value;\r\n        }\r\n\r\n        public Zone(int lg, String value, String padStr, boolean leftPad) {\r\n            this.lg = lg;\r\n            this.value = value;\r\n            this.padStr = padStr;\r\n            this.leftPad = leftPad;\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void execute(Map<String, Object> context) throws BusinessException {\r\n    \t\r\n    \t Date lastExecutionDate = new Date(1);\r\n\r\n      //Date lastExecutionDate = DateUtils.setDateToStartOfDay(DateUtils.addDaysToDate(new Date(), -1));\r\n      \r\n    \r\n      \r\n\r\n        decimalFormat.setDecimalSeparatorAlwaysShown(true);\r\n        decimalFormat.setGroupingUsed(false);\r\n        decimalFormat.setMinimumFractionDigits(2);\r\n\r\n        log.info(\"Execute ExportRapsodie - Context: {}\", context);\r\n        Provider appProvider = ((ProviderService) getServiceInterface(\"ProviderService\")).getProvider();\r\n        String fileNameParam = (String) context.get(\"fileName\");\r\n        String outputDirParam = (String) context.get(\"outputDir\");\r\n        String archivedDirParam = (String) context.get(\"archivedDir\");\r\n\r\n        String chrootDir = ParamBean.getInstance().getChrootDir(appProvider.getCode());\r\n        String absoluteOutputFileName = chrootDir;\r\n        String absoluteArchivedFileName = chrootDir;\r\n        if (!StringUtils.isBlank(outputDirParam)) {\r\n            absoluteOutputFileName += File.separator + outputDirParam.replaceAll(\"\\\\..\", \"\");\r\n        }\r\n        if (!StringUtils.isBlank(archivedDirParam)) {\r\n            absoluteArchivedFileName += File.separator + archivedDirParam.replaceAll(\"\\\\..\", \"\");\r\n        }\r\n\r\n        // make dir if doesnt exist\r\n        File outputDir = new File(absoluteOutputFileName);\r\n        if (!outputDir.exists()) {\r\n            outputDir.mkdirs();\r\n        }\r\n        File archivedDir = new File(absoluteArchivedFileName);\r\n        if (!archivedDir.exists()) {\r\n            archivedDir.mkdirs();\r\n        }\r\n\r\n        // file name\r\n        if (!StringUtils.isBlank(fileNameParam)) {\r\n            absoluteOutputFileName += File.separator + fileNameParam;\r\n            absoluteArchivedFileName += File.separator + fileNameParam;\r\n        } else {\r\n        \tabsoluteOutputFileName += File.separator + OC_CODE + \"_\" + ORGA_CODE + \"_\" + DateUtils.formatDateWithPattern(new Date(), \"ddMMyyyy_HHmmss\");\r\n        \tabsoluteArchivedFileName += File.separator + OC_CODE + \"_\" + ORGA_CODE + \"_\" + DateUtils.formatDateWithPattern(new Date(), \"ddMMyyyy_HHmmss\");\r\n        }\r\n\r\n        // 0 : batch input (BGR00)\r\n        buildBGR00();\r\n        contentBuilder.append(NEW_LINE);\r\n\r\n        int index = 1;\r\n        int index2 = index;\r\n\r\n        List<String> lines = new ArrayList<String>();\r\n        Map<String, AccountingEntry> invoiceWritings = getInvoiceWritings();\r\n        log.info(\"invoiceWritings.size() : \" + invoiceWritings.size());\r\n        for (Entry<String, AccountingEntry> entry : invoiceWritings.entrySet()) {\r\n            log.info(\"key = {}\", entry.getKey());\r\n            log.debug(\"key = {}\", entry.getKey());\r\n\r\n            AccountingEntry invoiceWriting = entry.getValue();\r\n            Map<String, AccountingEntry> invoiceSubcatWritings = null;\r\n            Map<String, AccountingEntry> taxWritings = null;\r\n\r\n            if (!invoiceWriting.getIsWritten()) {\r\n\r\n                lines.add(buildBBKPF(invoiceWriting.getEventDate(), new Date(), index++));\r\n                index2 = index - 1;\r\n                String OCEDateNumLecture = PREFIX + DateUtils.formatDateWithPattern(new Date(), \"ddMMyyyy\") + index2;\r\n\t\t\t\t\r\n\t\t\t\tlog.info(\"accountigcode InvoiceW==>\"+invoiceWriting.getAccountingCode().getCode());\r\n\t\t\t\tlog.info(\"eventDate InvoiceW==>\"+invoiceWriting.getEventDate());\r\n\r\n                invoiceSubcatWritings = getInvoiceSubcatsWritings(invoiceWriting.getEventDate(), invoiceWriting.getAccountingCode().getCode(), null);\r\n                log.info(\"invoicessubcateg size==>\"+ invoiceSubcatWritings.size());\r\n                for (Entry<String, AccountingEntry> entry2 : invoiceSubcatWritings.entrySet()) {\r\n                    AccountingEntry invoiceSubcatWriting = entry2.getValue();\t\t\t\t\t\r\n                    invoiceSubcatWriting.setExtraParam2(OCEDateNumLecture);\r\n                    String invoiceCategoryCode = invoiceSubcatWriting.getInvoiceCategory().getCode();\r\n\t\t\t\t\tlog.info(\"invoiceCategoryCode_InvoiceW entry2==>\"+ invoiceCategoryCode);\r\n                    String costl = getCostl(invoiceCategoryCode);\r\n                    String operationType = getOperationType(invoiceSubcatWriting);\r\n                   \r\n                    String taxCode = invoiceSubcatWriting.getTax().getCode();\r\n                    log.info(\"invoiceSubcatWriting.getTax()=>\"+taxCode);\r\n                    String eventType = getEventType(invoiceWriting);\r\n                    String line = buildBBSEG(operationType, eventType, leftPad(round(invoiceSubcatWriting.getAmount().abs(), 2), 16, \"0\"), null,\r\n                            ZUONREnum.INVOICE.getLabel(), taxCode, invoiceSubcatWriting.getAccountingCode().getCode(), costl);\r\n                    lines.add(line);\r\n                }\r\n\r\n                log.info(\"accCodeFor_taxWritings==>\"+invoiceWriting.getAccountingCode().getCode());\r\n                taxWritings = getTaxWritings(invoiceWriting.getEventDate(), invoiceWriting.getAccountingCode().getCode(), null);\r\n                log.info(\"invoicesTax_size=>\"+taxWritings.size());\r\n                for (Entry<String, AccountingEntry> entry2 : taxWritings.entrySet()) {\r\n                    AccountingEntry taxWriting = entry2.getValue();\r\n\t\t\t\t\tlog.info(\"taxWriting entry2==>\"+ taxWriting);\r\n                    taxWriting.setExtraParam2(OCEDateNumLecture);\r\n                    String operationType = getOperationType(taxWriting);\r\n                    String taxCode = taxWriting.getTax().getCode();\r\n                    String taxLine = buildBBTAX(operationType, leftPad(round(taxWriting.getAmount().abs(), 2), 16, \"0\"), taxCode);\r\n                    lines.add(taxLine);\r\n                }\r\n\r\n                String eventType = getEventType(invoiceWriting);\r\n                String accountType = DEBIT;\r\n                if (invoiceWriting.getAmount().compareTo(BigDecimal.ZERO) < 0) {\r\n                    accountType = CREDIT;\r\n                }\r\n                invoiceWriting.setExtraParam2(OCEDateNumLecture);\r\n                lines.add(buildBBSEG(accountType, eventType, leftPad(round(invoiceWriting.getAmount().abs(), 2), 16, \"0\"), null, ZUONREnum.INVOICE.getLabel(), \"\",\r\n                        invoiceWriting.getAccountingCode().getCode(), null));\r\n\r\n            }\r\n\r\n            // create writings\r\n            if (!invoiceWriting.getIsWritten()) {\r\n                accountingWritingService.create(invoiceWriting);\r\n                invoiceWriting.setIsWritten(true);\r\n            }\r\n\r\n            if (invoiceSubcatWritings != null) {\r\n                for (Entry<String, AccountingEntry> entry2 : invoiceSubcatWritings.entrySet()) {\r\n                    AccountingEntry invoiceSubcatWriting = entry2.getValue();\r\n                    accountingWritingService.create(invoiceSubcatWriting);\r\n                }\r\n            }\r\n\r\n            if (taxWritings != null) {\r\n                for (Entry<String, AccountingEntry> entry2 : taxWritings.entrySet()) {\r\n                    AccountingEntry taxWriting = entry2.getValue();\r\n                    accountingWritingService.create(taxWriting);\r\n                }\r\n            }\r\n\r\n        }\r\n        log.info(\"paymentsDeb\");\r\n        Map<String, AccountingEntry> paymentWritings = getPaymentWritings(lastExecutionDate);\r\n        log.info(\"payments\");\r\n        log.info(\"paymentWritings rsltsize=>\"+paymentWritings.size());\r\n        log.info(\"paymentWritings rslt=>\"+paymentWritings);\r\n        for (Entry<String, AccountingEntry> entry2 : paymentWritings.entrySet()) {\r\n            AccountingEntry paymentWriting = entry2.getValue();\r\n\r\n            lines.add(buildBBKPF(paymentWriting.getEventDate(), new Date(), index++));\r\n            index2 = index - 1;\r\n            String OCEDateNumLecture = PREFIX + DateUtils.formatDateWithPattern(new Date(), \"ddMMyyyy\") + index2;\r\n            paymentWriting.setExtraParam2(OCEDateNumLecture);\r\n\r\n            String occCode = \"\";\r\n            String costl = \"\";\r\n            log.info(\"afficher paymentWriting=>\"+paymentWriting);\r\n            \r\n            Tax tax=findTaxByCode(\"V0\");\r\n            log.info(\"tax V0 get ==>\"+tax);\r\n            String taxCode= \"\";\r\n            for (AccountOperation ao : paymentWriting.getAccountOperations()) {\r\n                occCode = ao.getCode();\r\n                log.info(\"afficher occCode AccOperation==>\"+occCode);\r\n                costl = getCostl(occCode);\r\n                log.info(\"afficher new costl=>\"+costl);\r\n                if(occCode.equals(\"PAY_FF\")){\r\n                    paymentWriting.setTax(tax);\r\n                    taxCode= paymentWriting.getTax().getCode();\r\n                    log.info(\"ForV0_taxCode=>\"+taxCode);\r\n                }\r\n                \r\n                \r\n            }\r\n\r\n            String line = buildBBSEG(DEBIT, paymentWriting.getEventType(), leftPad(round(paymentWriting.getAmount(), 2), 16, \"0\"), paymentWriting.getEventDate(), getZUONR(occCode, paymentWriting.getAccountingCode().getCode()), taxCode, paymentWriting.getAccountingCode().getCode(), costl);\r\n            lines.add(line);\r\n\r\n            String lineInvoicing = buildBBSEG(CREDIT, paymentWriting.getEventType(), leftPad(round(paymentWriting.getAmount(), 2), 16, \"0\"), paymentWriting.getEventDate(), getZUONR(occCode, paymentWriting.getExtraParam1()), \"\", paymentWriting.getExtraParam1(), null);\r\n            lines.add(lineInvoicing);\r\n        }\r\n\r\n        for (Entry<String, AccountingEntry> entry2 : paymentWritings.entrySet()) {\r\n            AccountingEntry paymentWriting = entry2.getValue();\r\n\t\t\tlog.info(\"paymentW==>\"+paymentWriting);\r\n            accountingWritingService.create(paymentWriting);\r\n            AccountingEntry paymentWriting2 = new AccountingEntry();\r\n            paymentWriting2.setAccountOperations(paymentWriting.getAccountOperations());\r\n            paymentWriting2.setExtraParam2(paymentWriting.getExtraParam2());\r\n            paymentWriting2.setAmount(paymentWriting.getAmount());\r\n            paymentWriting2.setEventDate(paymentWriting.getEventDate());\r\n            paymentWriting2.setExportDate(paymentWriting.getExportDate());\r\n            paymentWriting2.setEventType(paymentWriting.getEventType());\r\n            paymentWriting2.setAccountingCode(accountingCodeService.findByCode(paymentWriting.getExtraParam1()));\r\n            accountingWritingService.create(paymentWriting2);\r\n        }\r\n\r\n        Map<String, AccountingEntry> refundWritings = getRefundWritings(lastExecutionDate);\r\n        log.info(\"refundWritings==>\"+refundWritings);\r\n        for (Entry<String, AccountingEntry> entry3 : refundWritings.entrySet()) {\r\n            AccountingEntry refundWriting = entry3.getValue();\r\n\r\n            lines.add(buildBBKPF(refundWriting.getEventDate(), new Date(), index++));\r\n            index2 = index - 1;\r\n            String OCEDateNumLecture = PREFIX + DateUtils.formatDateWithPattern(new Date(), \"ddMMyyyy\") + index2;\r\n            refundWriting.setExtraParam2(OCEDateNumLecture);\r\n\r\n            String occCode = \"\";\r\n            for (AccountOperation ao : refundWriting.getAccountOperations()) {\r\n                occCode = ao.getCode();\r\n\t\t\t\t log.info(\"occCode_refundWritings==>\"+occCode);\r\n            }\r\n\r\n            String line = buildBBSEG(DEBIT, refundWriting.getEventType(), leftPad(round(refundWriting.getAmount(), 2), 16, \"0\"), refundWriting.getEventDate(), getZUONR(occCode, refundWriting.getAccountingCode().getCode()), \"\", refundWriting.getAccountingCode().getCode(), null);\r\n            lines.add(line);\r\n\r\n            String linePayment = buildBBSEG(CREDIT, refundWriting.getEventType(), leftPad(round(refundWriting.getAmount(), 2), 16, \"0\"), refundWriting.getEventDate(), getZUONR(occCode, refundWriting.getExtraParam1()), \"\", refundWriting.getExtraParam1(), null);\r\n            lines.add(linePayment);\r\n        }\r\n\r\n        for (Entry<String, AccountingEntry> entry2 : refundWritings.entrySet()) {\r\n            AccountingEntry refundWriting = entry2.getValue();\r\n            accountingWritingService.create(refundWriting);\r\n            AccountingEntry refundWriting2 = new AccountingEntry();\r\n            refundWriting2.setAccountOperations(refundWriting.getAccountOperations());\r\n            refundWriting2.setExtraParam2(refundWriting.getExtraParam2());\r\n            refundWriting2.setAmount(refundWriting.getAmount());\r\n            refundWriting2.setEventDate(refundWriting.getEventDate());\r\n            refundWriting2.setExportDate(refundWriting.getExportDate());\r\n            refundWriting2.setEventType(refundWriting.getEventType());\r\n            refundWriting2.setAccountingCode(accountingCodeService.findByCode(refundWriting.getExtraParam1()));\r\n            accountingWritingService.create(refundWriting2);\r\n        }\r\n\r\n\r\n        //pour les lignes des annulations des commandes\r\n        List<String> invoiceNumberList = getCancelinvoices(lastExecutionDate);\r\n\t\tlog.info(\"invoiceNumberList_cancelInvoices==>\"+invoiceNumberList);\r\n        if (invoiceNumberList.size() > 0) {\r\n\r\n            Map<String, AccountingEntry> invoiceWritingsAvoir = getAvoirWritings(invoiceNumberList);\r\n\r\n            for (Entry<String, AccountingEntry> entry : invoiceWritingsAvoir.entrySet()) {\r\n\r\n                log.info(\"key = {}\", entry.getKey());\r\n\r\n                AccountingEntry invoiceWriting = entry.getValue();\r\n                Map<String, AccountingEntry> invoiceSubcatWritings = null;\r\n                Map<String, AccountingEntry> taxWritings = null;\r\n\r\n                if (!invoiceWriting.getIsWritten()) {\r\n\r\n                    lines.add(buildBBKPF(invoiceWriting.getEventDate(), new Date(), index++));\r\n                    index2 = index - 1;\r\n                    String OCEDateNumLecture = PREFIX + DateUtils.formatDateWithPattern(new Date(), \"ddMMyyyy\") + index2;\r\n\r\n                    invoiceSubcatWritings = getInvoiceSubcatsWritings(invoiceWriting.getEventDate(), invoiceWriting.getAccountingCode().getCode(), invoiceNumberList);\r\n                    for (Entry<String, AccountingEntry> entry2 : invoiceSubcatWritings.entrySet()) {\r\n                        AccountingEntry invoiceSubcatWriting = entry2.getValue();\r\n                        invoiceSubcatWriting.setExtraParam2(OCEDateNumLecture);\r\n                        String invoiceCategoryCode = invoiceSubcatWriting.getInvoiceCategory().getCode();\r\n\t\t\t\t\t\tlog.info(\"invoiceCategoryCode==>\"+invoiceCategoryCode);\r\n                        String costl = getCostl(invoiceCategoryCode);\r\n                        String operationType = getOperationTypeAvoir(invoiceSubcatWriting);\r\n                        String taxCode = invoiceSubcatWriting.getTax().getCode();\r\n                        String eventType = EventEnum.ANNULATION_FACTURATION.getLabel();//getEventType(invoiceWriting);\r\n                        String line = buildBBSEG(operationType, eventType, leftPad(round(invoiceSubcatWriting.getAmount().abs(), 2), 16, \"0\"), null,\r\n                                ZUONREnum.INVOICE.getLabel(), taxCode, invoiceSubcatWriting.getAccountingCode().getCode(), costl);\r\n                        lines.add(line);\r\n                    }\r\n\r\n                    taxWritings = getTaxWritings(invoiceWriting.getEventDate(), invoiceWriting.getAccountingCode().getCode(), invoiceNumberList);\r\n                    for (Entry<String, AccountingEntry> entry2 : taxWritings.entrySet()) {\r\n                        AccountingEntry taxWriting = entry2.getValue();\r\n                        taxWriting.setExtraParam2(OCEDateNumLecture);\r\n                        String operationType = getOperationTypeAvoir(taxWriting);\r\n                        String taxCode = taxWriting.getTax().getCode();\r\n                        String taxLine = buildBBTAX(operationType, leftPad(round(taxWriting.getAmount().abs(), 2), 16, \"0\"), taxCode);\r\n                        lines.add(taxLine);\r\n                    }\r\n\r\n                    String eventType = EventEnum.ANNULATION_FACTURATION.getLabel();//getEventType(invoiceWriting);\r\n                    String accountType = CREDIT;\r\n                    if (invoiceWriting.getAmount().compareTo(BigDecimal.ZERO) < 0) {\r\n                        accountType = DEBIT;\r\n                    }\r\n                    invoiceWriting.setExtraParam2(OCEDateNumLecture);\r\n                    lines.add(buildBBSEG(accountType, eventType, leftPad(round(invoiceWriting.getAmount().abs(), 2), 16, \"0\"), null, ZUONREnum.INVOICE.getLabel(), \"\",\r\n                            invoiceWriting.getAccountingCode().getCode(), null));\r\n\r\n                }\r\n\r\n                // create writings\r\n                if (!invoiceWriting.getIsWritten()) {\r\n                    accountingWritingService.create(invoiceWriting);\r\n                    invoiceWriting.setIsWritten(true);\r\n                }\r\n\r\n                if (invoiceSubcatWritings != null) {\r\n                    for (Entry<String, AccountingEntry> entry2 : invoiceSubcatWritings.entrySet()) {\r\n                        AccountingEntry invoiceSubcatWriting = entry2.getValue();\r\n                        accountingWritingService.create(invoiceSubcatWriting);\r\n                    }\r\n                }\r\n\r\n                if (taxWritings != null) {\r\n                    for (Entry<String, AccountingEntry> entry2 : taxWritings.entrySet()) {\r\n                        AccountingEntry taxWriting = entry2.getValue();\r\n                        accountingWritingService.create(taxWriting);\r\n                    }\r\n                }\r\n\r\n            }\r\n\r\n\r\n        }\r\n\r\n\r\n\r\n        try {\r\n            if(lines.size() > 0) {\r\n                for (String line : lines) {\r\n                    appendLine(line);\r\n                }\r\n                contentBuilder.deleteCharAt(contentBuilder.lastIndexOf(NEW_LINE));\r\n                Files.write(contentBuilder, new File(absoluteOutputFileName), Charsets.UTF_8);\r\n                Files.write(contentBuilder, new File(absoluteArchivedFileName), Charsets.UTF_8);\r\n            }\r\n        } catch (IOException e) {\r\n            throw new BusinessException(e);\r\n        }\r\n\r\n    }\r\n    private Map<String, AccountingEntry> getAvoirWritings(List<String> invoiceNumberList) {\r\n\r\n\r\n        Map<String, Object> params = new HashMap<>();\r\n        log.info(\"invoiceNumberListAvoir\"+invoiceNumberList);\r\n        params.put(\"invoiceList\", invoiceNumberList);\r\n        log.info(\"params\"+params);\r\n        String    query = \"Select cast(inv.recordedInvoice.auditable.created as date), inv, inv.invoiceNumber FROM Invoice inv \"\r\n                + \" WHERE ( (inv.recordedInvoice is not null and cfValues like '%CF_DATE_FIN_INSTALLATION%' and invoiceType.code = 'INS') or (inv.recordedInvoice is not null and invoiceType.code = 'PVT' ) ) and inv.invoiceNumber in :invoiceList  and inv.seller.code = '\"+SELLER_CODE+\"' \";\r\n\r\n\r\n        OCCTemplate occTemplateRefInv = occTemplateService.findByCode(OCC_TEMP_CODE_REF_INV);\r\n        Map<String, AccountingEntry> accountingEntries = new HashMap<String, AccountingEntry>();\r\n\r\n\r\n        List<Object[]> rows = (List<Object[]>) invoiceService.executeSelectQuery(query, params);\r\n        log.info(\"okkkkk\"+rows);\r\n        for (Object[] row : rows) {\r\n            Date date = (Date) row[0];\r\n            Invoice invoice = (Invoice) row[1];\r\n            String invoiceNumber = (String) row[2];\r\n\r\n            log.info(\"---- facture : \");\r\n            log.info(\"date = {}\", date);\r\n            log.info(\"invoiceNumber = {}\", invoiceNumber);\r\n\r\n\r\n            String key = date+\"_\"+occTemplateRefInv.getAccountingCode().getCode();\r\n\t\t\tlog.info(\"keyAvoir ==>\"+key);\r\n\r\n            AccountingEntry accountingWriting = new AccountingEntry();\r\n            List<AccountOperation> accountOperations = new ArrayList<AccountOperation>();\r\n            if(accountingEntries.get(key) != null) {\r\n                accountingWriting = accountingEntries.get(key);\r\n                accountingWriting.setAmount(invoice.getAmountWithTax().add(accountingWriting.getAmount()));\r\n                accountOperations.addAll(accountingWriting.getAccountOperations());\r\n            } else {\r\n                accountingWriting.setAmount(invoice.getAmountWithTax());\r\n            }\r\n            accountOperations.add(invoice.getRecordedInvoice());\r\n\r\n            accountingWriting.setAccountingCode(occTemplateRefInv.getAccountingCode());\r\n            accountingWriting.setAccountOperations(accountOperations);\r\n            accountingWriting.setEventType(EventEnum.ANNULATION_FACTURATION.getLabel());\r\n            accountingWriting.setEventDate(date);\r\n            accountingWriting.setExportDate(new Date());\r\n            accountingWriting.setIsWritten(false);\r\n            accountingEntries.put(key, accountingWriting);\r\n        }\r\n\r\n        return accountingEntries;\r\n    }\r\n\r\n    private Map<String, AccountingEntry> getInvoiceWritings() {\r\n\r\n\r\n        Map<String, Object> params = new HashMap<>();\r\n\r\n\r\n        String   query = \"Select cast(inv.recordedInvoice.auditable.created as date), inv, inv.invoiceNumber FROM Invoice inv \"\r\n                + \" WHERE inv.recordedInvoice is not null  AND inv.seller.code = '\"+SELLER_CODE+\"' \";\r\n\r\n\r\n\r\n\r\n        Map<String, AccountingEntry> accountingEntries = new HashMap<String, AccountingEntry>();\r\n\r\n\r\n        List<Object[]> rows = (List<Object[]>) invoiceService.executeSelectQuery(query, params);\r\n        log.info(\"query invoiceWritings.size() :  ==>\"+ rows.size());  \r\n        for (Object[] row : rows) {\r\n            Date date = (Date) row[0];\r\n            Invoice invoice = (Invoice) row[1];\r\n            String invoiceNumber = (String) row[2];\r\n\r\n            //log.info(\"---- facture : \");\r\n            //log.info(\"date_IW ==>\"+ date);\r\n            //log.info(\"invoiceNumber_IW ==>\"+ invoiceNumber);\r\n\r\n            Boolean isWritten = !invoice.getRecordedInvoice().getAccountingEntries().isEmpty();\r\n\r\n            String key = date+\"_\"+isWritten+\"_\"+invoice.getInvoiceType().getOccTemplate().getAccountingCode().getCode();\r\n            log.info(\"key in invoiceW ==>\"+ key);\r\n\t\t\t\r\n            AccountingEntry accountingWriting = new AccountingEntry();\r\n            List<AccountOperation> accountOperations = new ArrayList<AccountOperation>();\r\n            if(accountingEntries.get(key) != null) {\r\n                accountingWriting = accountingEntries.get(key);\r\n\t\t\t\tlog.info(\"invoice.getAmountWithTax in invoiceW ==>\"+ invoice.getAmountWithTax());\r\n\t\t\t\tlog.info(\"accountingWriting.getAmount in invoiceW ==>\"+ accountingWriting.getAmount());\r\n                accountingWriting.setAmount(invoice.getAmountWithTax().add(accountingWriting.getAmount()));\r\n                accountOperations.addAll(accountingWriting.getAccountOperations());\r\n            } else {\r\n\t\t\t\tlog.info(\"new invoice.getAmountWithTax in invoiceW ==>\"+invoice.getAmountWithTax());\r\n                accountingWriting.setAmount(invoice.getAmountWithTax());\r\n            }\r\n            accountOperations.add(invoice.getRecordedInvoice());\r\n\r\n            accountingWriting.setAccountingCode(invoice.getInvoiceType().getOccTemplate().getAccountingCode());\r\n            accountingWriting.setAccountOperations(accountOperations);\r\n            accountingWriting.setEventType(EventEnum.FACTURATION.getLabel());\r\n            accountingWriting.setEventDate(date);\r\n            accountingWriting.setExportDate(new Date());\r\n            accountingWriting.setIsWritten(isWritten);\r\n            accountingEntries.put(key, accountingWriting);\r\n        }\r\n\r\n        return accountingEntries;\r\n    }\r\n\r\n  /*  private Map<String, AccountingEntry> getPaymentWritings(Date date, String accountingCode) {\r\n\r\n        Map<String, AccountingEntry> accountingEntries = new HashMap<String, AccountingEntry>();\r\n\r\n        String query = \"Select cast(ma2.accountOperation.auditable.created as date), ma2   \"\r\n                + \" FROM MatchingCode mc2 JOIN mc2.matchingAmounts ma2 \"\r\n                + \" WHERE mc2 IN \"\r\n                + \" (SELECT mc FROM MatchingCode mc JOIN mc.matchingAmounts ma \"\r\n                + \" WHERE ma.accountOperation.transactionCategory = org.meveo.model.payments.OperationCategoryEnum.DEBIT AND ma.accountOperation.occCode != 'REJ_DDT' \"\r\n                + \" AND ma.accountOperation.accountingCode.code=:accountingCode)\"\r\n                + \" AND ma2.accountOperation.transactionCategory = org.meveo.model.payments.OperationCategoryEnum.CREDIT\"\r\n                + \" AND ma2.accountOperation.accountingEntries is empty\"\r\n                +\"AND cast(ma.accountOperation.auditable.created ) > :date\";\r\n\r\n\r\n        Map<String, Object> params = new HashMap<>();\r\n        params.put(\"accountingCode\", accountingCode);\r\n        params.put(\"date\", date);\r\n\r\n        List<Object[]> rows = (List<Object[]>) invoiceService.executeSelectQuery(query, params);\r\n\r\n\r\n        for (Object[] row : rows) {\r\n\r\n            MatchingAmount matchingAmount = (MatchingAmount) row[1];\r\n            AccountOperation accountOperation = matchingAmount.getAccountOperation();\r\n            BigDecimal amount = matchingAmount.getMatchingAmount();\r\n            String paymentAccountCode = accountOperation.getAccountingCode().getCode();\r\n            String occCode = accountOperation.getOccCode();\r\n\r\n            log.debug(\"---- encaissement : \");\r\n            log.debug(\"matchingAmount = {}\", amount);\r\n            log.debug(\"accountCode = {}\", paymentAccountCode);\r\n            log.debug(\"occCode = {}\", occCode);\r\n\r\n            String key = date+\"_\"+paymentAccountCode+\"_\"+occCode;\r\n\r\n            AccountingEntry accountingWriting = new AccountingEntry();\r\n            List<AccountOperation> accountOperations = new ArrayList<AccountOperation>();\r\n            if(accountingEntries.get(key) != null) {\r\n                accountingWriting = accountingEntries.get(key);\r\n                accountingWriting.setAmount(amount.add(accountingWriting.getAmount()));\r\n                accountOperations.addAll(accountingWriting.getAccountOperations());\r\n            } else {\r\n                accountingWriting.setAmount(amount);\r\n            }\r\n\r\n            AccountOperation aoInList = accountOperations.stream().filter(ao -> accountOperation.getId().equals(ao.getId())).findAny().orElse(null);\r\n            if(aoInList == null) {\r\n                log.debug(\"# adding AO to AW\");\r\n                accountOperations.add(accountOperation);\r\n            }\r\n\r\n            accountingWriting.setAccountingCode(matchingAmount.getAccountOperation().getAccountingCode());\r\n            accountingWriting.setAccountOperations(accountOperations);\r\n            accountingWriting.setEventType(getEventLabel(occCode));\r\n            accountingWriting.setEventDate(date);\r\n            accountingWriting.setExportDate(new Date());\r\n            accountingWriting.setIsWritten(false);\r\n            accountingEntries.put(key, accountingWriting);\r\n\r\n        }\r\n\r\n        return accountingEntries;\r\n    }\r\n*/\r\n\r\n    private Map<String, AccountingEntry> getPaymentWritings(Date date) {\r\n\r\n        Map<String, AccountingEntry> accountingEntries = new HashMap<String, AccountingEntry>();\r\n\r\n        String query = \"Select cast(ma2.accountOperation.auditable.created as date), ma2, mc2 \"\r\n                + \" FROM MatchingCode mc2 JOIN mc2.matchingAmounts ma2 \"\r\n               // + \" WHERE mc2 IN \"\r\n               // + \" (SELECT mc FROM MatchingCode mc JOIN mc.matchingAmounts ma \"\r\n               // + \" WHERE ma.accountOperation.transactionCategory = org.meveo.model.payments.OperationCategoryEnum.DEBIT AND ma.accountOperation.code != 'REJ_DDT' AND ma.accountOperation.code not like 'REF%') \"\r\n               // + \" AND ma2.accountOperation.transactionCategory = org.meveo.model.payments.OperationCategoryEnum.CREDIT\"\r\n                + \" WHERE ma2.accountOperation.transactionCategory = org.meveo.model.payments.OperationCategoryEnum.CREDIT\"\r\n                + \" AND ma2.auditable.created > :date\"\r\n                + \" AND ma2.accountOperation.code != 'REF_INV'\"\r\n                + \" AND ma2.accountOperation.accountingEntries is empty  AND ma2.accountOperation.seller.code = '\"+SELLER_CODE+\"' \";\r\n\r\n\r\n\r\n        Map<String, Object> params = new HashMap<>();\r\n        params.put(\"date\", date);\r\n\r\n        List<Object[]> rows = (List<Object[]>) invoiceService.executeSelectQuery(query, params);\r\n        log.info(\"resultPaymentMatched=>\"+rows.size());\r\n        //if(rows.isEmpty()){\r\n           // accountingEntries= getPaymentNotMatchedWritings(date);\r\n           // log.info(\"result getPaymentNotMatchedWritings=>\"+accountingEntries);\r\n        //}\r\n       \r\n       // else{\r\n        for (Object[] row : rows) {\r\n\r\n            Date eventDate = (Date) row[0];\r\n            MatchingAmount matchingAmount = (MatchingAmount) row[1];\r\n            MatchingCode matchingCode = (MatchingCode) row[2];\r\n            List<MatchingAmount> matchingAmounts = matchingCode.getMatchingAmounts();\r\n            MatchingAmount invoiceMatchingAmount = matchingAmounts.stream().filter(ma ->\r\n                    org.meveo.model.payments.OperationCategoryEnum.DEBIT.equals(ma.getAccountOperation().getTransactionCategory())\r\n            ).findAny().orElse(null);\r\n\r\n            AccountOperation accountOperation = matchingAmount.getAccountOperation();\r\n            log.info(\"accountOperation in paymentWritings=>\"+accountOperation);\r\n            BigDecimal amount = matchingAmount.getMatchingAmount();\r\n            String paymentAccountCode = accountOperation.getAccountingCode().getCode();\r\n            String occCode = accountOperation.getCode();\r\n\r\n            log.info(\"---- encaissement : \");\r\n            log.info(\"1matchingAmount ==>\"+ amount);\r\n            log.info(\"1accountCode ==>\"+ paymentAccountCode);\r\n            log.info(\"1occCode ==>\"+ occCode);\r\n            log.info(\"1eventDate ==>\"+ eventDate);\r\n\r\n\r\n            String key = eventDate+\"_\"+paymentAccountCode+\"_\"+occCode;\r\n\t\t\tlog.info(\"1key==>\"+key);\r\n\r\n            AccountingEntry accountingWriting = new AccountingEntry();\r\n            List<AccountOperation> accountOperations = new ArrayList<AccountOperation>();\r\n            if(accountingEntries.get(key) != null) {\r\n                accountingWriting = accountingEntries.get(key);\r\n                log.info(\"accountingWriting.getAmount()==>\"+accountingWriting.getAmount());\r\n                accountingWriting.setAmount(amount.add(accountingWriting.getAmount()));\r\n                log.info(\"accountingWritingAdded.getAmount()==>\"+accountingWriting.getAmount());\r\n                accountOperations.addAll(accountingWriting.getAccountOperations());\r\n                log.info(\"accountingWriting.getAccountOperations()=>\"+accountOperations);\r\n                log.info(\"accountOperations.addAll=>\"+accountingWriting.getAccountOperations());\r\n            } else {\r\n                accountingWriting.setAmount(amount);\r\n            }\r\n\r\n            AccountOperation aoInList = accountOperations.stream().filter(ao -> accountOperation.getId().equals(ao.getId())).findAny().orElse(null);\r\n            if(aoInList == null) {\r\n                log.debug(\"# adding Payment AO to AW\");\r\n                accountOperations.add(accountOperation);\r\n            }\r\n            log.info(\"accountingWritingLogAO\"+matchingAmount.getAccountOperation());\r\n            accountingWriting.setAccountingCode(matchingAmount.getAccountOperation().getAccountingCode());\r\n            accountingWriting.setAccountOperations(accountOperations);\r\n            accountingWriting.setEventType(getEventLabel(occCode));\r\n            accountingWriting.setEventDate(eventDate);\r\n            accountingWriting.setExportDate(new Date());\r\n            accountingWriting.setIsWritten(false);\r\n           /* if(invoiceMatchingAmount==null){// envoyer une AW  d'un paiement meme si la commande de solde n'existe pas encore\r\n                accountingWriting.setExtraParam1(\"411120\");\r\n            }*/\r\n            //else{\r\n                accountingWriting.setExtraParam1(invoiceMatchingAmount.getAccountOperation().getAccountingCode().getCode());\r\n            //}\r\n            log.info(\" accountingWriting.setExtraParam1=>\"+ accountingWriting.getExtraParam1());\r\n            log.info(\"accountingWritingLog=>\"+accountingWriting.getAccountingCode());\r\n            accountingEntries.put(key, accountingWriting);\r\n\t\t\tlog.info(\"accountingEntries PaymentW==>\"+accountingEntries);\r\n\r\n        }\r\n        log.info(\"to enter paymentNotMatchingWritings!\");\r\n        log.info(\"OLD Value list accountingEntries ==>\"+accountingEntries);\r\n        accountingEntries= getPaymentNotMatchedWritings(date);\r\n        log.info(\"NEW Value list accountingEntries ==>\"+accountingEntries);\r\n    //}\r\n\r\n        return accountingEntries;\r\n    }\r\n// add this method to send the AO related to payment even if it not matched and the invoice doesn't exist yet \r\n   \r\n    private Map<String, AccountingEntry> getPaymentNotMatchedWritings(Date date) {\r\n\r\n         Map<String, AccountingEntry> accountingEntries = new HashMap<String, AccountingEntry>();\r\n         //log.info(\"accountingEntries as input =>\"+accountingEntries);\r\n         String query = \"Select cast(ao.auditable.created as date), ao\"\r\n         + \" FROM AccountOperation ao\"\r\n         + \" WHERE ao.transactionCategory = org.meveo.model.payments.OperationCategoryEnum.CREDIT\"\r\n         + \" AND ao.auditable.created > :date\"\r\n         + \" AND ao.code != 'REF_INV'\"\r\n         + \" AND ao.accountingEntries is empty  AND ao.seller.code = '\"+SELLER_CODE+\"' \";\r\n\r\n         Map<String, Object> params = new HashMap<>();\r\n        params.put(\"date\", date);\r\n        List<Object[]> rows = (List<Object[]>) invoiceService.executeSelectQuery(query, params);\r\n        for (Object[] row : rows) {\r\n            Date eventDate = (Date) row[0];\r\n            AccountOperation accountOperation = (AccountOperation) row[1];\r\n            log.info(\"accountOperation in getPaymentNotMatchedWritings=>\"+accountOperation);\r\n            BigDecimal amount = accountOperation.getAmount();\r\n            String paymentAccountCode = accountOperation.getAccountingCode().getCode();\r\n            String occCode = accountOperation.getCode();\r\n            log.info(\"---- encaissement 2: \");\r\n            log.info(\"2Amount ==>\"+ amount);\r\n            log.info(\"2accountCode ==>\"+ paymentAccountCode);\r\n            log.info(\"2occCode ==>\"+ occCode);\r\n            log.info(\"2eventDate ==>\"+ eventDate);\r\n            String key = eventDate+\"_\"+paymentAccountCode+\"_\"+occCode;\r\n\t\t\tlog.info(\"2key==>\"+key);\r\n\r\n            AccountingEntry accountingWriting = new AccountingEntry();\r\n            List<AccountOperation> accountOperations = new ArrayList<AccountOperation>();\r\n            if(accountingEntries.get(key) != null) {\r\n                accountingWriting = accountingEntries.get(key);\r\n\t\t\t\tlog.info(\"accountingWriting.getAmount()==>\"+accountingWriting.getAmount());\r\n                accountingWriting.setAmount(amount.add(accountingWriting.getAmount()));\r\n                log.info(\"accountingWritingAdded.getAmount()==>\"+accountingWriting.getAmount());\r\n                accountOperations.addAll(accountingWriting.getAccountOperations());\r\n                log.info(\"accountingWriting2.getAccountOperations()=>\"+accountOperations);\r\n                log.info(\"accountOperations2.addAll=>\"+accountingWriting.getAccountOperations());\r\n            } else {\r\n\t\t\t\tlog.info(\"new amount==>\"+amount);\r\n                accountingWriting.setAmount(amount);\r\n            }\r\n\r\n            AccountOperation aoInList = accountOperations.stream().filter(ao -> accountOperation.getId().equals(ao.getId())).findAny().orElse(null);\r\n            if(aoInList == null) {\r\n                log.debug(\"# adding Payment AO to AW\");\r\n                accountOperations.add(accountOperation);\r\n            }\r\n            log.info(\"accountOperation.getAccountingCode()=>\"+accountOperation.getAccountingCode());\r\n            accountingWriting.setAccountingCode(accountOperation.getAccountingCode());       \r\n            accountingWriting.setAccountOperations(accountOperations);\r\n            accountingWriting.setEventType(getEventLabel(occCode));\r\n            accountingWriting.setEventDate(eventDate);\r\n            accountingWriting.setExportDate(new Date());\r\n            accountingWriting.setIsWritten(false);\r\n            // envoyer une AW  d'un paiement meme si la commande de solde n'existe pas encore\r\n            accountingWriting.setExtraParam1(\"411120\");\r\n            //accountingWriting.setExtraParam1(invoiceMatchingAmount.getAccountOperation().getAccountingCode().getCode());\r\n            log.info(\" accountingWriting2.setExtraParam1=>\"+ accountingWriting.getExtraParam1());\r\n            log.info(\"accountingWritingLog=>\"+accountingWriting.getAccountingCode());\r\n            accountingEntries.put(key, accountingWriting);\r\n\t\t\tlog.info(\"accountingEntries PaymentW==>\"+accountingEntries);\r\n\r\n        }\r\n        return accountingEntries;\r\n\r\n}\r\n\r\n\r\nprivate Map<String, AccountingEntry> getRefundWritings(Date date) {\r\n\r\n        Map<String, AccountingEntry> accountingEntries = new HashMap<String, AccountingEntry>();\r\n\r\n        String query = \"Select cast(ma2.accountOperation.auditable.created as date), ma2, mc2  \"\r\n                + \" FROM MatchingCode mc2 JOIN mc2.matchingAmounts ma2 \"\r\n                + \" WHERE mc2 IN \"\r\n                + \" (SELECT mc FROM MatchingCode mc JOIN mc.matchingAmounts ma \"\r\n                + \" WHERE ma.accountOperation.transactionCategory = org.meveo.model.payments.OperationCategoryEnum.CREDIT)\"\r\n                + \" AND ma2.accountOperation.transactionCategory = org.meveo.model.payments.OperationCategoryEnum.DEBIT AND ma2.accountOperation.code != 'INV_STD' \"\r\n                + \" AND ma2.auditable.created > :date AND ma2.accountOperation.seller.code = '\"+SELLER_CODE+\"' \";\r\n\r\n        Map<String, Object> params = new HashMap<>();\r\n        params.put(\"date\", date);\r\n\r\n        List<Object[]> rows = (List<Object[]>) invoiceService.executeSelectQuery(query, params);\r\n        log.info(\"rowssize=>\"+rows.size());\r\n        for (Object[] row : rows) {\r\n            Date eventDate = (Date) row[0];\r\n            MatchingAmount matchingAmount = (MatchingAmount) row[1];\r\n            log.info(\"matchingAmount in refundWritings=>\"+matchingAmount);\r\n            MatchingCode matchingCode = (MatchingCode) row[2];\r\n            log.info(\"matchingCode in refundWritings=>\"+matchingCode);\r\n            List<MatchingAmount> matchingAmounts = matchingCode.getMatchingAmounts();\r\n\r\n            MatchingAmount paymentMatchingAmount = matchingAmounts.stream().filter(ma ->\r\n                    org.meveo.model.payments.OperationCategoryEnum.CREDIT.equals(ma.getAccountOperation().getTransactionCategory())\r\n            ).findAny().orElse(null);\r\n\r\n            AccountOperation accountOperation = matchingAmount.getAccountOperation();\r\n            BigDecimal amount = matchingAmount.getMatchingAmount();\r\n            String refundAccountCode = accountOperation.getAccountingCode().getCode();\r\n            String occCode = accountOperation.getCode();\r\n\r\n            log.debug(\"---- remboursement : \");\r\n            log.debug(\"matchingAmount = {}\", matchingAmount);\r\n            log.debug(\"accountCode = {}\", refundAccountCode);\r\n            log.debug(\"occCode = {}\", occCode);\r\n\r\n            String key = date+\"_\"+refundAccountCode+\"_\"+occCode;\r\n\r\n            AccountingEntry accountingWriting = new AccountingEntry();\r\n            List<AccountOperation> refundAccountOperations = new ArrayList<AccountOperation>();\r\n            if(accountingEntries.get(key) != null) {\r\n                accountingWriting = accountingEntries.get(key);\r\n                accountingWriting.setAmount(amount.add(accountingWriting.getAmount()));\r\n                refundAccountOperations.addAll(accountingWriting.getAccountOperations());\r\n            } else {\r\n                accountingWriting.setAmount(amount);\r\n            }\r\n\r\n            AccountOperation aoInList = refundAccountOperations.stream().filter(ao -> accountOperation.getId().equals(ao.getId())).findAny().orElse(null);\r\n            if(aoInList == null) {\r\n                log.debug(\"# adding Refund AO to AW\");\r\n                refundAccountOperations.add(accountOperation);\r\n            }\r\n\r\n            accountingWriting.setAccountingCode(matchingAmount.getAccountOperation().getAccountingCode());\r\n            accountingWriting.setAccountOperations(refundAccountOperations);\r\n            accountingWriting.setEventType(getEventLabel(occCode));\r\n            accountingWriting.setEventDate(eventDate);\r\n            accountingWriting.setExportDate(new Date());\r\n            accountingWriting.setIsWritten(false);\r\n            accountingWriting.setExtraParam1(paymentMatchingAmount.getAccountOperation().getAccountingCode().getCode());\r\n            accountingEntries.put(key, accountingWriting);\r\n\r\n        }\r\n\r\n        return accountingEntries;\r\n    }\r\n\r\n\r\n\r\n    private List<String> getCancelinvoices(Date date) {\r\n        log.info(\"avoir\");\r\n        Map<String, AccountingEntry>  accountingEntries = new HashMap<String, AccountingEntry>();\r\n        List<String> invoiceNumberList = new ArrayList<>();\r\n        String query = \"Select cast(ma2.accountOperation.auditable.created as date), ma2, mc2  \"\r\n                + \" FROM MatchingCode mc2 JOIN mc2.matchingAmounts ma2 \"\r\n                + \" WHERE mc2 IN \"\r\n                + \" (SELECT mc FROM MatchingCode mc JOIN mc.matchingAmounts ma \"\r\n                + \" WHERE ma.accountOperation.transactionCategory = org.meveo.model.payments.OperationCategoryEnum.CREDIT AND ma.accountOperation.code = 'REF_INV' )\"\r\n                + \" AND ma2.accountOperation.transactionCategory = org.meveo.model.payments.OperationCategoryEnum.DEBIT  \"\r\n                + \" AND ma2.auditable.created > :date   AND ma2.accountOperation.seller.code = '\"+SELLER_CODE+\"' \";\r\n\r\n        Map<String, Object> params = new HashMap<>();\r\n        params.put(\"date\", date);\r\n\r\n        List<Object[]> rows = (List<Object[]>) invoiceService.executeSelectQuery(query, params);\r\n\r\n        log.info(\"avoir\"+rows);\r\n\r\n        for (Object[] row : rows) {\r\n            log.info(\"MatchingAmount\"+(MatchingAmount) row[1]);\r\n            log.info(\"MatchingCode\"+(MatchingCode) row[2]);\r\n            Date eventDate = (Date) row[0];\r\n            MatchingAmount matchingAmount = (MatchingAmount) row[1];\r\n            MatchingCode matchingCode = (MatchingCode) row[2];\r\n            List<MatchingAmount> matchingAmounts = matchingCode.getMatchingAmounts();\r\n\r\n            MatchingAmount invoiceMatchingAmount = matchingAmounts.stream().filter(ma ->\r\n                    org.meveo.model.payments.OperationCategoryEnum.DEBIT.equals(ma.getAccountOperation().getTransactionCategory())\r\n            ).findAny().orElse(null);\r\n\r\n            AccountOperation accountOperation = matchingAmount.getAccountOperation();//invoice\r\n            String invoiceNumber = accountOperation.getReference();\r\n            Invoice invoice = findByInvoiceNumber(invoiceNumber);\r\n            invoiceNumberList.add(invoice.getInvoiceNumber());\r\n        }\r\n\r\n        return invoiceNumberList;\r\n    }\r\n\r\n\r\n    private Map<String, AccountingEntry> getTaxWritings(Date date, String accountingCode, List<String> invoiceNumberList) {\r\n\r\n\r\n        Map<String, AccountingEntry> accountingEntries = new HashMap<String, AccountingEntry>();\r\n\r\n        String query = null;\r\n        Map<String, Object> params = new HashMap<>();\r\n        OCCTemplate occTemplateInv = occTemplateService.findByCode(OCC_TEMP_CODE_INV_STD);\r\n\t\t\r\n        if(invoiceNumberList == null) {\r\n            query = \"Select cast(taxInvAgregate.invoice.recordedInvoice.auditable.created as date), taxInvAgregate  \"\r\n                    + \" FROM TaxInvoiceAgregate taxInvAgregate\"\r\n                    + \" WHERE taxInvAgregate.invoice.recordedInvoice is not null  \"\r\n\t\t\t\t\t+ \" AND cast(taxInvAgregate.invoice.recordedInvoice.auditable.created as date)=:date\"\r\n                    + \" AND taxInvAgregate.invoice.invoiceType.occTemplate.accountingCode.code=:accountingCode\"\r\n                    + \" AND taxInvAgregate.invoice.recordedInvoice.accountingEntries is empty  AND taxInvAgregate.invoice.seller.code = '\"+SELLER_CODE+\"' \";\r\n            params.put(\"date\", date);\r\n            params.put(\"accountingCode\", accountingCode);\r\n        }\r\n        else {\r\n\r\n            query = \"Select cast(taxInvAgregate.invoice.recordedInvoice.auditable.created as date), taxInvAgregate  \"\r\n                    + \" FROM TaxInvoiceAgregate taxInvAgregate\"\r\n                    + \" WHERE taxInvAgregate.invoice.recordedInvoice is not null AND cast(taxInvAgregate.invoice.recordedInvoice.auditable.created as date)=:date\"\r\n                    + \" AND taxInvAgregate.invoice.invoiceType.occTemplate.accountingCode.code=:accountingCode\"\r\n                    + \" AND taxInvAgregate.invoice.invoiceNumber in :invoiceNumberList  AND taxInvAgregate.invoice.seller.code = '\"+SELLER_CODE+\"' \";\r\n            params.put(\"invoiceNumberList\", invoiceNumberList);\r\n            params.put(\"accountingCode\", occTemplateInv.getAccountingCode().getCode());\r\n\r\n        }\r\n\r\n\r\n\r\n        params.put(\"date\", date);\r\n\r\n        List<Object[]> rows = (List<Object[]>) invoiceService.executeSelectQuery(query, params);\r\n        log.info(\"tax<riting\"+rows);\r\n        for (Object[] row : rows) {\r\n            TaxInvoiceAgregate taxInvoiceAgregate = (TaxInvoiceAgregate) row[1];\r\n\t\t\tlog.info(\"taxInvoiceAgregate methodTaxWritings==>\"+taxInvoiceAgregate);\r\n\r\n            String amountSign = \"PLUS\";\r\n            if(taxInvoiceAgregate.getAmountTax().compareTo(BigDecimal.ZERO) < 0) {\r\n                amountSign = \"MINUS\";\r\n            }\r\n\r\n            String key = date+\"_\"+taxInvoiceAgregate.getAccountingCode().getCode()+\"_\"+taxInvoiceAgregate.getTax().getCode()+\"_\"+amountSign;\r\n\r\n            AccountingEntry accountingWriting = new AccountingEntry();\r\n            List<AccountOperation> accountOperations = new ArrayList<AccountOperation>();\r\n            if(accountingEntries.get(key) != null) {\r\n                accountingWriting = accountingEntries.get(key);\r\n                accountingWriting.setAmount(taxInvoiceAgregate.getAmountTax().add(accountingWriting.getAmount()));\r\n                accountOperations.addAll(accountingWriting.getAccountOperations());\r\n            } else {\r\n                accountingWriting.setAmount(taxInvoiceAgregate.getAmountTax());\r\n            }\r\n            if(!accountOperations.contains(taxInvoiceAgregate.getInvoice().getRecordedInvoice())) {\r\n                accountOperations.add(taxInvoiceAgregate.getInvoice().getRecordedInvoice());\r\n            }\r\n\r\n            accountingWriting.setAccountingCode(taxInvoiceAgregate.getAccountingCode());\r\n            accountingWriting.setAccountOperations(accountOperations);\r\n            accountingWriting.setTax(taxInvoiceAgregate.getTax());\r\n            accountingWriting.setEventDate(date);\r\n            accountingWriting.setExportDate(new Date());\r\n            accountingEntries.put(key, accountingWriting);\r\n        }\r\n\r\n        for (Entry<String, AccountingEntry> entry : accountingEntries.entrySet()) {\r\n            AccountingEntry accountingWriting = entry.getValue();\r\n            log.debug(\"---- tax : \");\r\n            log.debug(\"date ==>\"+ accountingWriting.getEventDate());\r\n            log.debug(\"tax ==>\"+ accountingWriting.getTax());\r\n            log.debug(\"amount ==>\"+ accountingWriting.getAmount());\r\n            for(AccountOperation ao : accountingWriting.getAccountOperations()) {\r\n                log.debug(\" |__ ao ==>\"+ ao.getId());\r\n            }\r\n        }\r\n\r\n        return accountingEntries;\r\n    }\r\n\r\n    private  Map<String, AccountingEntry> getInvoiceSubcatsWritings(Date date, String accountingCode, List<String> invoiceNumberList) {\r\n\r\n        String query = null;\r\n        Map<String, Object> params = new HashMap<>();\r\n        log.info(\"invoiceNumberList_SubCatW=>\"+invoiceNumberList);\r\n        OCCTemplate occTemplateInv = occTemplateService.findByCode(OCC_TEMP_CODE_INV_STD);\r\n\t\t\r\n        if(invoiceNumberList == null) {\r\n            query = \"Select cast(subCatInvAgregate.invoice.recordedInvoice.auditable.created as date), subCatInvAgregate \"\r\n                    + \" FROM SubCategoryInvoiceAgregate subCatInvAgregate \"\r\n                    + \" WHERE subCatInvAgregate.invoice.recordedInvoice is not null  \"\r\n\t\t\t\t\t+ \" AND cast(subCatInvAgregate.invoice.recordedInvoice.auditable.created as date)=:date\"\r\n                    + \" AND subCatInvAgregate.invoice.invoiceType.occTemplate.accountingCode.code=:accountingCode\"\r\n                    + \" AND subCatInvAgregate.invoice.recordedInvoice.accountingEntries is empty  AND subCatInvAgregate.invoice.seller.code = '\"+SELLER_CODE+\"' \";\r\n\r\n            params.put(\"accountingCode\", accountingCode);\r\n        }\r\n        else {\r\n            log.info(\"okkkk\"+accountingCode);\r\n            query = \"Select cast(subCatInvAgregate.invoice.recordedInvoice.auditable.created as date), subCatInvAgregate \"\r\n                    + \" FROM SubCategoryInvoiceAgregate subCatInvAgregate \"\r\n                    + \" WHERE subCatInvAgregate.invoice.recordedInvoice is not null AND cast(subCatInvAgregate.invoice.recordedInvoice.auditable.created as date)=:date\"\r\n                    + \" AND subCatInvAgregate.invoice.invoiceType.occTemplate.accountingCode.code=:accountingCode\"\r\n                    + \" AND subCatInvAgregate.invoice.invoiceNumber in :invoiceNumberList AND subCatInvAgregate.invoice.seller.code = '\"+SELLER_CODE+\"' \";\r\n\r\n            params.put(\"invoiceNumberList\", invoiceNumberList);\r\n            params.put(\"accountingCode\", occTemplateInv.getAccountingCode().getCode());\r\n\r\n        }\r\n        log.info(\"date here=>\"+date);\r\n        params.put(\"date\", date);\r\n\r\n        Map<String, AccountingEntry> accountingEntries = new HashMap<String, AccountingEntry>();\r\n\r\n\r\n\r\n\r\n        List<Object[]> rows = (List<Object[]>) invoiceService.executeSelectQuery(query, params);\r\n        log.info(\"result\"+rows.size());\r\n        for (Object[] row : rows) {\r\n            SubCategoryInvoiceAgregate subCatInvAgregate = (SubCategoryInvoiceAgregate) row[1];            \r\n\t\t\tlog.info(\"subcat_invoice here=>\"+subCatInvAgregate.getInvoiceSubCategory());\r\n            String queryDistinctTaxClass = \"Select  distinct(rt.taxClass) FROM RatedTransaction rt  WHERE rt.invoiceSubCategory.id=\"\r\n\t\t\t\t\t+ subCatInvAgregate.getInvoiceSubCategory().getId() +\" AND rt.seller.code = '\"+SELLER_CODE+\"' \";\r\n\t\t\tList<TaxClass> listTaxClass = (List<TaxClass>) invoiceService.executeSelectQuery(queryDistinctTaxClass, null);\r\n\t\t\tif (listTaxClass == null || listTaxClass.size() == 0) {\r\n\t\t\t\tthrow new BusinessException(\"No taxes for the subCat:\" + subCatInvAgregate.getInvoiceSubCategory().getCode());\r\n\t\t\t}\r\n\r\n\t\t\tString queryMappingTax = \"select m.tax from TaxMapping m where  m.chargeTaxClass.id=\" + listTaxClass.get(0).getId() + \"\";\r\n\t\t\tList<Tax> taxs = (List<Tax>) invoiceService.executeSelectQuery(queryMappingTax, null);\r\n\t\t\tif (taxs == null || taxs.isEmpty() || taxs.size() > 1) {\r\n\t\t\t\tthrow new BusinessException(\"Cant found tax for the taxClass:\" + listTaxClass.get(0).getCode());\r\n\t\t\t}\r\n\t\t\tTax tax = taxs.get(0);\r\n\t\t\tlog.info(\"tax byOC==>\"+tax);\r\n\r\n\t\t\tString key = date + \"_\" + subCatInvAgregate.getInvoiceSubCategory().getInvoiceCategory().getCode() + \"_\" + subCatInvAgregate.getAccountingCode().getCode() + \"_\" + tax;\r\n            log.info(\"lkey_OC here ==>\"+key);\r\n\t\t\tAccountingEntry accountingWriting = new AccountingEntry();\r\n            List<AccountOperation> accountOperations = new ArrayList<AccountOperation>();\r\n            if(accountingEntries.get(key) != null) {\r\n\t\t\t\tlog.info(\"enter key here!==>\"+key);\r\n                log.info(\"subCatInvAgregate.getAmountWithoutTax() ==>\"+subCatInvAgregate.getAmountWithoutTax());\r\n\t\t\t\tlog.info(\"accountingWriting.getAmount()before ==>\"+accountingWriting.getAmount());\r\n                accountingWriting = accountingEntries.get(key);\r\n                accountingWriting.setAmount(subCatInvAgregate.getAmountWithoutTax().add(accountingWriting.getAmount()));\r\n                log.info(\"accountingWriting.getAmount()after ==>\"+accountingWriting.getAmount());               \r\n\t\t\t   accountOperations.addAll(accountingWriting.getAccountOperations());\r\n            } else {\r\n\t\t\t\t log.info(\"NEW subCatInvAgregate.getAmountWithoutTax()==>\"+subCatInvAgregate.getAmountWithoutTax());\r\n                accountingWriting.setAmount(subCatInvAgregate.getAmountWithoutTax());\r\n            }\r\n            if(!accountOperations.contains(subCatInvAgregate.getInvoice().getRecordedInvoice())) {\r\n                accountOperations.add(subCatInvAgregate.getInvoice().getRecordedInvoice());\r\n            }\r\n\r\n            accountingWriting.setEventDate(date);\r\n            if(invoiceNumberList == null)\r\n                accountingWriting.setEventType(EventEnum.FACTURATION.getLabel());\r\n            else  accountingWriting.setEventType(EventEnum.ANNULATION_FACTURATION.getLabel());\r\n            accountingWriting.setAccountingCode(subCatInvAgregate.getAccountingCode());\r\n            accountingWriting.setInvoiceCategory(subCatInvAgregate.getInvoiceSubCategory().getInvoiceCategory());\r\n            accountingWriting.setExportDate(new Date());\r\n            accountingWriting.setAccountOperations(accountOperations);\r\n            accountingWriting.setTax(tax);\r\n            accountingEntries.put(key, accountingWriting);\r\n\r\n        }\r\n\r\n        for (Entry<String, AccountingEntry> entry : accountingEntries.entrySet()) {\r\n            AccountingEntry accountingWriting = entry.getValue();\r\n            log.debug(\"---- invoiceCategory : \");\r\n            log.debug(\"date ==>\"+ accountingWriting.getEventDate());\r\n            log.debug(\"invoiceCategory ==>\"+ accountingWriting.getInvoiceCategory());\r\n            log.debug(\"amount ==>\"+ accountingWriting.getAmount());\r\n            for(AccountOperation ao : accountingWriting.getAccountOperations()) {\r\n                log.debug(\" |__ ao ==>\"+ ao.getId());\r\n            }\r\n        }\r\n\r\n        return accountingEntries;\r\n    }\r\n\r\n    public Date getJobLastExecutionDate(String jobCode) throws BusinessException {\r\n        JobInstance jobInstance = jobInstanceService.findByCode(jobCode);\r\n        if (jobInstance == null) {\r\n            log.error(\"No Job instance by code {} was found\", jobCode);\r\n            throw new BusinessException(\"No Job instance by code was found\");\r\n        }\r\n\r\n        String query = \"select hist.startDate FROM JobExecutionResultImpl hist WHERE hist.nbItemsCorrectlyProcessed=1 AND hist.jobInstance=:jobInstance ORDER BY hist.startDate desc\";\r\n        Query q = jobInstanceService.getEntityManager().createQuery(query);\r\n        q.setParameter(\"jobInstance\", jobInstance);\r\n\r\n        try {\r\n            List<Object> results = q.getResultList();\r\n            if(results.size() == 0) {\r\n                return null;\r\n            }\r\n            Date lastExecutionDate = (Date) q.getResultList().get(0);\r\n            return lastExecutionDate;\r\n        } catch (Exception e) {\r\n            log.error(\"error = {}\", e);\r\n            return null;\r\n        }\r\n    }\r\n\r\n    public long countJobExecutionHistory(String jobCode, Date startDate, Date endDate) throws BusinessException {\r\n        JobInstance jobInstance = jobInstanceService.findByCode(jobCode);\r\n        if (jobInstance == null) {\r\n            log.error(\"No Job instance by code {} was found\", jobCode);\r\n            throw new BusinessException(\"No Job instance by code was found\");\r\n        }\r\n\r\n        Map<String, Object> params = Maps.newHashMap();\r\n        String query = \"select count(*) FROM JobExecutionResultImpl hist WHERE hist.jobInstance=:jobInstance\";\r\n        params.put(\"jobInstance\", jobInstance);\r\n        if (startDate != null) {\r\n            params.put(\"startDate\", startDate);\r\n            query += \" and hist.startDate >= :startDate\";\r\n        }\r\n        if (endDate != null) {\r\n            params.put(\"endDate\", endDate);\r\n            query += \" and hist.endDate < :endDate\";\r\n        }\r\n\r\n        Query q = jobInstanceService.getEntityManager().createQuery(query);\r\n        for (Map.Entry<String, Object> entry : params.entrySet()) {\r\n            q.setParameter(entry.getKey(), entry.getValue());\r\n        }\r\n        long result = (long) q.getSingleResult();\r\n        return result > 9 ? 0 : result;\r\n    }\r\n\r\n    private static String getEventLabel(String occCode) {\r\n        if(EventEnum.valueOf(occCode) != null) {\r\n            return EventEnum.valueOf(occCode).getLabel();\r\n        }\r\n        return \"\";\r\n    }\r\n\r\n    private String getZUONR(String occCode, String accountingCode) {\r\n        StringBuilder sb = new StringBuilder();\r\n        sb.append(accountingCode);\r\n        sb.append(PAD_STR);\r\n        log.info(\"ZUONR_accountingCode=>\"+accountingCode);\r\n        log.info(\"ZUONREnum.valueOf(occCode)=>\"+ZUONREnum.valueOf(occCode));\r\n        if(ZUONREnum.valueOf(occCode) != null) {\r\n            sb.append(ZUONREnum.valueOf(occCode).getLabel());\r\n        }\r\n\r\n        return sb.toString();\r\n    }\r\n    \r\n    private String getCostl(String invoiceCategoryCode) {\r\n    \tString costl = null;\r\n    \tString accountingCode=null;\r\n    \tInvoiceCategory invoiceCategory=invoiceCategoryService.findByCode(invoiceCategoryCode);\r\n    \tList<InvoiceSubCategory> invoiceSubCategories = invoiceSubCategoryService.findByInvoiceCategory(invoiceCategory);\r\n    \tfor(InvoiceSubCategory subCat:invoiceSubCategories) {\r\n    \t\taccountingCode=subCat.getAccountingCode().getCode();\r\n    \t\tif(accountingCode!=null) {\r\n    \t\t\t if (CAT_VENDING_CODE.equals(invoiceCategoryCode) && (ACCOUNT_1.equals(accountingCode) || ACCOUNT_2.equals(accountingCode))){\r\n    \t\t\t\tcostl=COSTL_VCA_IN;\r\n    \t\t\t}else if (CAT_VENDING_CODE_2.equals(invoiceCategoryCode) && (ACCOUNT_2.equals(accountingCode) || ACCOUNT_3.equals(accountingCode))){\r\n    \t\t\t\tcostl=COSTL_VCA_SE;\r\n    \t\t\t}else if (CAT_SERVICE_PROVISION_CODE.equals(invoiceCategoryCode)) { \r\n    \t\t\t\tif(SUB_CAT_DEE.equals(subCat.getCode()) && (ACCOUNT_1.equals(accountingCode) || ACCOUNT_2.equals(accountingCode))){\r\n    \t\t\t\t\tcostl=COSTL_VCA_DE;\r\n    \t\t\t\t}else if(ACCOUNT_1.equals(accountingCode) || ACCOUNT_2.equals(accountingCode)){\r\n    \t\t\t\t\tcostl=COSTL_VCA_MA;\r\n    \t\t\t\t} \t\r\n    \t\t\t}   \t    \r\n    \t\t}\r\n    \t}\r\n    \treturn costl;\r\n    }\r\n\r\n    private String getOperationType(AccountingEntry accountingWriting) {\r\n        String operationType = CREDIT;\r\n        if(accountingWriting.getAmount().compareTo(BigDecimal.ZERO) < 0) {\r\n            operationType = DEBIT;\r\n        }\r\n        return operationType;\r\n    }\r\n\r\n    private String getOperationTypeAvoir(AccountingEntry accountingWriting) {\r\n        String operationType = DEBIT;\r\n        if(accountingWriting.getAmount().compareTo(BigDecimal.ZERO) < 0) {\r\n            operationType = CREDIT;\r\n        }\r\n        return operationType;\r\n    }\r\n\r\n    private String getEventType(AccountingEntry accountingWriting) {\r\n        String eventType = EventEnum.FACTURATION.getLabel();\r\n        if(accountingWriting.getAmount().compareTo(BigDecimal.ZERO) < 0) {\r\n            eventType = EventEnum.ANNULATION_FACTURATION.getLabel();\r\n        }\r\n        return eventType;\r\n    }\r\n\r\n    private void appendLine(String line) {\r\n        if (!StringUtils.isBlank(line)) {\r\n            contentBuilder.append(line);\r\n            contentBuilder.append(NEW_LINE);\r\n        }\r\n    }\r\n\r\n    private void buildBGR00() {\r\n        contentBuilder.append(\"0\"); // STYPE\r\n        contentBuilder.append(FOLDER_ID).append(ORGA_CODE).append(OC_CODE);\r\n        contentBuilder.append(String.format(\"%03d\", LocalDate.now().getDayOfYear()));\r\n        contentBuilder.append(coutJobExecution); // GROUP _QUEUE_NAME\r\n        contentBuilder.append(MANDANT);\r\n        contentBuilder.append(rightPad(\"RAPEXPL\", 12, PAD_STR)); // USNAM\r\n        contentBuilder.append(rightPad(\"\", 8, PAD_STR)); // START\r\n        contentBuilder.append(\"X\"); // XKEEP\r\n        contentBuilder.append(SKIP_CHAR);// NODATA\r\n    }\r\n\r\n    private String buildBBKPF(Date bldat, Date budat, int index) {\r\n        StringBuilder stringBuilder = new StringBuilder();\r\n        stringBuilder.append(\"1\");// STYPE\r\n        stringBuilder.append(rightPad(\"FB01\", 20, PAD_STR));// TCODE\r\n        stringBuilder.append(DateUtils.formatDateWithPattern(bldat, \"ddMMyyyy\"));// BLDAT\r\n        stringBuilder.append(\"WY\");// BLART\r\n        stringBuilder.append(ORGA_CODE);// BUKRS\r\n        stringBuilder.append(DateUtils.formatDateWithPattern(budat, \"ddMMyyyy\"));// BUDAT\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 2, PAD_STR));// MONAT\r\n        stringBuilder.append(rightPad(\"EUR\", 5, PAD_STR));// WAERS\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 10, PAD_STR));// KURSF\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 10, PAD_STR));// BELNR\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 8, PAD_STR));// WWERT\r\n        stringBuilder.append(rightPad(PREFIX + DateUtils.formatDateWithPattern(new Date(), \"ddMMyyyy\") + index, 16, PAD_STR));// XBLNR\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 16, PAD_STR));// BVORG\r\n        stringBuilder.append(rightPad(ORGA_CODE + \"_\"+OC_CODE+\" \", 25, PAD_STR));// BVORG\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 4, PAD_STR));// PARGB\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 8, PAD_STR));// AUGLV\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 6, PAD_STR));// VBUND\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 1, PAD_STR));// XMWST\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 10, PAD_STR));// DOCID\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 40, PAD_STR));// BARCD\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 8, PAD_STR));// STODT\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 4, PAD_STR));// BRNCH\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 3, PAD_STR));// NUMPG\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 2, PAD_STR));// STGRD\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 10, PAD_STR));// KURSF_M\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 50, PAD_STR));// AUGTX\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 1, PAD_STR));// XPRFG\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 1, PAD_STR));// XBWAE\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 4, PAD_STR));// LDGRP\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 13, PAD_STR));// PROPMANO\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 8, PAD_STR));// VATDATE\r\n        stringBuilder.append(rightPad(SKIP_CHAR, 1, PAD_STR));// SENDE\r\n        return stringBuilder.toString();\r\n    }\r\n\r\n    private String buildBBSEG(String accountType, String eventLabel, String amount, Date valut, String zuonr, String codeTVA, String accountCode, String kostl) {\r\n        TreeMap<Integer, Zone> zonesBBSEG = new TreeMap<>();\r\n        List<Integer> zoneLenghtBGR00List = Arrays\r\n                .asList(new Integer[] { 1, 30, 2, 10, 1, 4, 16, 16, 16, 16, 2, 1, 16, 16, 4, 10, 4, 12, 10, 5, 16, 18, 4, 17, 3, 10, 6, 4, 8, 3, 8, 8, 2, 18, 3, 1, 50, 2, 16, 8, 2, 16,\r\n                        16, 4, 3, 6, 3, 6, 3, 1, 10, 4, 3, 1, 8, 1, 2, 16, 16, 11, 2, 27, 8, 2, 12, 4, 8, 3, 7, 16, 10, 1, 1, 5, 4, 10, 4, 4, 3, 3, 1, 8, 8, 8, 1, 18, 1, 35, 35, 35,\r\n                        35, 35, 35, 10, 3, 3, 15, 3, 18, 2, 16, 11, 8, 1, 3, 3, 20, 1, 1, 10, 10, 1, 1, 17, 3, 17, 10, 10, 13, 1, 4, 16, 16, 14, 6, 3, 2, 10, 12, 8, 8, 10, 12, 4, 1, 2,\r\n                        10, 24, 2, 15, 16, 10, 16, 16, 4, 12, 12, 10, 3, 8, 1, 1, 30, 30, 30, 30, 60, 60, 8, 3, 16, 16, 1, 1, 2, 1, 18, 2, 4, 4, 6, 5, 4, 4, 4, 10, 2, 6, 10, 4, 12, 3,\r\n                        1, 9, 10, 24, 12, 2, 4, 3, 4, 2, 4, 2, 2, 10, 10, 10, 2, 3, 9, 2, 2, 4, 3, 8, 10, 6, 4, 8, 1, 3, 24, 1, 2, 3, 2, 2, 2, 1, 18, 18, 20, 30, 2, 2, 2, 2, 2, 5, 16,\r\n                        4, 4, 6, 10, 8, 8, 8, 8, 13, 4, 5, 13, 10, 4, 10, 10, 10, 30, 30, 5, 15, 13, 13, 20, 1, 2, 20, 16, 1, 34, 8, 10, 10, 5, 1, 16, 8, 1, 10, 1, 1, 8, 10, 8 });\r\n\r\n        zonesBBSEG.put(1, new Zone(1, \"2\"));// STYPE\r\n        zonesBBSEG.put(2, new Zone(30, \"BBSEG\"));// TBNAM\r\n        zonesBBSEG.put(32, new Zone(2, accountType));// NEWBS : 40 si compte débit / 50 si compte crédit\r\n        zonesBBSEG.put(49, new Zone(16, amount));// WRBTR\r\n        zonesBBSEG.put(113, new Zone(2, StringUtils.isBlank(codeTVA) ? SKIP_CHAR : codeTVA));// MWSKZ\r\n        if (!StringUtils.isBlank(kostl)) {\r\n            zonesBBSEG.put(152, new Zone(10, kostl, \"\", true));// KOSTL\r\n        }\r\n        zonesBBSEG.put(282, new Zone(8, \"\"));// VALUT , previous value = DateUtils.formatDateWithPattern(valut, \"ddMMyyyy\"))\r\n        zonesBBSEG.put(300, new Zone(18, \"Opencell\")); // ZUONR , previous value = zuonr\r\n        zonesBBSEG.put(322, new Zone(50, eventLabel)); // ZUONR\r\n        zonesBBSEG.put(1059, new Zone(17, accountCode, \"0\", true)); // NEWKO\r\n\r\n        return generateRecordLine(zonesBBSEG, zoneLenghtBGR00List);\r\n    }\r\n\r\n    private String buildBBTAX(String accountType, String amount, String codeTVA) {\r\n        TreeMap<Integer, Zone> zonesBBTAX = new TreeMap<>();\r\n        List<Integer> zoneLenghtBBTAXList = Arrays.asList(new Integer[] { 1, 30, 16, 2, 2, 15, 16, 4, 16, 16, 16, 16, 16, 16, 10, 1 });\r\n\r\n        zonesBBTAX.put(1, new Zone(1, \"2\"));// STYPE\r\n        zonesBBTAX.put(2, new Zone(30, \"BBTAX\"));// TBNAM\r\n        zonesBBTAX.put(32, new Zone(16, amount));// FWSTE\r\n        zonesBBTAX.put(48, new Zone(2, StringUtils.isBlank(codeTVA) ? SKIP_CHAR : codeTVA));// MWSKZ\r\n        zonesBBTAX.put(50, new Zone(2, accountType));// BSCHL : 40 si compte débit / 50 si compte crédit\r\n\r\n        return generateRecordLine(zonesBBTAX, zoneLenghtBBTAXList);\r\n    }\r\n\r\n    private String generateRecordLine(TreeMap<Integer, Zone> zones, List<Integer> zoneLenghtList) {\r\n        int pos = 1;\r\n        int lg;\r\n        for (int i = 0; i < zoneLenghtList.size(); i++) {\r\n            lg = zoneLenghtList.get(i);\r\n            if (zones.get(pos) == null) {\r\n                zones.put(pos, new Zone(lg, SKIP_CHAR));\r\n            }\r\n            pos += lg;\r\n        }\r\n        StringBuilder sb = new StringBuilder();\r\n        zones.forEach((p, zone) -> {\r\n            if (zone.value.length() >= zone.lg) {\r\n                sb.append(zone.value.substring(0, zone.lg));\r\n            } else {\r\n                if (zone.leftPad) {\r\n                    sb.append(leftPad(zone.value, zone.lg, zone.padStr));\r\n                } else {\r\n                    sb.append(rightPad(zone.value, zone.lg, zone.padStr));\r\n                }\r\n            }\r\n        });\r\n        return sb.toString();\r\n    }\r\n\r\n    private String round(BigDecimal amount, Integer scale) {\r\n        if (amount == null) {\r\n            amount = BigDecimal.ZERO;\r\n        }\r\n        if (scale == null) {\r\n            scale = 2;\r\n        }\r\n        amount = amount.setScale(scale, RoundingMode.HALF_UP);\r\n        return decimalFormat.format(amount);\r\n    }\r\n\r\n    private String getSafeAccountingCode(AccountingCode ac) {\r\n        if (ac != null) {\r\n            return ac.getCode();\r\n        }\r\n        return \"\";\r\n    }\r\n\r\n    private Invoice findByInvoiceNumber(String invoiceNumber){\r\n        try {\r\n            \r\n            QueryBuilder qb = new QueryBuilder(Invoice.class, \"i\");\r\n            qb.addCriterion(\"invoiceNumber\", \"=\", invoiceNumber, false);\r\n\r\n            return (Invoice) qb.getQuery(invoiceService.getEntityManager()).getSingleResult();\r\n        } catch (NoResultException ne) {\r\n            return null;\r\n        }\r\n\r\n    }\r\n\r\n    private Tax findTaxByCode(String code){\r\n        try {\r\n           \r\n            QueryBuilder qb = new QueryBuilder(Tax.class, \"t\");\r\n            qb.addCriterion(\"code\", \"=\", code, false);\r\n\r\n            return (Tax) qb.getQuery(invoiceService.getEntityManager()).getSingleResult();\r\n        } catch (NoResultException ne) {\r\n            return null;\r\n        }\r\n\r\n    }\r\n\r\n}]]>\r\n            </script>\r\n</ScriptInstance>"
								},
								"url": {
									"raw": "{{opencell.url}}/scriptInstance/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"scriptInstance",
										"createOrUpdate"
									]
								}
							},
							"response": []
						}
					]
				},
				{
					"name": "payment",
					"item": [
						{
							"name": "MercanetIntegrationScript",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/xml"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "<ScriptInstance code=\"com.opencellsoft.service.ekko.payment.MercanetIntegrationScript\" description=\"Ekko Mercanet Integration Script\">\r\n            <type>JAVA</type>\r\n            <script>\r\n            <![CDATA[package com.opencellsoft.service.ekko.payment;\r\n\r\nimport java.io.BufferedReader;\r\nimport java.io.File;\r\nimport java.io.FileInputStream;\r\nimport java.io.FileNotFoundException;\r\nimport java.io.IOException;\r\nimport java.io.InputStream;\r\nimport java.io.InputStreamReader;\r\nimport java.math.BigDecimal;\r\nimport java.nio.charset.StandardCharsets;\r\nimport java.nio.file.Files;\r\nimport java.nio.file.Path;\r\nimport java.nio.file.Paths;\r\nimport java.time.LocalDate;\r\nimport java.time.ZoneId;\r\nimport java.util.ArrayList;\r\nimport java.util.Date;\r\nimport java.util.HashMap;\r\nimport java.util.List;\r\nimport java.util.Map;\r\nimport java.util.stream.Collectors;\r\nimport java.util.stream.Stream;\r\n\r\nimport javax.persistence.NoResultException;\r\n\r\nimport org.meveo.admin.exception.BusinessException;\r\nimport org.meveo.admin.exception.NoAllOperationUnmatchedException;\r\nimport org.meveo.admin.exception.UnbalanceAmountException;\r\nimport org.meveo.commons.utils.ParamBean;\r\nimport org.meveo.commons.utils.ParamBeanFactory;\r\nimport org.meveo.commons.utils.QueryBuilder;\r\nimport org.meveo.commons.utils.StringUtils;\r\nimport org.meveo.model.MatchingReturnObject;\r\nimport org.meveo.model.crm.Provider;\r\nimport org.meveo.model.payments.CustomerAccount;\r\nimport org.meveo.model.payments.MatchingStatusEnum;\r\nimport org.meveo.model.payments.MatchingTypeEnum;\r\nimport org.meveo.model.payments.OCCTemplate;\r\nimport org.meveo.model.payments.Payment;\r\nimport org.meveo.model.payments.PaymentMethodEnum;\r\nimport org.meveo.model.payments.RecordedInvoice;\r\nimport org.meveo.model.shared.DateUtils;\r\nimport org.meveo.service.admin.impl.SellerService;\r\nimport org.meveo.service.crm.impl.ProviderService;\r\nimport org.meveo.service.payments.impl.MatchingCodeService;\r\nimport org.meveo.service.payments.impl.OCCTemplateService;\r\nimport org.meveo.service.payments.impl.PaymentService;\r\nimport org.meveo.service.payments.impl.RecordedInvoiceService;\r\nimport org.meveo.service.script.Script;\r\n\r\nimport com.google.common.collect.Maps;\r\n/**\r\n/**\r\n * @author myPower team , from dump PP 19/05/2021\r\n * \r\n * @author anasseh update for OC 11 and EKKO\r\n *\r\n */\r\npublic class MercanetIntegrationScript extends Script {\r\n\t\r\n\tprivate static final String SELLER_CODE = \"EKKO\";\r\n    private static final String DATETIME_FORMAT = \"dd_MM_yyyy-HHmm\";\r\n    private static final String MERCANET_INPUT_DIR = \"MERCANET_INPUT_DIR\";\r\n    private static final String MERCANET_FILE_EXT = \"MERCANET_FILE_EXT\";\r\n    private static final String MERCANET_DELIMITER = \"MERCANET_DELIMITER\";\r\n    private static final String MERCANET_ARCH_DIR = \"MERCANET_ARCH_DIR\";\r\n    private static final String MERCANET_ERR_DIR = \"MERCANET_ERR_DIR\";\r\n    private static final String MERCANET_WARN_DIR = \"MERCANET_WARN_DIR\";\r\n    private static final String MERCANET_REPORT_DIR = \"MERCANET_REPORT_DIR\";\r\n    private RecordedInvoiceService recordedInvoiceService = (RecordedInvoiceService) getServiceInterface(\"RecordedInvoiceService\");\r\n    private PaymentService paymentService = (PaymentService) getServiceInterface(\"PaymentService\");\r\n    private ParamBeanFactory paramBeanFactory = (ParamBeanFactory) getServiceInterface(\"ParamBeanFactory\");\r\n    private OCCTemplateService oCCTemplateService = (OCCTemplateService) getServiceInterface(\"OCCTemplateService\");\r\n    private MatchingCodeService matchingCodeService = (MatchingCodeService) getServiceInterface(\"MatchingCodeService\");\r\n    private Provider appProvider = ((ProviderService) getServiceInterface(\"ProviderService\")).getProvider();\r\n    private SellerService sellerService = (SellerService) getServiceInterface(\"SellerService\");\r\n\r\n    private String delimiter;\r\n    private OCCTemplate occCardTemplate;\r\n    private Map<String, Integer> processedItemsIndexes;\r\n    private List<String> reportMessages = new ArrayList<>();\r\n    private RecordedInvoice recordedInvoice = null;\r\n    /**\r\n     * script main execute method\r\n     * @param methodContext method context params\r\n     * @throws BusinessException business exception\r\n     */\r\n    @Override\r\n    public void execute(Map<String, Object> methodContext) throws BusinessException {\r\n        log.info(\"Execute methodContext:{}\",methodContext);\r\n        long startTime = System.currentTimeMillis();\r\n        String mercanetDir = (String) methodContext.get(MERCANET_INPUT_DIR);\r\n        String archiveDir = (String) methodContext.get(MERCANET_ARCH_DIR);\r\n        String errorDir = (String) methodContext.get(MERCANET_ERR_DIR);\r\n        String warnDir = (String) methodContext.get(MERCANET_WARN_DIR);\r\n        String reportDir = (String) methodContext.get(MERCANET_REPORT_DIR);\r\n        String mercanetFileExt = (String) methodContext.get(MERCANET_FILE_EXT);\r\n        String mercanetDelimiter = (String) methodContext.get(MERCANET_DELIMITER);\r\n        log.debug(\"MERCANET_INPUT_DIR={}\", mercanetDir);\r\n        log.debug(\"MERCANET_FILE_EXT={}\", mercanetFileExt);\r\n        log.debug(\"MERCANET_DELIMITER={}\", mercanetDelimiter);\r\n        log.debug(\"MERCANET_ARCH_DIR={}\", archiveDir);\r\n        log.debug(\"MERCANET_WARN_DIR={}\", warnDir);\r\n        log.debug(\"MERCANET_ERR_DIR={}\", errorDir);\r\n        log.debug(\"MERCANET_REPORT_DIR={}\", reportDir);\r\n        if (StringUtils.isBlank(mercanetDir)) {\r\n            throw new BusinessException(\"The variable input \" + MERCANET_INPUT_DIR + \" is mandatory\");\r\n        }\r\n        String rootDir = ParamBean.getInstance().getChrootDir(appProvider.getCode());\r\n        Path archiveDirPath = Paths.get(rootDir + File.separator + (!StringUtils.isBlank(archiveDir) ? archiveDir : \"mercanet_archive\"));\r\n        Path errorDirPath =  Paths.get(rootDir + File.separator + (!StringUtils.isBlank(errorDir) ? errorDir : \"mercanet_errors\"));\r\n        Path warnDirPath =  Paths.get(rootDir + File.separator + (!StringUtils.isBlank(warnDir) ? warnDir : \"mercanet_warns\"));\r\n        Path reportDirPath =  Paths.get(rootDir + File.separator + (!StringUtils.isBlank(reportDir) ? reportDir : \"mercanet_reports\"));\r\n        mercanetFileExt = !StringUtils.isBlank(mercanetFileExt) ? \".\" + mercanetFileExt : \".csv\";\r\n        this.delimiter = !StringUtils.isBlank(mercanetDelimiter) ? mercanetDelimiter : \"\\t\";\r\n        Path inputDir = Paths.get(rootDir + File.separator + mercanetDir);\r\n        List<Path> mercanetFiles = getMercanetLogFiles(inputDir, mercanetFileExt);\r\n        log.info(\"mercanetFiles\"+mercanetFiles);\r\n        if (mercanetFiles == null || mercanetFiles.isEmpty()) {\r\n            log.warn(\"No mercanet files are found in the input Dir. will exit!\");\r\n            methodContext.put(Script.JOB_RESULT_NB_OK, 0);\r\n            return;\r\n        }\r\n        log.debug(\"{} mercanet files found. start import them...\", mercanetFiles.size());\r\n        if (!createDirIfNotExist(archiveDirPath)) {\r\n            throw new BusinessException(\"Archive dir doesn't exist and could not be created\");\r\n        }\r\n        if (!createDirIfNotExist(errorDirPath)) {\r\n            throw new BusinessException(\"Error dir doesn't exist and could not be created\");\r\n        }\r\n        StringBuilder sbFiles = new StringBuilder(\"Processed \" + mercanetFiles.size() + \" mercanet files :\\n\");\r\n        mercanetFiles.forEach(file -> {\r\n            sbFiles.append(file.getFileName() + \"\\n\");\r\n        });\r\n        //OCC template for card and refund\r\n        ParamBean paramBean = paramBeanFactory.getInstance();\r\n        String occCardTemplateCode = paramBean.getProperty(\"occ.payment.card\", \"PAY_CRD\");\r\n        this.occCardTemplate = getOCCTemplate(occCardTemplateCode);\r\n        //counters for all import\r\n        ProcessingReport allReport = new ProcessingReport();\r\n        processedItemsIndexes = new HashMap<>();\r\n        for (Path mercanetFile : mercanetFiles) {\r\n            String fileName = mercanetFile.getFileName().toString();\r\n            //addReportMessage(\"Start processing file \" +fileName+ \"...\", null);\r\n            InputStream inputStream = null;\r\n            try {\r\n                inputStream = new FileInputStream(mercanetFile.toFile());\r\n            } catch (FileNotFoundException e) {\r\n                log.error(\"Error reading mercanet file \", mercanetFile.toString(), e);\r\n                addReportMessage(\"Error reading file: \" + e.getMessage(), fileName);\r\n                allReport.opKo++;\r\n                continue;\r\n            }\r\n            try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {\r\n                // skip the headers of the csv\r\n                bufferedReader.readLine();\r\n                bufferedReader.readLine();\r\n                //counters per file\r\n                ProcessingReport fileReport = new ProcessingReport();\r\n                //Read operations lines\r\n                String line;\r\n                int index = 2;\r\n                while ((line = bufferedReader.readLine()) != null && !line.equals(\"FOOTER\")) {\r\n                    index++;\r\n                    MercanetItem item = mapToItem(line, index);\r\n                    item.fileName = fileName;\r\n                    // #203 : Uniqueness of payment based on reference and MerchantId\r\n                    if (findPaymentByReferenceAndPaymentOrder(item.transactionReference, item.merchantId) != null) {\r\n                        log.error(\"Payment already created for mercanet operation at line n={}, fileName={}\", item.numLine, item.fileName);\r\n                        addReportMessage(\"Payment already created for line n=\" + item.numLine, item.fileName);\r\n                        fileReport.opKo++;\r\n                        continue;\r\n                    }\r\n                    if (processedItemsIndexes.get(item.getIdentifier()) != null) {\r\n                        Integer duplicateIndex = processedItemsIndexes.get(item.getIdentifier());\r\n                        log.debug(\"Warning! Line \" + index + \" is a duplicate of line number \" + processedItemsIndexes.get(item.getIdentifier()) + \". Filename=\" + fileName);\r\n                        addReportMessage(\"Warning! Line=\" + index + \", message=Line is escaped because it's a duplicate of line number \" + duplicateIndex, fileName);\r\n                        continue;\r\n                    }\r\n                    if (item.operationType.equals(\"CREDIT\") || item.operationType.equals(\"DEBIT\")) {\r\n                        try {\r\n                            Payment payment = createPayment(item, fileReport);\r\n                            if (payment != null && recordedInvoice != null) {\r\n                                // matching the created payment\r\n                                matchOperation(item.orderId, payment, recordedInvoice,fileName, index, fileReport);\r\n                            }\r\n                        } catch (Exception e) {\r\n                            log.error(\"Error processing line {}, file {}\", index, fileName, e);\r\n                            addReportMessage(\"Error processing line=\" + index + \", message=\" + e.getMessage() + \"\", fileName);\r\n                            fileReport.opKo++;\r\n                        }\r\n                    } /*else if (item.operationType.equals(\"DEBIT\")) {\r\n                        log.debug(\"Warning! Line \" + index + \" escaped because operation type is DEBIT. Filename=\" + fileName);\r\n                        addReportMessage(\"Warning on Line=\" + index + \", message=Line escaped because operation type is DEBIT.\", fileName);\r\n                    } */else {\r\n                        log.debug(\"Error on line=\" + index + \", operationType \\\"\" + item.operationType + \"\\\" not recognized. Filename=\" + fileName);\r\n                        addReportMessage(\"Error processing line=\" + index + \", message= Operation type \\\"\" + item.operationType + \"\\\" not recognized.\", fileName);\r\n                        fileReport.opKo++;\r\n                    }\r\n                    processedItemsIndexes.put(item.getIdentifier(), index);\r\n                }\r\n                // close mercanet file\r\n                bufferedReader.close();\r\n                inputStream.close();\r\n                // report for one file\r\n                fileReport.opAll = index - 2;\r\n                if (fileReport.opKo > 0) {\r\n                    moveToErrorDirectory(errorDirPath, mercanetFile);\r\n                } else if (fileReport.matchKo > 0) {\r\n                    moveToWarnDirectory(warnDirPath, mercanetFile);\r\n                } else {\r\n                    archivateMercanetFile(archiveDirPath, mercanetFile);\r\n                }\r\n                allReport.opAll += fileReport.opAll;\r\n                allReport.opOk += fileReport.opOk;\r\n                allReport.opKo += fileReport.opKo;\r\n                allReport.matchOk += fileReport.matchOk;\r\n                allReport.matchKo += fileReport.matchKo;\r\n            } catch (Exception e) {\r\n                log.error(\"Error processing mercanet file {}\", fileName, e);\r\n                addReportMessage(\"Error processing mercanet file [ message=\"+e.getMessage()+\" ]\", fileName);\r\n                allReport.opKo = 1;\r\n                moveToErrorDirectory(errorDirPath, mercanetFile);\r\n            }\r\n        }\r\n        methodContext.put(Script.JOB_RESULT_NB_OK, allReport.opOk);\r\n        methodContext.put(Script.JOB_RESULT_NB_WARN, allReport.matchKo);\r\n        methodContext.put(Script.JOB_RESULT_NB_KO, allReport.opKo);\r\n        methodContext.put(Script.JOB_RESULT_REPORT, reportMessages);\r\n        addReportMessage(sbFiles.toString(), null);\r\n        long processDuration = (System.currentTimeMillis() - startTime) / 1000;\r\n        addReportMessage(\"Files are processed in \" + processDuration + \" seconds.\", null);\r\n        addReportMessage(\"Import report : Total=\"+ allReport.opAll + \". \"\r\n                + \"AO creation: Ok=\" + allReport.opOk + \", KO=\" + allReport.opKo + \". \"\r\n                + \"AO matching: OK=\" + allReport.matchOk + \", KO=\" + allReport.matchKo, null);\r\n        //create import report file in input dir\r\n        Path reportFile = Paths.get(reportDirPath.toString() + File.separator + \"report_\" + DateUtils.formatDateWithPattern(new Date(), DATETIME_FORMAT));\r\n        try {\r\n            Files.createFile(reportFile);\r\n            log.debug(\"creating mercanet import report file at {}\", reportFile);\r\n            Files.write(reportFile, reportMessages, StandardCharsets.UTF_8);\r\n        } catch (IOException e) {\r\n            log.error(\"Could not create or write to mercanet import report file at {}\", reportFile, e);\r\n        }\r\n    }\r\n    /**\r\n     * Create a payment from mercanet log item\r\n     * @param item mercanet item\r\n     * @param report processing report\r\n     * @return OC payment entity\r\n     */\r\n    private Payment createPayment(MercanetItem item, ProcessingReport report) {\r\n        Payment payment = new Payment();\r\n        setAOProperties(payment, item);\r\n        if(payment.getCustomerAccount() != null) {\r\n            try {\r\n                payment.setPaymentOrder(item.merchantId);\r\n                payment.setFees(item.feeAmount);\r\n                paymentService.create(payment);\r\n                report.opOk++;\r\n                return payment;\r\n            } catch (BusinessException e) {\r\n                log.error(\"Couldn't create Payement entity for mercanet operation at line n={}, error={}\", item.numLine, e);\r\n                addReportMessage(\"Couldn't create payment for line n=\"+item.numLine+\". error=\"+e.getMessage() , item.fileName);\r\n                report.opKo++;\r\n                return null;\r\n            }\r\n        } else {\r\n            log.error(\"Couldn't create Payement entity for mercanet operation at line n={} : orderId={} not found\", item.numLine, item.orderId);\r\n            addReportMessage(\"Couldn't create payment for line n=\"+item.numLine+\". orderId=\"+item.orderId+\" not found\" , item.fileName);\r\n            report.opKo++;\r\n            return null;\r\n        }\r\n    }\r\n    /**\r\n     * move mercanet file containing errors to error directory\r\n     * @param errorDirPath error dir pth\r\n     * @param mercanetFile mercanet file\r\n     */\r\n    private void moveToErrorDirectory(Path errorDirPath, Path mercanetFile) {\r\n        log.debug(\"moving mercanet file {} to error dir.\", mercanetFile);\r\n        try {\r\n            Files.move(mercanetFile, Paths.get(errorDirPath + File.separator + mercanetFile.getFileName() + \".\" + DateUtils.formatDateWithPattern(new Date(), DATETIME_FORMAT)));\r\n        } catch (IOException e) {\r\n            log.error(\"Couldn't move mercanet file {} to errors dir {}\", mercanetFile.toString(), errorDirPath, e);\r\n            addReportMessage(\"Couldn't move mercanet file to errors dir: \" + e.getMessage(), null);\r\n        }\r\n    }\r\n    /**\r\n     * move mercanet file containing errors to error directory\r\n     * @param mercanetFile mercanet file\r\n     */\r\n    private void moveToWarnDirectory(Path warnDirPath, Path mercanetFile) {\r\n        log.debug(\"moving mercanet file {} to warn dir.\", mercanetFile);\r\n        try {\r\n            Files.move(mercanetFile, Paths.get(warnDirPath + File.separator + mercanetFile.getFileName() + \".\" + DateUtils.formatDateWithPattern(new Date(), DATETIME_FORMAT)));\r\n        } catch (IOException e) {\r\n            log.error(\"Couldn't move mercanet file {} to warns dir {}\", mercanetFile.toString(), warnDirPath, e);\r\n            addReportMessage(\"Couldn't move mercanet file to warns dir: \" + e.getMessage(), null);\r\n        }\r\n    }\r\n    /**\r\n     * archivate imported mercanet file\r\n     * @param archiveDirPath archive directory path\r\n     * @param mercanetFile mercanet file to archive\r\n     */\r\n    private void archivateMercanetFile(Path archiveDirPath, Path mercanetFile) {\r\n        String strArchiFilePath = archiveDirPath + File.separator + mercanetFile.getFileName() + \".\" + DateUtils.formatDateWithPattern(new Date(), DATETIME_FORMAT);\r\n        Path archFile = Paths.get(strArchiFilePath);\r\n        try {\r\n            Files.move(mercanetFile, archFile);\r\n        } catch (IOException e) {\r\n            log.error(\"Couldn't arcivate mercanet file {} to {}\", mercanetFile.toString(), archFile.toString(), e);\r\n            addReportMessage(\"Couldn't move mercanet file to errors dir: \" + e.getMessage(), null);\r\n        }\r\n    }\r\n    /**\r\n     *\r\n     * @param reportMessage report message\r\n     * @param fileName current processing mercanet file name\r\n     */\r\n    private void addReportMessage(String reportMessage, String fileName) {\r\n        if (fileName != null) {\r\n            reportMessages.add(fileName + \" >> \" + reportMessage);\r\n        } else {\r\n            reportMessages.add(reportMessage);\r\n        }\r\n    }\r\n    /**\r\n     * create directory if not exists\r\n     * @param dirPath directory path\r\n     * @return true if created else false\r\n     */\r\n    private boolean createDirIfNotExist(Path dirPath) {\r\n        if (!dirPath.toFile().exists()) {\r\n            try {\r\n                Files.createDirectories(dirPath);\r\n                log.debug(\"dir {} didn't exist and is created successfully.\", dirPath);\r\n            } catch (IOException e) {\r\n                log.error(\"Error creating directory {}\", dirPath, e);\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n    /**\r\n     *\r\n     * @param inputDir mercanet input dierctory\r\n     * @param ext mercanet file extention\r\n     * @return list of mercanet files found into input directory\r\n     * @throws BusinessException business exception\r\n     */\r\n    private List<Path> getMercanetLogFiles(Path inputDir, String ext) throws BusinessException {\r\n        if (!inputDir.toFile().exists() || !inputDir.toFile().isDirectory()) {\r\n            log.error(\"Mercanet input path {} is not a valid directory!\", inputDir);\r\n            throw new BusinessException(\"Param inputDir is not a valid directory\");\r\n        }\r\n        try (Stream<Path> filesStream = Files.list(inputDir)) {\r\n            if (filesStream != null) {\r\n                return filesStream.filter(s -> s.toString().contains(\"rapban\")).map(Path::toAbsolutePath).collect(Collectors.toList());\r\n            } else {\r\n                return null;\r\n            }\r\n        } catch (IOException e) {\r\n            log.error(\"Error on getting list Mercanet log files!\", e);\r\n            throw new BusinessException(e);\r\n        }\r\n    }\r\n    /**\r\n     * set AO properties from mercanet item and OCC template\r\n     * @param payment account operation\r\n     * @param item mercanet log item\r\n     */\r\n    private void setAOProperties(Payment  payment, MercanetItem item) {\r\n        if(!StringUtils.isBlank(item.orderId)) {\r\n            recordedInvoice = getRecordedInvoice(item.orderId);\r\n            if(recordedInvoice != null) {\r\n                payment.setCustomerAccount(recordedInvoice.getCustomerAccount());\r\n\r\n            }else{\r\n\r\n\r\n                CustomerAccount ca =findCustomerAccountByOrderNumber(item.orderId);\r\n                if(ca != null)\r\n                    payment.setCustomerAccount(ca);\r\n            }\r\n\r\n        }\r\n        payment.setPaymentMethod(PaymentMethodEnum.CARD);\r\n\r\n        payment.setAmount(item.originAmount);\r\n        payment.setMatchingAmount(BigDecimal.ZERO);\r\n        payment.setUnMatchingAmount(item.originAmount);\r\n        payment.setAccountingCode(occCardTemplate.getAccountingCode());\r\n        payment.setCode(occCardTemplate.getCode());\r\n        payment.setDescription(occCardTemplate.getDescription());\r\n        payment.setTransactionCategory(occCardTemplate.getOccCategory());\r\n        payment.setAccountCodeClientSide(occCardTemplate.getAccountCodeClientSide());\r\n        payment.setReference(item.transactionReference);\r\n        // tansaction date + 1 jour\r\n        if (item.transactionDateTime != null) {\r\n            LocalDate trDatePlus1Day = item.transactionDateTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate().plusDays(1);\r\n            payment.setTransactionDate(Date.from(trDatePlus1Day.atStartOfDay(ZoneId.systemDefault()).toInstant()));\r\n        }\r\n        payment.setDueDate(new Date());\r\n        payment.setMatchingStatus(MatchingStatusEnum.O);\r\n        payment.setSeller(sellerService.findByCode(SELLER_CODE));\r\n    }\r\n    /**\r\n     * get OCC template by code\r\n     * @param occTemplateCode occ template code\r\n     * @return OCC Template\r\n     * @throws BusinessException Business Exception\r\n     */\r\n    private OCCTemplate getOCCTemplate(String occTemplateCode) throws BusinessException {\r\n        OCCTemplate occTemplate = oCCTemplateService.findByCode(occTemplateCode);\r\n        if (occTemplate == null) {\r\n            throw new BusinessException(\"Cannot find OCC Template with code=\" + occTemplateCode);\r\n        }\r\n        return occTemplate;\r\n    }\r\n    /**\r\n     * get recorded invoice by order number\r\n     * @param orderNumber order number\r\n     * @return recorded invoice\r\n     */\r\n    private RecordedInvoice getRecordedInvoice(String orderNumber) {\r\n        Map<String, Object> params = Maps.newHashMap();\r\n        String query = \"From RecordedInvoice ri where (ri.subscription.code=:orderNumber or ri.reference=:orderNumber) and ri.matchingStatus ='O'\";\r\n        params.put(\"orderNumber\", orderNumber);\r\n        List<RecordedInvoice> recordedInvoices = (List<RecordedInvoice>) recordedInvoiceService.executeSelectQuery(query, params);\r\n        if (recordedInvoices.isEmpty()) {\r\n            return null;\r\n        }\r\n        return recordedInvoices.iterator().next();\r\n    }\r\n\r\n    private CustomerAccount findCustomerAccountByOrderNumber(String ordNumber) {\r\n        try {\r\n            \r\n            QueryBuilder qb = new QueryBuilder(CustomerAccount.class, \"\");\r\n            qb.addSql(\"cfValues like'%\" + ordNumber.toLowerCase() + \"%'\");\r\n            return (CustomerAccount) qb.getQuery(paymentService.getEntityManager()).getSingleResult();\r\n        } catch (NoResultException ne) {\r\n            return null;\r\n        }\r\n    }\r\n\r\n\r\n    /**\r\n     * Match the open\r\n     * @param payment operationToMatch\r\n     * @param fileName mercanet file name currently processed\r\n     * @param numLine line index\r\n     * @param report processing report\r\n     */\r\n    private void matchOperation(String orderNumber, Payment payment, RecordedInvoice recordedInvoice,  String fileName, Integer numLine, ProcessingReport report) {\r\n              \r\n        List<Long> operationIds = new ArrayList<Long>();\r\n        operationIds.add(payment.getId());\r\n        operationIds.add(recordedInvoice.getId());\r\n        \r\n        MatchingReturnObject matchingReturn = null;\r\n        try {\r\n            matchingReturn = matchingCodeService.matchOperations(payment.getCustomerAccount().getId(),\r\n                    null, operationIds, null, MatchingTypeEnum.A);\r\n        } catch (BusinessException | NoAllOperationUnmatchedException | UnbalanceAmountException e) {\r\n            log.warn(\"Problem on matching operation id={}, line n={}!\", payment.getId(), numLine, e);\r\n            addReportMessage(\"[WARN] Problem on matching operation on line=\"+numLine+\", opid=\"+payment.getId()+\", message=\"+e.getMessage(), fileName);\r\n            report.matchKo++;\r\n            return;\r\n        }\r\n        if (matchingReturn.isOk()) {\r\n            log.debug(\"Matching is OK for the operation id={}, line n={}!\", payment.getId(), numLine);\r\n            report.matchOk++;\r\n        } else {\r\n            log.warn(\"Matching is NOK for the operation id={}, line n°{}!\", payment.getId(), numLine);\r\n            addReportMessage(\"[WARN] Matching NOK for operation on line=\"+numLine+\", opid=\"+payment.getId(), fileName);\r\n            report.matchKo++;\r\n        }\r\n    }\r\n    /**\r\n     * map mercanet file line with MercanetItem item\r\n     * @param line mercanet operation line\r\n     * @param index line index\r\n     * @return MercanetItem item\r\n     */\r\n    private MercanetItem mapToItem (String line, int index) {\r\n        String[] lineFields = line.split(this.delimiter);\r\n        int lineLength = lineFields.length;\r\n        MercanetItem item = new MercanetItem();\r\n        item.numLine = index;\r\n        item.recordCode = lineLength > 0 ? lineFields[0] : null;\r\n        item.merchantId = lineLength > 1 ? lineFields[1] : null;\r\n        item.transactionReference = lineLength > 2 ? lineFields[2] : null;\r\n        item.operationSequence = lineLength > 3 ? lineFields[3] : null;\r\n        item.transactionDateTime = lineLength > 4 ? toDate(lineFields[4]) : null;\r\n        item.orderId = lineLength > 5 ? lineFields[5] : null;\r\n        item.orderChannel = lineLength > 6 ? lineFields[6] : null;\r\n        item.paymentMeanBrand = lineLength > 7 ? lineFields[7] : null;\r\n        item.paymentMeanType = lineLength > 8 ? lineFields[8] : null;\r\n        item.operationType = lineLength > 9 ? lineFields[9] : null;\r\n        item.remittanceDateTime = lineLength > 10 ? toDate(lineFields[10]) : null;\r\n        item.remittanceNumber = lineLength > 11 ? lineFields[11] : null;\r\n        item.paymentStatus = lineLength > 12 ? lineFields[12] : null;\r\n        item.currencyCode = lineLength > 13 ? lineFields[13] : null;\r\n        item.originAmount = lineLength > 14 ? toBigDecimal(lineFields[14]) : null;\r\n        item.grossAmount = lineLength > 15 ? toBigDecimal(lineFields[15]) : null;\r\n        item.netAmount = lineLength > 16 ? toBigDecimal(lineFields[16],4) : null;\r\n        item.feeCurrency = lineLength > 17 ? lineFields[17] : null;\r\n        item.feeAmount = lineLength > 18 ? toBigDecimal(lineFields[18],4) : null;\r\n        item.s10TransactionId = lineLength > 19 ? lineFields[19] : null;\r\n        item.s10TransactionIdDate = lineLength > 20 ? toDate(lineFields[20]) : null;\r\n        item.acquirerContractNumber = lineLength > 21 ? lineFields[21] : null;\r\n        item.authorisationId = lineLength > 22 ? lineFields[22] : null;\r\n        item.feeType = lineLength > 23 ? lineFields[23] : null;\r\n        item.fundTransferNumber = lineLength > 24 ? lineFields[24] : null;\r\n        item.settlementMode = lineLength > 25 ? lineFields[25] : null;\r\n        item.returnContext = lineLength > 26 ? lineFields[26] : null;\r\n        item.customerId = lineLength > 27 ? lineFields[27] : null;\r\n        item.interchangeFee = lineLength > 28 ? lineFields[28] : null;\r\n        item.cardInterchangeCategoryCode = lineLength > 29 ? lineFields[29] : null;\r\n        item.lastMerchantOperationDateTime = lineLength > 30 ? toDate(lineFields[30]) : null;\r\n        item.lastMerchantOperationName = lineLength > 31 ? lineFields[31] : null;\r\n        item.mandateId = lineLength > 32 ? lineFields[32] : null;\r\n        item.acquisitionType = lineLength > 33 ? lineFields[33] : null;\r\n        item.feesDebitNumber = lineLength > 34 ? lineFields[34] : null;\r\n        item.settlementArchivingReference = lineLength > 35 ? lineFields[35] : null;\r\n        return item;\r\n    }\r\n    /**\r\n     * To big decimal.\r\n     *\r\n     * @param input the input\r\n     * @param scale the scale\r\n     * @return the bigdecimal\r\n     */\r\n    private BigDecimal toBigDecimal(String input, int scale) {\r\n        return BigDecimal.valueOf(Long.valueOf(input), scale);\r\n    }\r\n    /**\r\n     * String to bigdecimal\r\n     * @param input string\r\n     * @return bigdecimal\r\n     */\r\n    private BigDecimal toBigDecimal(String input) {\r\n        return BigDecimal.valueOf(Long.valueOf(input), 2);\r\n    }\r\n    /**\r\n     * String to date\r\n     * @param input string\r\n     * @return date\r\n     */\r\n    private Date toDate(String input) {\r\n        return DateUtils.guessDate(input, \"yyyyMMdd hhmmss\", \"yyyy-MM-dd hh:mm:ss\");\r\n    }\r\n    /**\r\n     * Classe to map mercanet line\r\n     */\r\n    private class MercanetItem {\r\n        String fileName;\r\n        int numLine;\r\n        String recordCode;\r\n        String merchantId;\r\n        String transactionReference;\r\n        String operationSequence;\r\n        Date transactionDateTime;\r\n        String orderId;\r\n        String orderChannel;\r\n        String paymentMeanBrand;\r\n        String paymentMeanType;\r\n        String operationType;\r\n        Date remittanceDateTime;\r\n        String remittanceNumber;\r\n        String paymentStatus;\r\n        String currencyCode;\r\n        BigDecimal originAmount;\r\n        BigDecimal grossAmount;\r\n        BigDecimal netAmount;\r\n        String feeCurrency;\r\n        BigDecimal feeAmount;\r\n        String s10TransactionId;\r\n        Date s10TransactionIdDate;\r\n        String acquirerContractNumber;\r\n        String authorisationId;\r\n        String feeType;\r\n        String fundTransferNumber;\r\n        String settlementMode;\r\n        String returnContext;\r\n        String customerId;\r\n        String interchangeFee;\r\n        String cardInterchangeCategoryCode;\r\n        Date lastMerchantOperationDateTime;\r\n        String lastMerchantOperationName;\r\n        String mandateId;\r\n        String acquisitionType;\r\n        String feesDebitNumber;\r\n        String settlementArchivingReference;\r\n        String getIdentifier(){\r\n            return fileName + \"_\" + transactionReference;\r\n        }\r\n    }\r\n    private class ProcessingReport{\r\n        int opAll = 0;\r\n        int opOk = 0;\r\n        int opKo = 0;\r\n        int matchOk = 0;\r\n        int matchKo = 0;\r\n    }\r\n\r\n\r\n    /**\r\n     * Find payment by reference and payment order.\r\n     *\r\n     * @param reference the reference\r\n     * @param paymentOrder the payment order\r\n     * @return the payment\r\n     */\r\n    public Payment findPaymentByReferenceAndPaymentOrder(String reference, String paymentOrder) {\r\n        try {\r\n            \r\n            QueryBuilder qb = new QueryBuilder(Payment.class, \"p\");\r\n            qb.addCriterion(\"reference\", \"=\", reference, false);\r\n            qb.addCriterion(\"paymentOrder\", \"=\", paymentOrder, false);\r\n            qb.addCriterion(\"seller.code\", \"=\", SELLER_CODE, false);\r\n            \r\n            return (Payment) qb.getQuery(paymentService.getEntityManager()).getSingleResult();\r\n        } catch (NoResultException ne) {\r\n            return null;\r\n        }\r\n    }\r\n}\r\n\r\n]]>\r\n            </script>\r\n</ScriptInstance>"
								},
								"url": {
									"raw": "{{opencell.url}}/scriptInstance/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"scriptInstance",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "Create SepaDDRequestBuilderScript",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/xml"
									},
									{
										"key": "Proxy-Authorization",
										"type": "text",
										"value": "{{proxy.auth}}"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "<ScriptInstance code=\"com.opencellsoft.service.ekko.payment.SepaDDRequestBuilderScript\" description=\"Ekko Sepa Pain08 et camt54 Script\">\r\n            <type>JAVA</type>\r\n            <script>\r\n            <![CDATA[package com.opencellsoft.service.ekko.payment;\r\n\r\nimport java.io.File;\r\nimport java.math.BigDecimal;\r\nimport java.math.RoundingMode;\r\nimport java.util.ArrayList;\r\nimport java.util.Arrays;\r\nimport java.util.Date;\r\nimport java.util.HashMap;\r\nimport java.util.List;\r\nimport java.util.Map;\r\nimport java.util.stream.Collectors;\r\n\r\nimport org.meveo.admin.exception.BusinessException;\r\nimport org.meveo.admin.sepa.DDRejectFileInfos;\r\nimport org.meveo.admin.sepa.jaxb.camt054.AccountNotification2;\r\nimport org.meveo.admin.sepa.jaxb.camt054.BankToCustomerDebitCreditNotificationV02;\r\nimport org.meveo.admin.sepa.jaxb.pain008.AccountIdentification4Choice;\r\nimport org.meveo.admin.sepa.jaxb.pain008.ActiveOrHistoricCurrencyAndAmount;\r\nimport org.meveo.admin.sepa.jaxb.pain008.BranchAndFinancialInstitutionIdentification4;\r\nimport org.meveo.admin.sepa.jaxb.pain008.CashAccount16;\r\nimport org.meveo.admin.sepa.jaxb.pain008.CustomerDirectDebitInitiationV02;\r\nimport org.meveo.admin.sepa.jaxb.pain008.DirectDebitTransaction6;\r\nimport org.meveo.admin.sepa.jaxb.pain008.DirectDebitTransactionInformation9;\r\nimport org.meveo.admin.sepa.jaxb.pain008.Document;\r\nimport org.meveo.admin.sepa.jaxb.pain008.FinancialInstitutionIdentification7;\r\nimport org.meveo.admin.sepa.jaxb.pain008.GenericFinancialIdentification1;\r\nimport org.meveo.admin.sepa.jaxb.pain008.GenericPersonIdentification1;\r\nimport org.meveo.admin.sepa.jaxb.pain008.GroupHeader39;\r\nimport org.meveo.admin.sepa.jaxb.pain008.LocalInstrument2Choice;\r\nimport org.meveo.admin.sepa.jaxb.pain008.MandateRelatedInformation6;\r\nimport org.meveo.admin.sepa.jaxb.pain008.Party6Choice;\r\nimport org.meveo.admin.sepa.jaxb.pain008.PartyIdentification32;\r\nimport org.meveo.admin.sepa.jaxb.pain008.PaymentIdentification1;\r\nimport org.meveo.admin.sepa.jaxb.pain008.PaymentInstructionInformation4;\r\nimport org.meveo.admin.sepa.jaxb.pain008.PaymentMethod2Code;\r\nimport org.meveo.admin.sepa.jaxb.pain008.PaymentTypeInformation20;\r\nimport org.meveo.admin.sepa.jaxb.pain008.PersonIdentification5;\r\nimport org.meveo.admin.sepa.jaxb.pain008.PersonIdentificationSchemeName1Choice;\r\nimport org.meveo.admin.sepa.jaxb.pain008.SequenceType1Code;\r\nimport org.meveo.admin.sepa.jaxb.pain008.ServiceLevel8Choice;\r\nimport org.meveo.admin.util.ArConfig;\r\nimport org.meveo.commons.utils.EjbUtils;\r\nimport org.meveo.commons.utils.JAXBUtils;\r\nimport org.meveo.commons.utils.ParamBean;\r\nimport org.meveo.commons.utils.StringUtils;\r\nimport org.meveo.model.admin.Seller;\r\nimport org.meveo.model.billing.BankCoordinates;\r\nimport org.meveo.model.billing.Subscription;\r\nimport org.meveo.model.crm.Provider;\r\nimport org.meveo.model.payments.AccountOperation;\r\nimport org.meveo.model.payments.CustomerAccount;\r\nimport org.meveo.model.payments.DDPaymentMethod;\r\nimport org.meveo.model.payments.DDRequestItem;\r\nimport org.meveo.model.payments.DDRequestLOT;\r\nimport org.meveo.model.payments.OperationCategoryEnum;\r\nimport org.meveo.model.payments.PaymentGateway;\r\nimport org.meveo.model.payments.PaymentMethod;\r\nimport org.meveo.model.payments.PaymentMethodEnum;\r\nimport org.meveo.model.payments.RecordedInvoice;\r\nimport org.meveo.model.shared.DateUtils;\r\nimport org.meveo.model.shared.Name;\r\nimport org.meveo.model.shared.Title;\r\nimport org.meveo.service.admin.impl.SellerService;\r\nimport org.meveo.service.billing.impl.SubscriptionService;\r\nimport org.meveo.service.catalog.impl.CalendarBankingService;\r\nimport org.meveo.service.catalog.impl.TitleService;\r\nimport org.meveo.service.payments.impl.AccountOperationService;\r\nimport org.meveo.service.payments.impl.CustomerAccountService;\r\nimport org.meveo.service.payments.impl.DDRequestItemService;\r\nimport org.meveo.service.payments.impl.DDRequestLOTService;\r\nimport org.meveo.service.payments.impl.PaymentGatewayService;\r\nimport org.meveo.service.payments.impl.RecordedInvoiceService;\r\nimport org.meveo.service.script.payment.DDRequestBuilderScript;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n/**\r\n * The Class SepaDDRequestBuilderScript.\r\n *\r\n * @author anasseh\r\n */\r\n\r\npublic class SepaDDRequestBuilderScript extends DDRequestBuilderScript {\r\n\t/** The log. */\r\n\tprivate static Logger log = LoggerFactory.getLogger(SepaDDRequestBuilderScript.class);\r\n\r\n\t/** The location of SDD schema. */\r\n\tprivate static final String SDD_SCHEMA_LOCATION = \"https://github.com/w2c/sepa-sdd-xml-generator/blob/master/validation_schemes/pain.008.001.02.xsd\";\r\n\r\n\t/** The Constant SIMPLE_DATE_PATTERN. */\r\n\tprivate static final String SIMPLE_DATE_PATTERN = \"yyyyMMdd\";\r\n\r\n\t/** The Constant EMPTY_STRING. */\r\n\tprivate static final String EMPTY_STRING = \"\";\r\n\r\n\t/** The Constant DASH_STRING. */\r\n\tprivate static final String DASH_STRING = \"-\";\r\n\r\n\t/** The Constant DOUBLE_POINT. */\r\n\tprivate static final String DOUBLE_POINT = \"\\\\..\";\r\n\r\n\t/** The underscore separator used at sepa file name. */\r\n\tprivate static final String UNDERSCORE_SEPARATOR = \"_\";\r\n\r\n\t/** The Constant EURO_CCY. */\r\n\tprivate static final String EURO_CCY = \"EUR\";\r\n\r\n\t/** The Constant SEPA_SERVICE_LEVEL_CD. */\r\n\tprivate static final String SEPA_SERVICE_LEVEL_CD = \"SEPA\";\r\n\r\n\t/** The Constant SEPA_LOCAL_INSTRUMENT_CODE. */\r\n\tprivate static final String SEPA_LOCAL_INSTRUMENT_CODE = \"CORE\";\r\n\r\n\t/** The dd request item service. */\r\n\tprivate DDRequestItemService ddRequestItemService = (DDRequestItemService) EjbUtils.getServiceInterface(DDRequestItemService.class.getSimpleName());\r\n\r\n\t/** The dd request LOT service. */\r\n\tprivate DDRequestLOTService ddRequestLOTService = (DDRequestLOTService) EjbUtils.getServiceInterface(DDRequestLOTService.class.getSimpleName());\r\n\r\n\t/** The customer account service. */\r\n\tprivate CustomerAccountService customerAccountService = (CustomerAccountService) EjbUtils.getServiceInterface(CustomerAccountService.class.getSimpleName());\r\n\tprivate SubscriptionService subscriptionService = (SubscriptionService) EjbUtils.getServiceInterface(SubscriptionService.class.getSimpleName());\r\n\r\n\t/** The recorded invoice service. */\r\n\tprivate RecordedInvoiceService recordedInvoiceService = (RecordedInvoiceService) EjbUtils.getServiceInterface(RecordedInvoiceService.class.getSimpleName());\r\n\tprivate SellerService sellerService = (SellerService) EjbUtils.getServiceInterface(SellerService.class.getSimpleName());\r\n\tprivate TitleService titleService = (TitleService) EjbUtils.getServiceInterface(TitleService.class.getSimpleName());\r\n\tprivate CalendarBankingService calendarBankingService = (CalendarBankingService) getServiceInterface(CalendarBankingService.class.getSimpleName());\r\n\t\r\n\t\r\n\t\r\n\t\r\n\tprivate AccountOperationService accountOperationService = (AccountOperationService) EjbUtils.getServiceInterface(AccountOperationService.class.getSimpleName());\r\n\t\r\n\t\r\n\tprivate static final String CF_SUB_PAY_METHOD = \"CF_SUB_PAY_METHOD\";\r\n\t\r\n\t\r\n\t\r\n\r\n\t@Override\r\n\tpublic List<AccountOperation> findListAoToPay(Map<String, Object> methodContext) throws BusinessException {\r\n\t\tlog.info(\"findListAoToPay methodContext:{}\",methodContext);\r\n\t\tList<AccountOperation> aos = (List<AccountOperation>) methodContext.get(DDRequestBuilderScript.DD_REQUEST_LIST_AO);\r\n\t\tif (aos == null || aos.isEmpty()) {\r\n\t\t\treturn aos;\r\n\t\t}\r\n\t\taos = aos.stream().filter(ao -> (isDirectDebitOrder(ao))).collect(Collectors.toList());\r\n\t\tSeller seller = sellerService.findByCode(\"EKKO\");\r\n\t\tDouble paymentThreshold = (Double) seller.getCfValue(\"CF_SEL_PAY_AMOUNT_THRESHOLD\");\r\n\t\tif(paymentThreshold == null) {\r\n\t\t\tpaymentThreshold = 1d;\r\n\t\t}\r\n\r\n\t\tMap<CustomerAccount, List<AccountOperation>> aosByCA = new HashMap<CustomerAccount, List<AccountOperation>>();\r\n\t\tfor (AccountOperation ao : aos) {\r\n\t\t\tao = accountOperationService.refreshOrRetrieve(ao);\r\n\t\t\tCustomerAccount ca = customerAccountService.refreshOrRetrieve(ao.getCustomerAccount());\r\n\t\t\tList<AccountOperation> aosForCA = new ArrayList<AccountOperation>();\r\n\t\t\tif (aosByCA.containsKey(ca)) {\r\n\t\t\t\taosForCA = aosByCA.get(ca);\r\n\t\t\t}\r\n\t\t\taosForCA.add(ao);\r\n\t\t\taosByCA.put(ca, aosForCA);\r\n\t\t}\r\n\t\taos = new ArrayList<AccountOperation>();\r\n\t\tfor (Map.Entry<CustomerAccount, List<AccountOperation>> entry : aosByCA.entrySet()) {\r\n\t\t\tBigDecimal amountToPayByItem = BigDecimal.ZERO;\r\n\t\t\t\r\n\t\t\tCustomerAccount ca = entry.getKey();\r\n\t\t\t\r\n\t\t\tfor (AccountOperation ao : entry.getValue()) {\r\n\t\t\t\t\r\n\t\t\t\t\tamountToPayByItem = amountToPayByItem.add(ao.getUnMatchingAmount());\r\n\t\t\t\t\r\n\t\t\t}\r\n\t\t\tif(amountToPayByItem.compareTo(BigDecimal.valueOf(paymentThreshold))>=0) {\r\n\t\t\t\taos.addAll(entry.getValue());\r\n\t\t\t}\r\n\r\n\t\t\t\r\n\t\t}\r\n\r\n\t\treturn aos;\r\n\t}\r\n\r\n\tprivate boolean isDirectDebitOrder(AccountOperation ao) {\r\n\t\tlog.info(\"checking paymentMethodType for AO id:\"+ao.getId());\r\n\t\tif(ao.getSubscription() != null) {\r\n\t\t\tSubscription sub = subscriptionService.refreshOrRetrieve(ao.getSubscription());\r\n\t\t\tString orderPayMethod = (String)sub.getCfValue(CF_SUB_PAY_METHOD) ;\r\n\t\t\tlog.info(\"orderPayMethod:\"+orderPayMethod);\r\n\t\t\tif(PaymentMethodEnum.CARD.name().equals(orderPayMethod)) {\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn true;\r\n\t}\r\n\r\n\t@Override\r\n\tpublic String getDDFileName(Map<String, Object> methodContext) throws BusinessException {\r\n\t\tDDRequestLOT ddRequestLOT = (DDRequestLOT) methodContext.get(DDRequestBuilderScript.DD_REQUEST_LOT);\r\n\t\tProvider appProvider = (Provider) methodContext.get(DDRequestBuilderScript.PROVIDER);\r\n\t\tif (ddRequestLOT.getPaymentOrRefundEnum().getOperationCategoryToProcess() == OperationCategoryEnum.DEBIT) {\r\n\t\t\treturn getFileName(ddRequestLOT, appProvider, ArConfig.getDDRequestFileNamePrefix(), ArConfig.getDDRequestFileNameExtension(), ArConfig.getDDRequestOutputDirectory());\r\n\t\t} else {\r\n\t\t\treturn getFileName(ddRequestLOT, appProvider, ArConfig.getSCTRequestFileNamePrefix(), ArConfig.getSCTRequestFileNameExtension(), ArConfig.getSCTRequestOutputDir());\r\n\t\t}\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void generateDDRequestLotFile(Map<String, Object> methodContext) throws BusinessException {\r\n\r\n\t\tlog.info(\" >>> Starting generateDDRequestLotFile ... \");\r\n\t\tProvider appProvider = (Provider) methodContext.get(DDRequestBuilderScript.PROVIDER);\r\n\t\tDDRequestLOT ddRequestLOT = (DDRequestLOT) methodContext.get(DDRequestBuilderScript.DD_REQUEST_LOT);\r\n\t\tDDRequestLOTService ddRequestLotService = (DDRequestLOTService) getServiceInterface(\"DDRequestLOTService\");\r\n\t\tddRequestLOT = ddRequestLotService.findById(ddRequestLOT.getId(), Arrays.asList(\"ddrequestItems\", \"ddRequestBuilder\"));\r\n\t\tif (ddRequestLOT.getPaymentOrRefundEnum().getOperationCategoryToProcess() == OperationCategoryEnum.DEBIT) {\r\n\t\t\tgenerateDDRequestLotFileForSSD(ddRequestLOT, appProvider);\r\n\t\t} else {\r\n\t\t\t// generateDDRequestLotFileForSCT(ddRequestLOT, appProvider);\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the file name.\r\n\t *\r\n\t * @param ddRequestLot        the dd request lot\r\n\t * @param appProvider         the app provider\r\n\t * @param fileNamePrefix      the file name prefix\r\n\t * @param fileNameExtension   the file name extension\r\n\t * @param additionalOutputDir the additional output dir\r\n\t * @return the file name\r\n\t * @throws BusinessException the business exception\r\n\t */\r\n\tprivate String getFileName(DDRequestLOT ddRequestLot, Provider appProvider, String fileNamePrefix, String fileNameExtension, String additionalOutputDir)\r\n\t\t\tthrows BusinessException {\r\n\t\ttry {\r\n\t\t\t//SDD.PRL.MYP1_EKKO_20210401XXXXXXXXX.xml\r\n\t\t\tParamBean paramBean = ParamBean.getInstanceByProvider(appProvider.getCode());\r\n\t\t\tString fileName = \"SDD.PRL.MYP1_EKKO_\"+DateUtils.formatDateWithPattern(new Date(), \"yyyyMMddhhmmssSSS\")+\".xml\";\r\n\t\t\t\r\n\t\t\tString outputDir = paramBean.getChrootDir(appProvider.getCode());\r\n\r\n\t\t\toutputDir = outputDir + File.separator + additionalOutputDir;\r\n\t\t\toutputDir = outputDir.replaceAll(DOUBLE_POINT, EMPTY_STRING) + File.separator + \"EKKO\";\r\n\r\n\t\t\tlog.info(\"DDRequest output directory=\" + outputDir);\r\n\t\t\tFile dir = new File(outputDir);\r\n\t\t\tif (!dir.exists()) {\r\n\t\t\t\tdir.mkdirs();\r\n\t\t\t}\r\n\t\t\treturn outputDir + File.separator + fileName;\r\n\t\t} catch (Exception e) {\r\n\t\t\tlog.error(e.getMessage(), e);\r\n\t\t\tthrow new BusinessException(e.getMessage());\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Generate DD request lot file for SSD.\r\n\t *\r\n\t * @param ddRequestLot the dd request lot\r\n\t * @param appProvider  the app provider\r\n\t * @throws BusinessException the business exception\r\n\t */\r\n\tprivate void generateDDRequestLotFileForSSD(DDRequestLOT ddRequestLot, Provider appProvider) throws BusinessException {\r\n\t\ttry {\r\n\t\t\tParamBean paramBean = ParamBean.getInstanceByProvider(appProvider.getCode());\r\n\t\t\tDocument document = new Document();\r\n\t\t\tCustomerDirectDebitInitiationV02 message = new CustomerDirectDebitInitiationV02();\r\n\t\t\tdocument.setCstmrDrctDbtInitn(message);\r\n\t\t\taddHeader(message, ddRequestLot, appProvider);\r\n\r\n\t\t\tboolean isEmptyLot = addPaymentInformation(message, ddRequestLot, appProvider);\r\n\r\n\t\t\tif (isEmptyLot) {\r\n\t\t\t\tlog.warn(\"There no valid dd item, file will not created\");\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tString schemaLocation = paramBean.getProperty(\"sepa.schemaLocation.pain008\", SDD_SCHEMA_LOCATION);\r\n\t\t\tJAXBUtils.marshaller(document, new File(ddRequestLot.getFileName()), schemaLocation);\r\n\t\t} catch (Exception e) {\r\n\t\t\tlog.error(\"Error on generateDDRequestLotFileForSSD\", e);\r\n\t\t\tthrow new BusinessException(e.getMessage());\r\n\t\t}\r\n\r\n\t}\r\n\r\n\t/**\r\n\t * Adds the header of SDD file.\r\n\t *\r\n\t * @param message      the SDD message\r\n\t * @param ddRequestLOT the dd request LOT\r\n\t * @param appProvider  the provider\r\n\t * @throws Exception the exception\r\n\t */\r\n\tprivate void addHeader(CustomerDirectDebitInitiationV02 message, DDRequestLOT ddRequestLOT, Provider appProvider) throws Exception {\r\n\r\n\t\tGroupHeader39 groupHeader = new GroupHeader39();\r\n\t\tmessage.setGrpHdr(groupHeader);\r\n\t\tgroupHeader.setMsgId(ArConfig.getDDRequestHeaderReference() + DASH_STRING + ddRequestLOT.getId());\r\n\t\tgroupHeader.setCreDtTm(DateUtils.dateToXMLGregorianCalendar(new Date()));\r\n\t\tgroupHeader.setNbOfTxs(String.valueOf(ddRequestLOT.getNbItemsOk()));\r\n\t\tBigDecimal total = BigDecimal.ZERO;\r\n\t\tfor (DDRequestItem item : ddRequestLOT.getDdrequestItems()) {\r\n\t\t\tif (!item.hasError()) {\r\n\t\t\t\ttotal = total.add(item.getAmount().setScale(2, RoundingMode.HALF_UP));\r\n\t\t\t}\r\n\t\t}\r\n\t\tddRequestLOT.setTotalAmount(total);\r\n\t\tddRequestLOTService.updateNoCheck(ddRequestLOT);\r\n\t\tgroupHeader.setCtrlSum(total.setScale(2, RoundingMode.HALF_UP));\r\n\t\tPartyIdentification32 initgPty = new PartyIdentification32();\r\n\t\tif (ddRequestLOT.getSeller() != null) {\t\t\t\r\n\t\t\tinitgPty.setNm(format(sellerService.refreshOrRetrieve(ddRequestLOT.getSeller()).getDescription()));\r\n\t\t} else {\r\n\t\t\tinitgPty.setNm(format(appProvider.getDescription()));\r\n\t\t}\r\n\r\n\t\tgroupHeader.setInitgPty(initgPty);\r\n\r\n\t}\r\n\r\n\t/**\r\n\t * Adds the payment information of SDD file.\r\n\t *\r\n\t * @param Message       the SDD message\r\n\t * @param dDRequestItem the dd request item\r\n\t * @param appProvider   the provider\r\n\t * @throws Exception the exception\r\n\t */\r\n\tprivate boolean addPaymentInformation(CustomerDirectDebitInitiationV02 Message, DDRequestLOT ddRequestLot, Provider appProvider) throws Exception {\r\n\t\tboolean isEmptyLot = true;\r\n\t\tlog.info(\"addPaymentInformation dDRequestLot id=\" + ddRequestLot.getId());\r\n\t\tParamBean paramBean = ParamBean.getInstanceByProvider(appProvider.getCode());\r\n\t\tPaymentInstructionInformation4 paymentInformation = new PaymentInstructionInformation4();\r\n\t\tMessage.getPmtInf().add(paymentInformation);\r\n\t\tpaymentInformation.setPmtInfId(ArConfig.getDDRequestHeaderReference() + DASH_STRING + ddRequestLot.getId());\r\n\t\tpaymentInformation.setPmtMtd(PaymentMethod2Code.DD);\r\n\t\tpaymentInformation.setNbOfTxs(\"\" + ddRequestLot.getNbItemsOk());\r\n\t\tpaymentInformation.setCtrlSum(ddRequestLot.getTotalAmount().setScale(2, RoundingMode.HALF_UP));\r\n\t\tPaymentTypeInformation20 paymentTypeInformation = new PaymentTypeInformation20();\r\n\t\tpaymentInformation.setPmtTpInf(paymentTypeInformation);\r\n\t\tServiceLevel8Choice serviceLevel = new ServiceLevel8Choice();\r\n\t\tpaymentTypeInformation.setSvcLvl(serviceLevel);\r\n\t\tserviceLevel.setCd(SEPA_SERVICE_LEVEL_CD);\r\n\t\tLocalInstrument2Choice localInstrument = new LocalInstrument2Choice();\r\n\t\tpaymentTypeInformation.setLclInstrm(localInstrument);\r\n\t\tlocalInstrument.setCd(paramBean.getProperty(\"sepa.LclInstrm\", SEPA_LOCAL_INSTRUMENT_CODE));\r\n\t\tpaymentTypeInformation.setSeqTp(SequenceType1Code.RCUR);\r\n\t\t\r\n\t\t\r\n\t\tSeller seller = sellerService.findByCode(\"EKKO\");\r\n\t\tLong nbDaysSepa = (Long) seller.getCfValue(\"CF_SEL_SEPA_NB_BUSI_DAYS\");\r\n\t\tLong nbDaysPay = (Long) seller.getCfValue(\"CF_SEL_PAY_NB_BUSI_DAYS\");\r\n\t\tLong nbDaysToAdd = nbDaysPay - nbDaysSepa;\r\n\t\t\r\n\t\tDate customerRequestedDate = addBusinessDays(new Date(), nbDaysToAdd);\r\n\t\tlog.info(\"customerRequestedDate business day:\" + customerRequestedDate);\r\n\r\n\t\tlog.info(\"customerRequestedDate business day:\" + customerRequestedDate);\r\n\t\tpaymentInformation.setReqdColltnDt(DateUtils.dateToXMLGregorianCalendarFieldUndefined(customerRequestedDate));\r\n\r\n\t\tBankCoordinates bankCoordinates = getBankCoordinates(ddRequestLot, appProvider);\r\n\r\n\t\tif (bankCoordinates == null) {\r\n\t\t\tthrow new BusinessException(\"Missing bank information on provider or seller\");\r\n\t\t}\r\n\t\tPartyIdentification32 creditor = new PartyIdentification32();\r\n\t\tif (ddRequestLot.getSeller() != null) {\r\n\t\t\tcreditor.setNm(format(sellerService.refreshOrRetrieve(ddRequestLot.getSeller()).getDescription()));\r\n\t\t} else {\r\n\t\t\tcreditor.setNm(format(appProvider.getDescription()));\r\n\t\t}\r\n\r\n\t\tpaymentInformation.setCdtr(creditor);\r\n\r\n\t\tCashAccount16 creditorAccount = new CashAccount16();\r\n\t\tpaymentInformation.setCdtrAcct(creditorAccount);\r\n\t\tAccountIdentification4Choice identification = new AccountIdentification4Choice();\r\n\t\tcreditorAccount.setId(identification);\r\n\t\tidentification.setIBAN(format(bankCoordinates.getIban()));\r\n\r\n\t\tBranchAndFinancialInstitutionIdentification4 creditorAgent = new BranchAndFinancialInstitutionIdentification4();\r\n\t\tpaymentInformation.setCdtrAgt(creditorAgent);\r\n\t\tFinancialInstitutionIdentification7 financialInstitutionIdentification = new FinancialInstitutionIdentification7();\r\n\t\tcreditorAgent.setFinInstnId(financialInstitutionIdentification);\r\n\t\tfinancialInstitutionIdentification.setBIC(bankCoordinates.getBic());\r\n\t\tPartyIdentification32 creditorSchemeIdentification = new PartyIdentification32();\r\n\t\tpaymentInformation.setCdtrSchmeId(creditorSchemeIdentification);\r\n\t\tParty6Choice cdtrSchmeId = new Party6Choice();\r\n\t\tcreditorSchemeIdentification.setId(cdtrSchmeId);\r\n\t\tPersonIdentification5 privateidentifier = new PersonIdentification5();\r\n\t\tcdtrSchmeId.setPrvtId(privateidentifier);\r\n\t\tGenericPersonIdentification1 other = new GenericPersonIdentification1();\r\n\t\tprivateidentifier.getOthr().add(other);\r\n\t\tother.setId(bankCoordinates.getIcs());\r\n\t\tPersonIdentificationSchemeName1Choice schemeName = new PersonIdentificationSchemeName1Choice();\r\n\t\tother.setSchmeNm(schemeName);\r\n\t\tschemeName.setPrtry(SEPA_SERVICE_LEVEL_CD);\r\n\r\n\t\tfor (DDRequestItem ddrequestItem : ddRequestLot.getDdrequestItems()) {\r\n\t\t\tddrequestItem = ddRequestItemService.findById(ddrequestItem.getId(), Arrays.asList(\"accountOperations\"));\r\n\t\t\tif (!ddrequestItem.hasError()) {\r\n\t\t\t\taddTransaction(ddrequestItem, paymentInformation);\r\n\t\t\t\tisEmptyLot = false;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn isEmptyLot;\r\n\r\n\t}\r\n\r\n\t/**\r\n\t * Adds the transaction of SDD file.\r\n\t *\r\n\t * @param dDRequestItem      the dd request item\r\n\t * @param paymentInformation the payment information of SDD file\r\n\t * @throws Exception the exception\r\n\t */\r\n\tprivate void addTransaction(DDRequestItem dDRequestItem, PaymentInstructionInformation4 paymentInformation) throws Exception {\r\n\t\tCustomerAccount ca = customerAccountService.findById(dDRequestItem.getAccountOperations().get(0).getCustomerAccount().getId(), Arrays.asList(\"paymentMethods\"));\r\n\r\n\t\tPaymentMethod preferedPaymentMethod = customerAccountService.getPreferredPaymentMethod(dDRequestItem.getAccountOperations().get(0).getCustomerAccount().getId());\r\n\t\tif (preferedPaymentMethod == null || !(preferedPaymentMethod instanceof DDPaymentMethod)) {\r\n\t\t\tthrow new BusinessException(\"Payment method not valid!\");\r\n\t\t}\r\n\t\tBankCoordinates bankCoordinates = ((DDPaymentMethod) preferedPaymentMethod).getBankCoordinates();\r\n\r\n\t\tif (bankCoordinates == null) {\r\n\t\t\tthrow new BusinessException(\"Bank Coordinate is absent for Payment method \" + ((DDPaymentMethod) preferedPaymentMethod).getAlias());\r\n\t\t}\r\n\r\n\t\tDirectDebitTransactionInformation9 directDebitTransactionInformation = new DirectDebitTransactionInformation9();\r\n\t\tpaymentInformation.getDrctDbtTxInf().add(directDebitTransactionInformation);\r\n\t\tPaymentIdentification1 PaymentIdentification = new PaymentIdentification1();\r\n\t\tdirectDebitTransactionInformation.setPmtId(PaymentIdentification);\r\n\t\tPaymentIdentification.setInstrId(getCorrelationId(ca, dDRequestItem.getAccountOperations().get(0), dDRequestItem.getId()));\r\n\t\tPaymentIdentification.setEndToEndId(getCorrelationId(ca, dDRequestItem.getAccountOperations().get(0), dDRequestItem.getId()));\r\n\t\tActiveOrHistoricCurrencyAndAmount instructedAmount = new ActiveOrHistoricCurrencyAndAmount();\r\n\t\tdirectDebitTransactionInformation.setInstdAmt(instructedAmount);\r\n\t\tinstructedAmount.setValue(dDRequestItem.getAmount().setScale(2, RoundingMode.HALF_UP));\r\n\t\tinstructedAmount.setCcy(EURO_CCY);\r\n\t\tDirectDebitTransaction6 directDebitTransaction = new DirectDebitTransaction6();\r\n\t\tdirectDebitTransactionInformation.setDrctDbtTx(directDebitTransaction);\r\n\t\tMandateRelatedInformation6 mandateRelatedInformation = new MandateRelatedInformation6();\r\n\t\tdirectDebitTransaction.setMndtRltdInf(mandateRelatedInformation);\r\n\r\n\t\tmandateRelatedInformation.setMndtId(((DDPaymentMethod) preferedPaymentMethod).getMandateIdentification());\r\n\t\tmandateRelatedInformation.setDtOfSgntr(DateUtils.dateToXMLGregorianCalendarFieldUndefined(((DDPaymentMethod) preferedPaymentMethod).getMandateDate()));\r\n\t\tBranchAndFinancialInstitutionIdentification4 debtorAgent = new BranchAndFinancialInstitutionIdentification4();\r\n\t\tdirectDebitTransactionInformation.setDbtrAgt(debtorAgent);\r\n\t\tFinancialInstitutionIdentification7 financialInstitutionIdentification = new FinancialInstitutionIdentification7();\r\n\t\tGenericFinancialIdentification1 bicInfo = new GenericFinancialIdentification1();\r\n\t\tbicInfo.setId(\"NOTPROVIDED\");\r\n\t\tfinancialInstitutionIdentification.setOthr(bicInfo);\r\n\t\tdebtorAgent.setFinInstnId(financialInstitutionIdentification);\r\n\r\n\t\tPartyIdentification32 debtor = new PartyIdentification32();\r\n\t\tdirectDebitTransactionInformation.setDbtr(debtor);\r\n\t\tdebtor.setNm(format(getDebtorFullName(ca)));\r\n\r\n\t\tCashAccount16 debtorAccount = new CashAccount16();\r\n\t\tdirectDebitTransactionInformation.setDbtrAcct(debtorAccount);\r\n\t\tAccountIdentification4Choice identification = new AccountIdentification4Choice();\r\n\t\tidentification.setIBAN(bankCoordinates.getIban());\r\n\t\tdebtorAccount.setId(identification);\r\n\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the correlation id.\r\n\t *\r\n\t * @param ca               the ca\r\n\t * @param accountOperation the account operation\r\n\t * @param ddReqItemId      the dd req item id\r\n\t * @return the correlation id\r\n\t */\r\n\tprivate String getCorrelationId(CustomerAccount ca, AccountOperation accountOperation, Long ddReqItemId) {\r\n\r\n\t\treturn accountOperation.getId() + \"_\" + ca.getCode() + \"_\" + ddReqItemId;\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the debtor full name.\r\n\t *\r\n\t * @param ca the ca\r\n\t * @return the debtor full name\r\n\t */\r\n\tprivate String getDebtorFullName(CustomerAccount ca) {\r\n\t\tString fullName = \"\";\r\n\t\tName name = ca.getName();\r\n\t\tif (name != null) {\t\t\r\n\t\t\tfullName = geFullName(name);\r\n\t\t} else {\r\n\t\t\tfullName = geFullName(ca.getCustomer().getName());\r\n\t\t}\r\n\t\treturn fullName;\r\n\t}\r\n\t\r\n\tprivate String geFullName(Name name) {\r\n\t\tTitle title = titleService.refreshOrRetrieve(name.getTitle());\r\n\t\treturn   title.getCode()+\" \"+name.getFirstName()+\" \"+name.getLastName();\r\n\t\t\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the bank coordinates.\r\n\t *\r\n\t * @param ddRequestLOT the dd request LOT\r\n\t * @param appProvider  the app provider\r\n\t * @return the bank coordinates\r\n\t * @throws BusinessException the business exception\r\n\t */\r\n\tprivate BankCoordinates getBankCoordinates(DDRequestLOT ddRequestLOT, Provider appProvider) throws BusinessException {\r\n\t\tif (ddRequestLOT.getSeller() != null) {\r\n\t\t\tPaymentGatewayService paymentGatewayService = (PaymentGatewayService) getServiceInterface(\"PaymentGatewayService\");\r\n\t\t\tPaymentGateway paymentGateway = paymentGatewayService.getPaymentGateway(ddRequestLOT.getSeller(), PaymentMethodEnum.DIRECTDEBIT);\r\n\t\t\tif (paymentGateway == null) {\r\n\t\t\t\tthrow new BusinessException(\"Cant find payment gateway for seller : \" + ddRequestLOT.getSeller());\r\n\t\t\t}\r\n\t\t\treturn paymentGateway.getBankCoordinates();\r\n\t\t} else {\r\n\t\t\treturn appProvider.getBankCoordinates();\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the end to end id.\r\n\t *\r\n\t * @param accountNotification2 the account notification 2\r\n\t * @return the end to end id\r\n\t */\r\n\tprivate String getEndToEndId(AccountNotification2 accountNotification2) {\r\n\t\tString endToEndId = null;\r\n\t\ttry {\r\n\t\t\tendToEndId = accountNotification2.getNtry().get(0).getNtryDtls().get(0).getTxDtls().get(0).getRefs().getEndToEndId();\r\n\t\t\treturn endToEndId;\r\n\t\t} catch (Exception e) {\r\n\t\t\tthrow new BusinessException(\"Can't found END_TO_END \");\r\n\t\t}\r\n\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the dd item id from end to end.\r\n\t *\r\n\t * @param endToEnd the end to end\r\n\t * @return the dd item id from end to end\r\n\t */\r\n\tprivate Long getDdItemIdFromEndToEnd(String endToEnd) {\r\n\t\tif (StringUtils.isBlank(endToEnd) || endToEnd.indexOf(\"_\") == -1) {\r\n\t\t\tthrow new BusinessException(\"Invalid format END_TO_END :\" + endToEnd);\r\n\t\t}\r\n\t\ttry {\r\n\r\n\t\t\treturn Long.valueOf(endToEnd.substring(endToEnd.lastIndexOf(\"_\") + 1, endToEnd.length()));\r\n\t\t} catch (Exception e) {\r\n\t\t\tthrow new BusinessException(\"Invalid type END_TO_END :\" + endToEnd);\r\n\t\t}\r\n\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the a id from end to end.\r\n\t *\r\n\t * @param endToEnd the end to end\r\n\t * @return the a id from end to end\r\n\t */\r\n\tprivate Long getAIdFromEndToEnd(String endToEnd) {\r\n\t\tif (StringUtils.isBlank(endToEnd) || endToEnd.indexOf(\"_\") == -1) {\r\n\t\t\tthrow new BusinessException(\"Invalid format END_TO_END :\" + endToEnd);\r\n\t\t}\r\n\t\ttry {\r\n\r\n\t\t\treturn Long.valueOf(endToEnd.substring(0, endToEnd.indexOf(\"_\")));\r\n\t\t} catch (Exception e) {\r\n\t\t\tthrow new BusinessException(\"Invalid type END_TO_END :\" + endToEnd);\r\n\t\t}\r\n\r\n\t}\r\n\r\n\tpublic DDRejectFileInfos processSDDRejectedFile(Map<String, Object> methodContext) throws BusinessException {\r\n\t\tFile sepaRejectedFile = (File) methodContext.get(DDRequestBuilderScript.DD_REJECT_FILE);\r\n\t\tif (sepaRejectedFile == null) {\r\n\t\t\tthrow new BusinessException(\"sepaRejectedFile is null\");\r\n\t\t}\r\n\t\tlog.info(\"processSDDRejectedFile:\" + sepaRejectedFile.getName());\r\n\t\tDDRejectFileInfos ddRejectFileInfos = new DDRejectFileInfos();\r\n\t\ttry {\r\n\t\t\tddRejectFileInfos.setFileName(sepaRejectedFile.getName());\r\n\t\t\torg.meveo.admin.sepa.jaxb.camt054.Document camt54 = (org.meveo.admin.sepa.jaxb.camt054.Document) JAXBUtils\r\n\t\t\t\t\t.unmarshaller(org.meveo.admin.sepa.jaxb.camt054.Document.class, sepaRejectedFile);\r\n\r\n\t\t\tBankToCustomerDebitCreditNotificationV02 bkToCstmrDbtCdtNtfctn = camt54.getBkToCstmrDbtCdtNtfctn();\r\n\r\n\t\t\tList<AccountNotification2> listNtfctn = bkToCstmrDbtCdtNtfctn.getNtfctn();\r\n\t\t\tfor (AccountNotification2 accountNotification2 : listNtfctn) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tString endToEnd = getEndToEndId(accountNotification2);\r\n\t\t\t\t\tString rejectReason = getRejectReason(accountNotification2);\r\n\t\t\t\t\tddRejectFileInfos.getListInvoiceRefsRejected().put(getDdItemIdFromEndToEnd(endToEnd), rejectReason);\r\n\t\t\t\t\tddRequestLOTService.rejectPayment(ddRequestItemService.findById(getDdItemIdFromEndToEnd(endToEnd)), rejectReason, sepaRejectedFile.getName());\r\n\t\t\t\t\tddRejectFileInfos.addItemOk();\r\n\r\n\t\t\t\t\tRecordedInvoice ri = recordedInvoiceService.findById(getAIdFromEndToEnd(endToEnd));\r\n\t\t\t\t\tri.setPaymentInfo6(\"NotAllowed\");\r\n\t\t\t\t\trecordedInvoiceService.updateNoCheck(ri);\r\n\r\n\t\t\t\t} catch (Exception e) {\r\n\t\t\t\t\tddRejectFileInfos.addItemKo();\r\n\t\t\t\t\tlog.error(\"Error on processSDDRejectedFile :\", e);\r\n\t\t\t\t\tddRejectFileInfos.getListErrors().add(e.getMessage());\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t} catch (Exception e) {\r\n\t\t\tthrow new BusinessException(e.getMessage());\r\n\t\t}\r\n\t\treturn ddRejectFileInfos;\r\n\t}\r\n\r\n\t/**\r\n\t * Format.\r\n\t *\r\n\t * @param valueStr the value str\r\n\t * @return the string\r\n\t */\r\n\tprivate String format(String valueStr) {\r\n\t\tif (valueStr == null) {\r\n\t\t\treturn \"\";\r\n\t\t}\r\n\t\treturn StringUtils.enleverAccent(valueStr);\r\n\t}\r\n\r\n\t/**\r\n\t * Gets the reject reason.\r\n\t *\r\n\t * @param accountNotification2 the account notification 2\r\n\t * @return the reject reason\r\n\t */\r\n\tprivate String getRejectReason(AccountNotification2 accountNotification2) {\r\n\t\tString rejectReason = null;\r\n\t\ttry {\r\n\t\t\trejectReason = accountNotification2.getNtry().get(0).getNtryDtls().get(0).getTxDtls().get(0).getRtrInf().getRsn().getCd();\r\n\t\t\tif (\"AC01\".equals(rejectReason))\r\n\t\t\t\treturn rejectReason + \":\" + \"IBAN incorrect ou inconnu\";\r\n\t\t\tif (\"AC04\".equals(rejectReason))\r\n\t\t\t\treturn rejectReason + \":\" + \"Le titulaire a ferm\\u00E9 son compte\";\r\n\t\t\tif (\"AC06\".equals(rejectReason))\r\n\t\t\t\treturn rejectReason + \":\" + \"Compte bloqu\\u00E9 pour pr\\u00E9l\\u00e8vement automatique\";\r\n\t\t\tif (\"AG02\".equals(rejectReason))\r\n\t\t\t\treturn rejectReason + \":\" + \"Information incorrecte\";\r\n\t\t\tif (\"AM04\".equals(rejectReason))\r\n\t\t\t\treturn rejectReason + \":\" + \"Fonds insuffisants\";\r\n\t\t\tif (\"MD01\".equals(rejectReason))\r\n\t\t\t\treturn rejectReason + \":\" + \"Mandat non valide\";\r\n\t\t\tif (\"MD06\".equals(rejectReason))\r\n\t\t\t\treturn rejectReason + \":\" + \"R\\u00E9tro-facturation du paiement\";\r\n\t\t\tif (\"MD07\".equals(rejectReason))\r\n\t\t\t\treturn rejectReason + \":\" + \"Le client est d\\u00E9c\\u00E9d\\u00E9\";\r\n\t\t\tif (\"MS02\".equals(rejectReason))\r\n\t\t\t\treturn rejectReason + \":\" + \"Transaction refus\\u00E9e\";\r\n\t\t\tif (\"MS03\".equals(rejectReason))\r\n\t\t\t\treturn rejectReason + \":\" + \"Autre raison\";\r\n\t\t\tif (\"SL01\".equals(rejectReason))\r\n\t\t\t\treturn rejectReason + \":\" + \"Refus\\u00E9 par la banque d\\u00E9bitrice\";\r\n\t\t\treturn rejectReason;\r\n\t\t} catch (Exception e) {\r\n\t\t\tthrow new BusinessException(\"Can't found rejectReason \");\r\n\t\t}\r\n\t}\r\n\t\r\n\tprivate Date addBusinessDays(Date dateStart, Long nbDays) {\r\n\r\n\t\tint daysAdded = 0;\r\n\t\tDate endDate = dateStart;\r\n\t\twhile (daysAdded != nbDays.intValue()) {\r\n\t\t\tendDate = DateUtils.addDaysToDate(endDate, 1);\r\n\t\t\tif (calendarBankingService.isBankWorkingDate(endDate)) {\r\n\t\t\t\tdaysAdded++;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn DateUtils.setDateToEndOfDay(endDate);\r\n\t}\r\n}\r\n\r\n\r\n ]]>\r\n            </script>\r\n</ScriptInstance>"
								},
								"url": {
									"raw": "{{opencell.url}}/scriptInstance/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"scriptInstance",
										"createOrUpdate"
									]
								},
								"description": "A Custom script to compute CUrrent Month Date range."
							},
							"response": []
						},
						{
							"name": "Create PaymentEkkoDateRangeScript",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Status code is 200\", function () {",
											"    pm.response.to.have.status(200);",
											"});"
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"auth": {
									"type": "basic",
									"basic": [
										{
											"key": "username",
											"value": "{{opencell.username}}",
											"type": "string"
										},
										{
											"key": "password",
											"value": "{{opencell.password}}",
											"type": "string"
										}
									]
								},
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/xml"
									},
									{
										"key": "Proxy-Authorization",
										"type": "text",
										"value": "{{proxy.auth}}"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "<ScriptInstance code=\"com.opencellsoft.service.ekko.payment.PaymentEkkoDateRangeScript\" description=\"Range date payment EKKO\">\r\n            <type>JAVA</type>\r\n            <script>\r\n            <![CDATA[package com.opencellsoft.service.ekko.payment;\r\n\r\nimport java.util.Date;\r\nimport java.util.Map;\r\n\r\nimport org.meveo.admin.exception.BusinessException;\r\nimport org.meveo.admin.job.DateRange;\r\nimport org.meveo.model.admin.Seller;\r\nimport org.meveo.model.shared.DateUtils;\r\nimport org.meveo.service.admin.impl.SellerService;\r\nimport org.meveo.service.catalog.impl.CalendarBankingService;\r\nimport org.meveo.service.script.payment.DateRangeScript;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n/**\r\n * \r\n * @author anasseh\r\n *\r\n */\r\n\r\npublic class PaymentEkkoDateRangeScript extends DateRangeScript {\r\n\tprivate Logger log = LoggerFactory.getLogger(PaymentEkkoDateRangeScript.class);\r\n\r\n\tprivate CalendarBankingService calendarBankingService = (CalendarBankingService) getServiceInterface(CalendarBankingService.class.getSimpleName());\r\n\tprivate SellerService sellerService = (SellerService) getServiceInterface(SellerService.class.getSimpleName());\r\n\r\n\t\r\n\tprivate static final String CF_SEL_SEPA_NB_BUSI_DAYS = \"CF_SEL_SEPA_NB_BUSI_DAYS\";\r\n\t\r\n\t@Override\r\n\tpublic DateRange computeDateRange(Map<String, Object> methodContext) throws BusinessException {\r\n\t\t\r\n\t\tlog.info(\"Execute context : {} \",methodContext);\r\n\t\t\r\n\t\tSeller seller = sellerService.findByCode(\"EKKO\");\r\n\t\tLong nbDaysSepa = (Long) seller.getCfValue(CF_SEL_SEPA_NB_BUSI_DAYS);\r\n\r\n\t\tDateRange dateRange = new DateRange(DateUtils.setDateToStartOfDay(new Date(1)), addBusinessDays(new Date(),nbDaysSepa));\r\n\r\n\t\tlog.info(\"sysdate:{} startDate:{} endDate:{}\", new Date(), dateRange.getFrom(), dateRange.getTo());\r\n\t\treturn dateRange;\r\n\t}\r\n\r\n\tprivate Date addBusinessDays(Date dateStart, Long nbDays) {\r\n\r\n\t\tint daysAdded = 0;\r\n\t\tDate endDate = dateStart;\r\n\t\twhile (daysAdded != nbDays.intValue()) {\r\n\t\t\tendDate = DateUtils.addDaysToDate(endDate, 1);\r\n\t\t\tif (calendarBankingService.isBankWorkingDate(endDate)) {\r\n\t\t\t\tdaysAdded++;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn DateUtils.setDateToEndOfDay(endDate);\r\n\t}\r\n} ]]>\r\n            </script>\r\n</ScriptInstance>\r\n\r\n"
								},
								"url": {
									"raw": "{{opencell.url}}/scriptInstance/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"scriptInstance",
										"createOrUpdate"
									]
								},
								"description": "A Custom script to compute CUrrent Month Date range."
							},
							"response": []
						}
					]
				}
			]
		},
		{
			"name": "Settings",
			"item": [
				{
					"name": "AccountingCodes",
					"item": [
						{
							"name": "706260",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \"code\": \"706260\",\r\n  \"description\": \"706260\",\r\n  \"chartOfAccountTypeEnum\" : \"ASSETS\",\r\n  \"chartOfAccountViewTypeEnum\" : \"VIEW\"\r\n  \r\n}"
								},
								"url": {
									"raw": "{{opencell.url}}/billing/accountingCode/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"billing",
										"accountingCode",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "709300",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \"code\": \"709300\",\r\n  \"description\": \"709300\",\r\n  \"chartOfAccountTypeEnum\" : \"EXPENSE\",\r\n  \"chartOfAccountViewTypeEnum\" : \"VIEW\"\r\n  \r\n}"
								},
								"url": {
									"raw": "{{opencell.url}}/billing/accountingCode/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"billing",
										"accountingCode",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "706800",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \"code\": \"706800\",\r\n  \"description\": \"706800\",\r\n  \"chartOfAccountTypeEnum\" : \"ASSETS\",\r\n  \"chartOfAccountViewTypeEnum\" : \"VIEW\"\r\n  \r\n}"
								},
								"url": {
									"raw": "{{opencell.url}}/billing/accountingCode/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"billing",
										"accountingCode",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "445710",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \"code\": \"445710\",\r\n  \"description\": \"445710\",\r\n  \"chartOfAccountTypeEnum\" : \"LIABILITIES\",\r\n  \"chartOfAccountViewTypeEnum\" : \"REGULAR\"\r\n  \r\n}"
								},
								"url": {
									"raw": "{{opencell.url}}/billing/accountingCode/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"billing",
										"accountingCode",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "411120",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \"code\": \"411120\",\r\n  \"description\": \"411120\",\r\n  \"chartOfAccountTypeEnum\" : \"LIABILITIES\",\r\n  \"chartOfAccountViewTypeEnum\" : \"REGULAR\"\r\n  \r\n}"
								},
								"url": {
									"raw": "{{opencell.url}}/billing/accountingCode/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"billing",
										"accountingCode",
										"createOrUpdate"
									]
								}
							},
							"response": []
						}
					]
				},
				{
					"name": "customer",
					"item": [
						{
							"name": "Titles",
							"item": [
								{
									"name": "title M",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "test",
												"value": "test"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"code\": \"M.\",\n    \"description\": \"Monsieur\",\n    \"isCompany\": false\n   \n}"
										},
										"url": {
											"raw": "{{opencell.url}}/account/title/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"account",
												"title",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "title Mme",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "test",
												"value": "test"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"code\": \"Mme\",\n    \"description\": \"Madame\",\n    \"isCompany\": false\n   \n}"
										},
										"url": {
											"raw": "{{opencell.url}}/account/title/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"account",
												"title",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "title Mlle",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "test",
												"value": "test"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"code\": \"Mlle\",\n    \"description\": \"Mademoiselle\",\n    \"isCompany\": false\n   \n}"
										},
										"url": {
											"raw": "{{opencell.url}}/account/title/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"account",
												"title",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "title CIE",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "test",
												"value": "test"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"code\": \"CIE\",\n    \"description\": \"Sté\",\n    \"isCompany\": true\n   \n}"
										},
										"url": {
											"raw": "{{opencell.url}}/account/title/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"account",
												"title",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						},
						{
							"name": "Currencies",
							"item": [
								{
									"name": "code=EUR|desc=Euro",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{ \n  \"code\": \"{{code}}\",\n  \"description\": \"{{desc}}\"\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/currency/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"currency",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						},
						{
							"name": "Countries",
							"item": [
								{
									"name": "code=FR|name=France|currency=EUR",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{ \n  \"countryCode\": \"{{code}}\",\n  \"name\": \"{{name}}\",\n  \"currencyCode\":\"{{currency}}\"\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/country/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"country",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						},
						{
							"name": "Languages",
							"item": [
								{
									"name": "code=FRA|desc=Français",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{ \n  \"code\": \"{{code}}\",\n  \"description\": \"{{desc}}\"\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/language/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"language",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						}
					]
				},
				{
					"name": "Taxes",
					"item": [
						{
							"name": "Tax categories",
							"item": [
								{
									"name": "taxCat|code=STANDARD|desc=Comptes standards",
									"event": [
										{
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											},
											"listen": "test"
										},
										{
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											},
											"listen": "prerequest"
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"value": "application/json",
												"key": "Content-Type"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"code\": \"{{code}}\",\n    \"description\": \"{{desc}}\",\n    \"descriptionI18n\": [\n        {\n            \"languageCode\": \"FRA\",\n            \"description\": \"{{desc}}\"\n        }\n    ]\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/taxCategory/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"taxCategory",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						},
						{
							"name": "Rate",
							"item": [
								{
									"name": "20% BF",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										},
										{
											"listen": "prerequest",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n  \"code\": \"BF\",\n  \"description\": \"Coll. 20,0% - FR Opérations taxables\",\n  \"percent\": \"20\",\n  \"accountingCode\": \"445710\",\n  \"languageDescriptions\": [\n  {\n    \"languageCode\": \"FRA\",\n    \"description\": \"Coll. 20,0% - FR Opérations taxables\"\n  }\n  ]\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/tax/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"tax",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "10% BE",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										},
										{
											"listen": "prerequest",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n  \"code\": \"BE\",\n  \"description\": \"Coll. 10,0% - FR Opérations taxables\",\n  \"percent\": \"10\",\n  \"accountingCode\": \"445710\",\n  \"languageDescriptions\": [\n  {\n    \"languageCode\": \"FRA\",\n    \"description\": \"Coll. 10,0% - FR Opérations taxables\"\n  }\n  ]\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/tax/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"tax",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "5.5% B2",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										},
										{
											"listen": "prerequest",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n  \"code\": \"B2\",\n  \"description\": \"Coll. 5,5% - FR Opérations taxables\",\n  \"percent\": \"5.5\",\n  \"accountingCode\": \"445710\",\n  \"languageDescriptions\": [\n  {\n    \"languageCode\": \"FRA\",\n    \"description\": \"Coll. 5,5% - FR Opérations taxables\"\n  }\n  ]\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/tax/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"tax",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						},
						{
							"name": "Tax classes (charge)",
							"item": [
								{
									"name": "TVA_20",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										},
										{
											"listen": "prerequest",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"code\": \"TVA_20\",\n    \"description\": \"Tva standard 20\"\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/taxClass/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"taxClass",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "TVA_10",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										},
										{
											"listen": "prerequest",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"code\": \"TVA_10\",\n    \"description\": \"Tva standard 10\"\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/taxClass/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"taxClass",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "TVA_5.5",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										},
										{
											"listen": "prerequest",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"code\": \"TVA_55\",\n    \"description\": \"Tva standard 5.5\"\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/taxClass/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"taxClass",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						},
						{
							"name": "Tax mapping",
							"item": [
								{
									"name": "TVA_20_FR",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										},
										{
											"listen": "prerequest",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"accountTaxCategoryCode\": \"STANDARD\",\n    \"chargeTaxClassCode\": \"TVA_20\",\n    \"buyerCountryCode\": \"FR\",\n    \"taxCode\": \"BF\",\n    \"priority\": 0\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/taxMapping/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"taxMapping",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "TVA_10_FR",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										},
										{
											"listen": "prerequest",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"accountTaxCategoryCode\": \"STANDARD\",\n    \"chargeTaxClassCode\": \"TVA_10\",\n    \"buyerCountryCode\": \"FR\",\n    \"taxCode\": \"BE\",\n    \"priority\": 0\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/taxMapping/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"taxMapping",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "TVA_55_FR",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										},
										{
											"listen": "prerequest",
											"script": {
												"exec": [
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"accountTaxCategoryCode\": \"STANDARD\",\n    \"chargeTaxClassCode\": \"TVA_55\",\n    \"buyerCountryCode\": \"FR\",\n    \"taxCode\": \"B2\",\n    \"priority\": 0\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/taxMapping/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"taxMapping",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						},
						{
							"name": "CLIENT",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"var jsonData = JSON.parse(responseBody);",
											"tests[\"is.success\"] = jsonData.status === \"SUCCESS\";"
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									}
								],
								"body": {
									"mode": "raw",
									"raw": " {\n    \"code\": \"CLIENT\",\n    \"description\": \"Client\",\n    \"exoneratedFromTaxes\": \"false\",\n    \"taxCategoryCode\": \"STANDARD\",\n    \"accountingCode\": null\n }"
								},
								"url": {
									"raw": "{{opencell.url}}/account/customer/createOrUpdateCategory",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"account",
										"customer",
										"createOrUpdateCategory"
									]
								}
							},
							"response": []
						}
					],
					"event": [
						{
							"listen": "prerequest",
							"script": {
								"type": "text/javascript",
								"exec": [
									""
								]
							}
						},
						{
							"listen": "test",
							"script": {
								"type": "text/javascript",
								"exec": [
									""
								]
							}
						}
					]
				},
				{
					"name": "CFs",
					"item": [
						{
							"name": "CF_SEL_INV_NB_BUSI_DAYS",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\n            \"code\":\"CF_SEL_INV_NB_BUSI_DAYS\",\n            \"description\":\"Nombre de jours aprés facturation upFront\",\n            \"appliesTo\": \"Seller\",\n            \"fieldType\":\"LONG\",\n            \"storageType\":\"SINGLE\",\n            \"valueRequired\":false,\n            \"versionable\":false,\n            \"allowEdit\":true,\n            \"hideOnNew\":false,\n            \"guiPosition\": \"tab:Facturation;field:0\"\n         }"
								},
								"url": {
									"raw": "{{opencell.url}}/customFieldTemplate/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"customFieldTemplate",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "CF_SEL_SEPA_NB_BUSI_DAYS",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\n            \"code\":\"CF_SEL_SEPA_NB_BUSI_DAYS\",\n            \"description\":\"Nombre de jours ouvrable pour la génération Sepa\",\n            \"appliesTo\": \"Seller\",\n            \"fieldType\":\"LONG\",\n            \"storageType\":\"SINGLE\",\n            \"valueRequired\":false,\n            \"versionable\":false,\n            \"allowEdit\":true,\n            \"hideOnNew\":false,\n            \"guiPosition\": \"tab:Paiement;field:0\"\n         }"
								},
								"url": {
									"raw": "{{opencell.url}}/customFieldTemplate/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"customFieldTemplate",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "CF_SEL_PAY_NB_BUSI_DAYS",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\n            \"code\":\"CF_SEL_PAY_NB_BUSI_DAYS\",\n            \"description\":\"Nombre de jours ouvrable pour la date de paiement\",\n            \"appliesTo\": \"Seller\",\n            \"fieldType\":\"LONG\",\n            \"storageType\":\"SINGLE\",\n            \"valueRequired\":false,\n            \"versionable\":false,\n            \"allowEdit\":true,\n            \"hideOnNew\":false,\n            \"guiPosition\": \"tab:Paiement;field:0\"\n         }"
								},
								"url": {
									"raw": "{{opencell.url}}/customFieldTemplate/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"customFieldTemplate",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "CF_SEL_PAY_AMOUNT_THRESHOLD",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\n            \"code\":\"CF_SEL_PAY_AMOUNT_THRESHOLD\",\n            \"description\":\"Seuil de prélèvementt\",\n            \"appliesTo\": \"Seller\",\n            \"fieldType\":\"DOUBLE\",\n            \"storageType\":\"SINGLE\",\n            \"valueRequired\":false,\n            \"versionable\":false,\n            \"allowEdit\":true,\n            \"hideOnNew\":false,\n            \"guiPosition\": \"tab:Paiement;field:0\"\n         }"
								},
								"url": {
									"raw": "{{opencell.url}}/customFieldTemplate/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"customFieldTemplate",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "CF_SUB_SF_DATA",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\n            \"code\":\"CF_SUB_SF_DATA\",\n            \"description\":\"Données contrat sur salesForce\",\n            \"appliesTo\": \"Subscription\",\n            \"fieldType\":\"STRING\",\n            \"storageType\":\"MAP\",\n            \"valueRequired\":false,\n            \"versionable\":false,\n            \"allowEdit\":false,\n            \"hideOnNew\":false,\n            \"guiPosition\": \"tab:SalesForce;field:0\"\n         }"
								},
								"url": {
									"raw": "{{opencell.url}}/customFieldTemplate/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"customFieldTemplate",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "CF_SUB_DATE_INSTALL",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\n            \"code\":\"CF_SUB_DATE_INSTALL\",\n            \"description\":\"Date installation\",\n            \"appliesTo\": \"Subscription\",\n            \"fieldType\":\"DATE\",\n            \"storageType\":\"SINGLE\",\n            \"valueRequired\":false,\n            \"versionable\":false,\n            \"allowEdit\":false,\n            \"hideOnNew\":false,\n            \"guiPosition\": \"tab:SalesForce;field:0\"\n         }"
								},
								"url": {
									"raw": "{{opencell.url}}/customFieldTemplate/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"customFieldTemplate",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "CF_SUB_PAY_METHOD",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\n            \"code\":\"CF_SUB_PAY_METHOD\",\n            \"description\":\"Mode de paiement\",\n            \"appliesTo\": \"Subscription\",\n            \"fieldType\":\"STRING\",\n            \"storageType\":\"SINGLE\",\n            \"valueRequired\":false,\n            \"versionable\":false,\n            \"allowEdit\":false,\n            \"hideOnNew\":false,\n            \"guiPosition\": \"tab:SalesForce;field:0\"\n         }"
								},
								"url": {
									"raw": "{{opencell.url}}/customFieldTemplate/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"customFieldTemplate",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "CF_SUB_REF_MATS",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\n            \"code\":\"CF_SUB_REF_MATS\",\n            \"description\":\"Référence matériels\",\n            \"appliesTo\": \"Subscription\",\n            \"fieldType\":\"STRING\",\n            \"storageType\":\"MAP\",\n            \"valueRequired\":false,\n            \"versionable\":false,\n            \"allowEdit\":false,\n            \"hideOnNew\":false,\n            \"guiPosition\": \"tab:SalesForce;field:1\"\n         }"
								},
								"url": {
									"raw": "{{opencell.url}}/customFieldTemplate/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"customFieldTemplate",
										"createOrUpdate"
									]
								}
							},
							"response": []
						}
					]
				},
				{
					"name": "Sellers",
					"item": [
						{
							"name": "EKKO",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\n  \"code\": \"EKKO\",\n  \"description\": \"Mon Pilotage Elec\",\n  \"currencyCode\": \"EUR\",\n  \"countryCode\": \"FR\",\n  \"languageCode\": \"FRA\",\n  \"address\": {\n    \"address1\": \"1 Place Samuel Champlain\",\n    \"address2\": \"Paris La Défense Cedex\",\n    \"zipCode\": 92930,\n    \"city\": \"Courbevoie\",\n    \"country\": \"FR\"\n  }\n,\n\t\"customFields\": {\n\t\t\"customField\": [\t\t\t\n\t\t\t{\n\t\t\t\t\"code\": \"CF_SEL_INV_NB_BUSI_DAYS\",\n\t\t\t\t\"longValue\": 5\n\t\t\t},\n            {\n\t\t\t\t\"code\": \"CF_SEL_PAY_NB_BUSI_DAYS\",\n\t\t\t\t\"longValue\": 10\n\t\t\t},\n            {\n\t\t\t\t\"code\": \"CF_SEL_SEPA_NB_BUSI_DAYS\",\n\t\t\t\t\"longValue\": 5\n\t\t\t},\n            {\n\t\t\t\t\"code\": \"CF_SEL_PAY_AMOUNT_THRESHOLD\",\n\t\t\t\t\"doubleValue\": 1\n\t\t\t}\n\n            \n\n\t\t]\n\t}\n}"
								},
								"url": {
									"raw": "{{opencell.url}}/seller/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"seller",
										"createOrUpdate"
									]
								}
							},
							"response": []
						}
					]
				},
				{
					"name": "Calendars",
					"item": [
						{
							"name": "MENSUEL",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\n    \"code\": \"MENSUEL\",\n    \"description\": \"1St Monthly\",\n    \"calendarType\":\"YEARLY\",\n    \"days\":[\n        {\"day\":1,\"month\":\"JANUARY\"},\n        {\"day\":1,\"month\":\"FEBRUARY\"},\n        {\"day\":1,\"month\":\"MARCH\"},\n        {\"day\":1,\"month\":\"APRIL\"},\n        {\"day\":1,\"month\":\"MAY\"},\n        {\"day\":1,\"month\":\"JUNE\"},\n        {\"day\":1,\"month\":\"JULY\"},\n        {\"day\":1,\"month\":\"AUGUST\"},\n        {\"day\":1,\"month\":\"SEPTEMBER\"},\n        {\"day\":1,\"month\":\"OCTOBER\"},\n         {\"day\":1,\"month\":\"NOVEMBER\"},\n          {\"day\":1,\"month\":\"DECEMBER\"}\n    ]\n}"
								},
								"url": {
									"raw": "{{opencell.url}}/calendar/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"calendar",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "FR_BANKING_2021",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\n    \"code\": \"FR_BANKING_2021\",\n    \"description\": \"Jours Fériés France 2021\",\n    \"calendarType\":\"BANKING\",\n    \"startDate\":\"2021-01-01\",\n    \"endDate\":\"2021-12-31\",\n    \"weekendBegin\":6,\n    \"weekendEnd\" : 7,\n    \"holidays\":[\n        {\"holidayBegin\":101,\"holidayEnd\":101},\n        {\"holidayBegin\":405,\"holidayEnd\":405},\n         {\"holidayBegin\":501,\"holidayEnd\":501},\n         {\"holidayBegin\":508,\"holidayEnd\":508},\n         {\"holidayBegin\":513,\"holidayEnd\":513},\n         {\"holidayBegin\":524,\"holidayEnd\":524},\n         {\"holidayBegin\":714,\"holidayEnd\":714},\n         {\"holidayBegin\":815,\"holidayEnd\":815},\n         {\"holidayBegin\":1101,\"holidayEnd\":1101},\n         {\"holidayBegin\":1111,\"holidayEnd\":1111},\n         {\"holidayBegin\":1225,\"holidayEnd\":1225}\n\n    ]\n}"
								},
								"url": {
									"raw": "{{opencell.url}}/calendar/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"calendar",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "FR_BANKING_2022",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\n    \"code\": \"FR_BANKING_2022\",\n    \"description\": \"Jours Fériés France 2022\",\n    \"calendarType\":\"BANKING\",\n    \"startDate\":\"2022-01-01\",\n    \"endDate\":\"2022-12-31\",\n    \"weekendBegin\":6,\n    \"weekendEnd\" : 7,\n    \"holidays\":[\n        {\"holidayBegin\":101,\"holidayEnd\":101},\n        {\"holidayBegin\":418,\"holidayEnd\":418},\n         {\"holidayBegin\":501,\"holidayEnd\":501},\n         {\"holidayBegin\":508,\"holidayEnd\":508},\n         {\"holidayBegin\":526,\"holidayEnd\":526},\n         {\"holidayBegin\":606,\"holidayEnd\":606},\n         {\"holidayBegin\":714,\"holidayEnd\":714},\n         {\"holidayBegin\":815,\"holidayEnd\":815},\n         {\"holidayBegin\":1101,\"holidayEnd\":1101},\n         {\"holidayBegin\":1111,\"holidayEnd\":1111},\n         {\"holidayBegin\":1225,\"holidayEnd\":1225}\n\n    ]\n}"
								},
								"url": {
									"raw": "{{opencell.url}}/calendar/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"calendar",
										"createOrUpdate"
									]
								}
							},
							"response": []
						}
					]
				},
				{
					"name": "Billing",
					"item": [
						{
							"name": "AOsTemplate",
							"item": [
								{
									"name": "INV_STD",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "test",
												"value": "test"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"code\": \"INV_STD\",\n    \"description\": \"Standard invoice sub-item\",\n    \"occCategory\": \"DEBIT\",\n    \"accountingCode\": \"411120\"\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/occTemplate/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"occTemplate",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "PAY_DDT",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "test",
												"value": "test"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"code\": \"PAY_DDT\",\n    \"description\": \"Payment DirectDebit\",\n    \"occCategory\": \"CREDIT\",\n    \"accountingCode\": \"445710\"\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/occTemplate/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"occTemplate",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "REJ_DDT",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "test",
												"value": "test"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"code\": \"REJ_DDT\",\n    \"description\": \"Rejected payment - direct debit\",\n    \"occCategory\": \"DEBIT\",\n    \"accountingCode\": \"706800\"\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/occTemplate/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"occTemplate",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						},
						{
							"name": "Invoice types",
							"item": [
								{
									"name": "REC_SEQ",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "test",
												"value": "test"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"code\": \"REC_SEQ\",\n    \"description\": \"Ekko séquence facture récurrente\",\n    \"sequenceSize\": 11,\n    \"currentInvoiceNb\": 0\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceSequence/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceSequence",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "UPF_SEQ",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "test",
												"value": "test"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"code\": \"UPF_SEQ\",\n    \"description\": \"Ekko séquence facture Upfront\",\n    \"sequenceSize\": 11,\n    \"currentInvoiceNb\": 0\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceSequence/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceSequence",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "REC",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "test",
												"value": "test"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"code\": \"REC\",\n    \"description\": \"Ekko facture récurrente\",\n    \"occTemplateCode\": \"INV_STD\",\n    \"occTemplateNegativeCode\": \"INV_CRN\",\n      \"billingTemplateName\":\"REC\",\n    \"customInvoiceXmlScriptInstanceCode\":\"com.opencellsoft.service.ekko.invoicing.InvoiceXmlScript\",\n    \"sequenceDto\": {\n    \t\"prefixEL\": \"5\",    \n        \"invoiceSequenceCode\": \"REC_SEQ\"\n    },\n    \"matchingAuto\": false,\n    \"billingTemplateNameEL\": \"\",\n    \"useSelfSequence\": false,\n    \"sellerSequence\": {}\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceType/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceType",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "UPF",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "test",
												"value": "test"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n    \"code\": \"UPF\",\n    \"description\": \"Ekko facture Upfront\",\n    \"occTemplateCode\": \"INV_STD\",\n    \"occTemplateNegativeCode\": \"INV_CRN\",\n    \"billingTemplateName\":\"UPF\",\n     \"customInvoiceXmlScriptInstanceCode\":\"com.opencellsoft.service.ekko.invoicing.InvoiceXmlScript\",\n    \"sequenceDto\": {\n    \t\"prefixEL\": \"5\",    \n        \"invoiceSequenceCode\": \"REC_SEQ\"\n    },\n    \"matchingAuto\": false,\n    \"billingTemplateNameEL\": \"\",\n    \"useSelfSequence\": false,\n    \"sellerSequence\": {}\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceType/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceType",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						},
						{
							"name": "Billing cycles",
							"item": [
								{
									"name": "MENSUEL",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n  \"code\": \"MENSUEL\",\n  \"type\": \"SUBSCRIPTION\",\n  \"description\": \"Mensuel\",\n  \"invoiceDateDelay\": \"0\",\n  \"dueDateDelayEL\": \"#{mv:executeScript(entity, 'com.opencellsoft.service.ekko.invoicing.DueDateScript', '')}\",\n  \"invoiceDateProductionDelay\": \"0\",\n  \"calendar\": \"MENSUEL\",  \n  \"scriptInstanceCode\":\"com.opencellsoft.service.ekko.invoicing.EkkoBillingCycleScript\"\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/billingCycle/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"billingCycle",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "NO INVOICING",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\n  \"code\": \"NO_INVOICING\",\n  \"type\": \"SUBSCRIPTION\",\n  \"description\": \"Pas de facturation\",\n  \"invoiceDateDelay\": \"0\",\n  \"dueDateDelayEL\": \"0\",\n  \"invoiceDateProductionDelay\": \"0\",\n  \"calendar\": \"MENSUEL\"\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/billingCycle/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"billingCycle",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						},
						{
							"name": "Categories",
							"item": [
								{
									"name": "ICAT_EKKO_INSTALL",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{ \n  \"code\": \"ICAT_EKKO_INSTALL\",\n  \"description\": \"Instalation\"\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceCategory/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceCategory",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "ICAT_EKKO_MATERIEL",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{ \n  \"code\": \"ICAT_EKKO_MATERIEL\",\n  \"description\": \"Vente\"\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceCategory/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceCategory",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "ICAT_EKKO_ABO",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{ \n  \"code\": \"ICAT_EKKO_ABO\",\n  \"description\": \"Abonnement\"\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceCategory/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceCategory",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						},
						{
							"name": "Sub categories",
							"item": [
								{
									"name": "ISCAT_EKKO_INSTALL",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n\t\"code\": \"ISCAT_EKKO_INSTALL\",\r\n\t\"description\": \"Instalation\",\r\n\t\"invoiceCategory\": \"ICAT_EKKO_INSTALL\",\r\n\t\"accountingCode\": \"706260\"\r\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceSubCategory/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceSubCategory",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "ISCAT_EKKO_INSTALL_REMISE",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n\t\"code\": \"ISCAT_EKKO_INSTALL_REMISE\",\r\n\t\"description\": \"Instalation Remise\",\r\n\t\"invoiceCategory\": \"ICAT_EKKO_INSTALL\",\r\n\t\"accountingCode\": \"709300\"\r\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceSubCategory/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceSubCategory",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "ISCAT_EKKO_INSTALL_GEST",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n\t\"code\": \"ISCAT_EKKO_INSTALL_GEST\",\r\n\t\"description\": \"Geste commercial\",\r\n\t\"invoiceCategory\": \"ICAT_EKKO_INSTALL\",\r\n\t\"accountingCode\": \"709300\"\r\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceSubCategory/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceSubCategory",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "ISCAT_EKKO_MAT_VENTE",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n\t\"code\": \"ISCAT_EKKO_MAT_VENTE\",\r\n\t\"description\": \"Vente matériel\",\r\n\t\"invoiceCategory\": \"ICAT_EKKO_MATERIEL\",\r\n\t\"accountingCode\": \"706260\"\r\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceSubCategory/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceSubCategory",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "ISCAT_EKKO_MAT_REMISE",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n\t\"code\": \"ISCAT_EKKO_MAT_REMISE\",\r\n\t\"description\": \"Remise matériel\",\r\n\t\"invoiceCategory\": \"ICAT_EKKO_MATERIEL\",\r\n\t\"accountingCode\": \"709300\"\r\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceSubCategory/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceSubCategory",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "ISCAT_EKKO_DEEE",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n\t\"code\": \"ISCAT_EKKO_DEEE\",\r\n\t\"description\": \"Eco-participations DEEE\",\r\n\t\"invoiceCategory\": \"ICAT_EKKO_MATERIEL\",\r\n\t\"accountingCode\": \"706260\"\r\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceSubCategory/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceSubCategory",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "ISCAT_EKKO_DEEE_REMISE",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n\t\"code\": \"ISCAT_EKKO_DEEE_REMISE\",\r\n\t\"description\": \"Remise eco-participations DEEE\",\r\n\t\"invoiceCategory\": \"ICAT_EKKO_MATERIEL\",\r\n\t\"accountingCode\": \"709300\"\r\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceSubCategory/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceSubCategory",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "ISCAT_EKKO_ABO",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n\t\"code\": \"ISCAT_EKKO_ABO\",\r\n\t\"description\": \"Abonnement EKKO\",\r\n\t\"invoiceCategory\": \"ICAT_EKKO_ABO\",\r\n\t\"accountingCode\": \"706800\"\r\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceSubCategory/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceSubCategory",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "ISCAT_EKKO_ABO_REMISE",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n\t\"code\": \"ISCAT_EKKO_ABO_REMISE\",\r\n\t\"description\": \"Remise abonnement EKKO\",\r\n\t\"invoiceCategory\": \"ICAT_EKKO_ABO\",\r\n\t\"accountingCode\": \"709300\"\r\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceSubCategory/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceSubCategory",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "ISCAT_EKKO_ABO_GEST",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n\t\"code\": \"ISCAT_EKKO_ABO_GEST\",\r\n\t\"description\": \"Geste commercial abonnement\",\r\n\t\"invoiceCategory\": \"ICAT_EKKO_ABO\",\r\n\t\"accountingCode\": \"709300\"\r\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/invoiceSubCategory/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"invoiceSubCategory",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						}
					]
				},
				{
					"name": "Provider",
					"item": [
						{
							"name": "EKKO",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\n\t\"code\": \"EKKO\",\n\t\"description\": \"Mon Pilotage Elec\",\n\t\"enterprise\": \"true\",\n\t\"rounding\": \"2\",\n\t\"invoiceRounding\": \"2\",\n    \"invoiceRoundingMode\":\"DOWN\",\n\t\"invoiceConfiguration\": {\n\t\t\"displaySubscriptions\": \"true\",\n\t\t\"displayServices\": \"true\",\n\t\t\"displayOffers\": \"true\",\n\t\t\"displayEdrs\": \"false\",\n\t\t\"displayProvider\": \"true\",\n\t\t\"displayCfAsXML\": \"true\",\n\t\t\"displayPricePlans\": \"true\",\n\t\t\"displayDetail\": \"true\",\n\t\t\"displayChargesPeriods\": \"true\",\n\t\t\"displayFreeTransacInInvoice\": \"false\",\n\t\t\"displayBillingCycle\": \"false\",\n\t\t\"displayOrders\": \"false\"\n\t},\n    \"bankCoordinates\":{\n        \"iban\":\"FR7630004013280001323623704\",\n        \"bic\" :\"BNPAFRPPXXX\",\n        \"ics\":\"FRXXZZZ123456\",\n        \"bankId\":\"BNP\",\n        \"bankCode\":\"\",\n        \"accountNumber\":\"\",\n        \"issuerNumber\":\"\"\n\n    }\n}"
								},
								"url": {
									"raw": "{{opencell.url}}/provider/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"provider",
										"createOrUpdate"
									]
								}
							},
							"response": []
						}
					]
				}
			],
			"event": [
				{
					"listen": "prerequest",
					"script": {
						"type": "text/javascript",
						"exec": [
							""
						]
					}
				},
				{
					"listen": "test",
					"script": {
						"type": "text/javascript",
						"exec": [
							""
						]
					}
				}
			]
		},
		{
			"name": "Catalog",
			"item": [
				{
					"name": "Charges",
					"item": [
						{
							"name": "OneShot",
							"item": [
								{
									"name": "CH_OS_EKKO_INSTALL",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n    \"code\": \"CH_OS_EKKO_INSTALL\",\r\n    \"description\": \"Installation\",\r\n    \"disabled\": false,\r\n    \"invoiceSubCategory\": \"ISCAT_EKKO_INSTALL\",\r\n    \"amountEditable\": true,\r\n    \"unitNbDecimal\": 12,\r\n    \"roundingModeDtoEnum\": \"NEAREST\",\r\n    \"taxClassCode\": \"TVA_55\",\r\n    \"dropZeroWo\": false,\r\n    \"oneShotChargeTemplateType\": \"OTHER\",\r\n    \"immediateInvoicing\": false\r\n}"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/oneShotChargeTemplate/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"oneShotChargeTemplate",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "CH_OS_EKKO_REM_INST",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "\r\n{\r\n    \"code\": \"CH_OS_EKKO_REM_INST\",\r\n    \"description\": \"Remise sur installation\",\r\n    \"disabled\": false,\r\n    \"invoiceSubCategory\": \"ISCAT_EKKO_INSTALL_REMISE\",\r\n    \"amountEditable\": true,\r\n    \"unitNbDecimal\": 12,\r\n    \"roundingModeDtoEnum\": \"NEAREST\",\r\n    \"taxClassCode\": \"TVA_55\",\r\n    \"dropZeroWo\": false,\r\n    \"oneShotChargeTemplateType\": \"OTHER\",\r\n    \"immediateInvoicing\": false\r\n}\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/oneShotChargeTemplate/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"oneShotChargeTemplate",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "CH_OS_EKKO_GEST_INST",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n    \"code\": \"CH_OS_EKKO_GEST_INST\",\r\n    \"description\": \"Geste commercial suite à pb à l’installation\",\r\n    \"disabled\": false,\r\n    \"invoiceSubCategory\": \"ISCAT_EKKO_INSTALL_GEST\",\r\n    \"amountEditable\": true,\r\n    \"unitNbDecimal\": 12,\r\n    \"roundingModeDtoEnum\": \"NEAREST\",\r\n    \"taxClassCode\": \"TVA_55\",\r\n    \"dropZeroWo\": false,\r\n    \"oneShotChargeTemplateType\": \"OTHER\",\r\n    \"immediateInvoicing\": false\r\n}\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/oneShotChargeTemplate/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"oneShotChargeTemplate",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "CH_OS_EKKO_DEEE",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n    \"code\": \"CH_OS_EKKO_DEEE\",\r\n    \"description\": \"Eco-participation DEEE\",\r\n    \"disabled\": false,\r\n    \"invoiceSubCategory\": \"ISCAT_EKKO_DEEE\",\r\n    \"amountEditable\": true,\r\n    \"unitNbDecimal\": 12,\r\n    \"roundingModeDtoEnum\": \"NEAREST\",\r\n    \"taxClassCode\": \"TVA_20\",\r\n    \"dropZeroWo\": false,\r\n    \"oneShotChargeTemplateType\": \"OTHER\",\r\n    \"immediateInvoicing\": false\r\n}\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/oneShotChargeTemplate/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"oneShotChargeTemplate",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "CF_OS_EKKO_REM_DEEE",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n    \"code\": \"CH_OS_EKKO_REM_DEEE\",\r\n    \"description\": \"Remise sur Eco-participation DEEE\",\r\n    \"disabled\": false,\r\n    \"invoiceSubCategory\": \"ISCAT_EKKO_DEEE_REMISE\",\r\n    \"amountEditable\": true,\r\n    \"unitNbDecimal\": 12,\r\n    \"roundingModeDtoEnum\": \"NEAREST\",\r\n    \"taxClassCode\": \"TVA_20\",\r\n    \"dropZeroWo\": false,\r\n    \"oneShotChargeTemplateType\": \"OTHER\",\r\n    \"immediateInvoicing\": false\r\n}\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/oneShotChargeTemplate/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"oneShotChargeTemplate",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "CH_OS_EKKO_MATERIEL",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n    \"code\": \"CH_OS_EKKO_MATERIEL\",\r\n    \"description\": \"Materiel\",\r\n    \"disabled\": false,\r\n    \"invoiceSubCategory\": \"ISCAT_EKKO_MAT_VENTE\",\r\n    \"amountEditable\": true,\r\n    \"unitNbDecimal\": 12,\r\n    \"roundingModeDtoEnum\": \"NEAREST\",\r\n    \"taxClassCode\": \"TVA_55\",\r\n    \"dropZeroWo\": false,\r\n    \"oneShotChargeTemplateType\": \"OTHER\",\r\n    \"immediateInvoicing\": false\r\n}\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/oneShotChargeTemplate/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"oneShotChargeTemplate",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "CH_OS_EKKO_REM_MAT",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n    \"code\": \"CH_OS_EKKO_REM_MAT\",\r\n    \"description\": \"Remise sur materiel\",\r\n    \"disabled\": false,\r\n    \"invoiceSubCategory\": \"ISCAT_EKKO_MAT_REMISE\",\r\n    \"amountEditable\": true,\r\n    \"unitNbDecimal\": 12,\r\n    \"roundingModeDtoEnum\": \"NEAREST\",\r\n    \"taxClassCode\": \"TVA_55\",\r\n    \"dropZeroWo\": false,\r\n    \"oneShotChargeTemplateType\": \"OTHER\",\r\n    \"immediateInvoicing\": false\r\n}\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/oneShotChargeTemplate/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"oneShotChargeTemplate",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "CH_OS_EKKO_GEST_ABO",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n    \"code\": \"CH_OS_EKKO_GEST_ABO\",\r\n    \"description\": \"Geste commercial abonnement\",\r\n    \"disabled\": false,\r\n    \"invoiceSubCategory\": \"ISCAT_EKKO_ABO_GEST\",\r\n    \"amountEditable\": true,\r\n    \"unitNbDecimal\": 12,\r\n    \"roundingModeDtoEnum\": \"NEAREST\",\r\n    \"taxClassCode\": \"TVA_20\",\r\n    \"dropZeroWo\": false,\r\n    \"oneShotChargeTemplateType\": \"OTHER\",\r\n    \"immediateInvoicing\": false\r\n}\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/oneShotChargeTemplate/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"oneShotChargeTemplate",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						},
						{
							"name": "Recurring",
							"item": [
								{
									"name": "CH_REC_EKKO_ABO",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n\t\"code\": \"CH_REC_EKKO_ABO\",\r\n\t\"description\": \"Service Abonnement\",\r\n\t\"invoiceSubCategory\": \"ISCAT_EKKO_ABO\",\r\n\t\"disabled\": false,\r\n    \"amountEditable\": true,\r\n\t\"unitNbDecimal\": 12,\r\n\t\"roundingModeDtoEnum\": \"NEAREST\",\r\n\t\"calendar\": \"MENSUEL\",\r\n\t\"subscriptionProrata\": false,\r\n\t\"terminationProrata\": false,\r\n\t\"applyInAdvance\": true,\r\n\t\"taxClassCode\": \"TVA_20\"\r\n\t}\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/recurringChargeTemplate/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"recurringChargeTemplate",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "CH_REC_EKKO_ABO_REM",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n\t\"code\": \"CH_REC_EKKO_ABO_REM\",\r\n\t\"description\": \"Prestation de services Remises\",\r\n\t\"invoiceSubCategory\": \"ISCAT_EKKO_ABO_REMISE\",\r\n\t\"disabled\": false,\r\n    \"amountEditable\": true,\r\n\t\"unitNbDecimal\": 12,\r\n\t\"roundingModeDtoEnum\": \"NEAREST\",\r\n\t\"calendar\": \"MENSUEL\",\r\n\t\"subscriptionProrata\": false,\r\n\t\"terminationProrata\": false,\r\n\t\"applyInAdvance\": false,\r\n\t\"taxClassCode\": \"TVA_20\"\r\n\t}\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/recurringChargeTemplate/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"recurringChargeTemplate",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						}
					]
				},
				{
					"name": "PricesPlans",
					"item": [
						{
							"name": "OneShot",
							"item": [
								{
									"name": "PP_CH_OS_EKKO_INSTALL",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n  \"code\": \"PP_CH_OS_EKKO_INSTALL\",\r\n  \"eventCode\": \"CH_OS_EKKO_INSTALL\",\r\n  \"amountWithoutTax\": -1,\r\n  \"priority\": 1,\r\n  \"criteriaEL\" : null\r\n}\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/pricePlan/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"pricePlan",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "PP_ CH_OS_EKKO_REM_INST",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n  \"code\": \"PP_CH_OS_EKKO_REM_INST\",\r\n  \"eventCode\": \"CH_OS_EKKO_REM_INST\",\r\n  \"amountWithoutTax\": -1,\r\n  \"priority\": 1,\r\n  \"criteriaEL\" : null\r\n}\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/pricePlan/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"pricePlan",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "PP_CH_OS_EKKO_DEEE",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n  \"code\": \"PP_CH_OS_EKKO_DEEE\",\r\n  \"eventCode\": \"CH_OS_EKKO_DEEE\",\r\n  \"amountWithoutTax\": -1,\r\n  \"priority\": 1,\r\n  \"criteriaEL\" : null\r\n}\r\n\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/pricePlan/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"pricePlan",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "PP_CH_OS_EKKO_REM_DEEE",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n  \"code\": \"PP_CH_OS_EKKO_REM_DEEE\",\r\n  \"eventCode\": \"CH_OS_EKKO_REM_DEEE\",\r\n  \"amountWithoutTax\": -1,\r\n  \"priority\": 1,\r\n  \"criteriaEL\" : null\r\n}\r\n\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/pricePlan/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"pricePlan",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "PP_CH_OS_EKKO_MATERIEL",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n  \"code\": \"PP_CH_OS_EKKO_MATERIEL\",\r\n  \"eventCode\": \"CH_OS_EKKO_MATERIEL\",\r\n  \"amountWithoutTax\": -1,\r\n  \"priority\": 1,\r\n  \"criteriaEL\" : null\r\n}\r\n\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/pricePlan/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"pricePlan",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "PP_CH_OS_EKKO_GEST",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n  \"code\": \"PP_CH_OS_EKKO_GEST_INST\",\r\n  \"eventCode\": \"CH_OS_EKKO_GEST_INST\",\r\n  \"amountWithoutTax\": -1,\r\n  \"priority\": 1,\r\n  \"criteriaEL\" : null\r\n}\r\n\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/pricePlan/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"pricePlan",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "PP_CH_OS_EKKO_REM_MAT",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n  \"code\": \"PP_CH_OS_EKKO_REM_MAT\",\r\n  \"eventCode\": \"CH_OS_EKKO_REM_MAT\",\r\n  \"amountWithoutTax\": -1, \r\n  \"priority\": 1,\r\n  \"criteriaEL\" : null\r\n}\r\n\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/pricePlan/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"pricePlan",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "PP_CH_OS_EKKO_GEST_ABO",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n  \"code\": \"PP_CH_OS_EKKO_GEST_ABO\",\r\n  \"eventCode\": \"CH_OS_EKKO_GEST_ABO\",\r\n  \"amountWithoutTax\": -1, \r\n  \"priority\": 1,\r\n  \"criteriaEL\" : null\r\n}\r\n\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/pricePlan/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"pricePlan",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						},
						{
							"name": "Recurring",
							"item": [
								{
									"name": "PP_CH_REC_EKKO_ABO",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n  \"code\": \"PP_CH_REC_EKKO_ABO\",\r\n  \"eventCode\": \"CH_REC_EKKO_ABO\",\r\n  \"amountWithoutTax\": 1\r\n}\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/pricePlan/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"pricePlan",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "PP_CH_REC_EKKO_ABO_REM",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n  \"code\": \"PP_CH_REC_EKKO_ABO_REM\",\r\n  \"eventCode\": \"CH_REC_EKKO_ABO_REM\",\r\n  \"amountWithoutTax\": -0.5,\r\n  \"criteriaEL\" : null\r\n}\r\n"
										},
										"url": {
											"raw": "{{opencell.url}}/catalog/pricePlan/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"catalog",
												"pricePlan",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						}
					]
				},
				{
					"name": "Services",
					"item": [
						{
							"name": "CFs",
							"item": [
								{
									"name": "CF_SUB_PRICES",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n            \"code\":\"CF_SUB_PRICES\",\r\n            \"description\":\"Prices\",\r\n            \"appliesTo\": \"Subscription\",\r\n            \"fieldType\":\"DOUBLE\",\r\n            \"storageType\":\"MAP\",\r\n            \"valueRequired\":false,\r\n            \"versionable\":false,\r\n            \"allowEdit\":false,\r\n            \"hideOnNew\":false,\r\n            \"guiPosition\": \"tab:Prix;field:1\"\r\n         }"
										},
										"url": {
											"raw": "{{opencell.url}}/customFieldTemplate/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"customFieldTemplate",
												"createOrUpdate"
											]
										}
									},
									"response": []
								},
								{
									"name": "CF_SUB_LABELS",
									"event": [
										{
											"listen": "test",
											"script": {
												"exec": [
													"pm.test(\"Successful request\", () => {",
													"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
													"});",
													"",
													""
												],
												"type": "text/javascript"
											}
										}
									],
									"request": {
										"method": "POST",
										"header": [
											{
												"key": "Content-Type",
												"value": "application/json"
											},
											{
												"key": "Authorization",
												"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
											}
										],
										"body": {
											"mode": "raw",
											"raw": "{\r\n            \"code\":\"CF_SUB_LABELS\",\r\n            \"description\":\"Labels\",\r\n            \"appliesTo\": \"Subscription\",\r\n            \"fieldType\":\"STRING\",\r\n            \"storageType\":\"MAP\",\r\n            \"valueRequired\":false,\r\n            \"versionable\":false,\r\n            \"allowEdit\":false,\r\n            \"hideOnNew\":false,\r\n            \"guiPosition\": \"tab:Prix;field:2\"\r\n         }"
										},
										"url": {
											"raw": "{{opencell.url}}/customFieldTemplate/createOrUpdate",
											"host": [
												"{{opencell.url}}"
											],
											"path": [
												"customFieldTemplate",
												"createOrUpdate"
											]
										}
									},
									"response": []
								}
							]
						},
						{
							"name": "SE_EKKO_ABO",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\n    \"code\": \"SE_EKKO_ABO\",\n    \"description\": \"Service abonnement EKKO\",\n    \"mandatory\": false,\t\n    \"serviceChargeTemplateRecurrings\": {\n        \"serviceChargeTemplateRecurring\": [\n            {\n                \"code\": \"CH_REC_EKKO_ABO\"\n            }\n        ]\n    }\n}\n\n"
								},
								"url": {
									"raw": "{{opencell.url}}/catalog/serviceTemplate/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"catalog",
										"serviceTemplate",
										"createOrUpdate"
									]
								}
							},
							"response": []
						},
						{
							"name": "SE_EKKO_ABO_REM",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46b3BlbmNlbGwuYWRtaW4="
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\n    \"code\": \"SE_EKKO_ABO_REM\",\n    \"description\": \"Service abonnement remise EKKO\",\n    \"mandatory\": false,\t\n    \"serviceChargeTemplateRecurrings\": {\n        \"serviceChargeTemplateRecurring\": [\n            {\n                \"code\": \"CH_REC_EKKO_ABO_REM\"\n            }\n        ]\n    }\n}"
								},
								"url": {
									"raw": "{{opencell.url}}/catalog/serviceTemplate/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"catalog",
										"serviceTemplate",
										"createOrUpdate"
									]
								}
							},
							"response": []
						}
					]
				},
				{
					"name": "Offers",
					"item": [
						{
							"name": "OF_EKKO",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											"pm.test(\"Successful request\", () => {",
											"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
											"});",
											"",
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [
									{
										"key": "Content-Type",
										"value": "application/json"
									},
									{
										"key": "Authorization",
										"value": "Basic b3BlbmNlbGwuYWRtaW46aFViNTJBTTNDZSEh"
									}
								],
								"body": {
									"mode": "raw",
									"raw": "{\r\n    \"code\": \"OF_EKKO\",\r\n    \"description\": \"Engie EKKO\",\r\n    \"lifeCycleStatus\": \"ACTIVE\",\t\r\n    \"globalRatingScriptInstance\":\"com.opencellsoft.service.ekko.rating.EkkoRatingScript\",\r\n    \"seller\": [\r\n            \"EKKO\"\r\n    ],\r\n    \"offerServiceTemplate\": [\r\n        {\"serviceTemplate\":{\"code\": \"SE_EKKO_ABO\" }},\r\n        {\"serviceTemplate\":{\"code\": \"SE_EKKO_ABO_REM\" }}]\t\r\n}"
								},
								"url": {
									"raw": "{{opencell.url}}/catalog/offerTemplate/createOrUpdate",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"catalog",
										"offerTemplate",
										"createOrUpdate"
									]
								}
							},
							"response": []
						}
					]
				}
			]
		},
		{
			"name": "Sepa_Pain08_Camt54",
			"item": [
				{
					"name": "Create Sepa DDRequestBuilder",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Successful request\", () => {",
									"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
									"});",
									"",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							},
							{
								"key": "Proxy-Authorization",
								"type": "text",
								"value": "{{proxy.auth}}"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"code\": \"EKKO_Sepa_Pain08_Camt54\",\r\n    \"description\": \"Ekko Format sepa Pain08 and Camt54\",\r\n    \"type\" : \"CUSTOM\" , \r\n    \"scriptInstanceCode\" : \"com.opencellsoft.service.ekko.payment.SepaDDRequestBuilderScript\", \r\n    \"paymentLevel\" : \"CA\"\r\n    \r\n}"
						},
						"url": {
							"raw": "{{opencell.url}}/payment/ddRequestBuilder/createOrUpdate",
							"host": [
								"{{opencell.url}}"
							],
							"path": [
								"payment",
								"ddRequestBuilder",
								"createOrUpdate"
							]
						}
					},
					"response": []
				},
				{
					"name": "Create DDRequestLotOp",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Successful request\", () => {",
									"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
									"});",
									"",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							},
							{
								"key": "Proxy-Authorization",
								"value": "{{proxy.auth}}",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"recurrent\": true,\r\n    \"fromDueDate\" : \"2000-01-01\",\r\n    \"toDueDate\" : \"2999-01-01\",\r\n    \"ddRequestBuilderCode\" : \"EKKO_Sepa_Pain08_Camt54\",\r\n    \"dueDateRageScriptCode\" : \"com.opencellsoft.service.ekko.payment.PaymentEkkoDateRangeScript\"\r\n}"
						},
						"url": {
							"raw": "{{opencell.url}}/payment/ddrequestLotOp",
							"host": [
								"{{opencell.url}}"
							],
							"path": [
								"payment",
								"ddrequestLotOp"
							]
						}
					},
					"response": []
				},
				{
					"name": "Create SEPA_CAMT54_JOB",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Successful request\", () => {",
									"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
									"});",
									"",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							},
							{
								"key": "Proxy-Authorization",
								"type": "text",
								"value": "{{proxy.auth}}"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"code\": \"EKKO_Reject_SDD_JOB\",\r\n    \"description\": \"EKKO Camt054 Reject Sepa DD Job\",\r\n    \"jobCategory\": \"PAYMENT\",\r\n    \"jobTemplate\": \"SepaRejectedTransactionsJob\" , \r\n    \"customFields\" : {\r\n    \t\"customField\": [ \r\n    \t\t{ \"code\":\"RejectSepaJob_ddRequestBuilder\", \r\n    \t\t   \"entityReferenceValue\" : {\r\n    \t\t        \"classname\" : \"org.meveo.model.payments.DDRequestBuilder\" ,\r\n    \t\t        \"code\" : \"EKKO_Sepa_Pain08_Camt54\"\r\n    \t\t   }\r\n    \t\t},\r\n            { \"code\":\"RejectSepaJob_inputDir\", \r\n    \t\t   \"stringValue\" : \"/sepa/ekko/rejet\"\r\n    \t\t},\r\n            { \"code\":\"RejectSepaJob_fileNameExtension\", \r\n    \t\t   \"stringValue\" : \"xml\"\r\n    \t\t},\r\n            { \"code\":\"RejectSepaJob_fileNamePrefix\", \r\n    \t\t   \"stringValue\" : \"camt\"\r\n    \t\t}\r\n\r\n    \t] \r\n    }\r\n}"
						},
						"url": {
							"raw": "{{opencell.url}}/jobInstance/createOrUpdate",
							"host": [
								"{{opencell.url}}"
							],
							"path": [
								"jobInstance",
								"createOrUpdate"
							]
						}
					},
					"response": []
				},
				{
					"name": "Create SEPA_PAIN08_JOB",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Successful request\", () => {",
									"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
									"});",
									"",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							},
							{
								"key": "Proxy-Authorization",
								"value": "{{proxy.auth}}",
								"type": "text"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\r\n    \"code\": \"EKKO_SDD_JOB\",\r\n    \"description\": \"EKKO Pain08 Payment Sepa DD Job\",\r\n    \"jobCategory\": \"PAYMENT\",\r\n    \"jobTemplate\": \"SepaDirectDebitJob\" , \r\n    \"followingJob\": \"EKKO_Reject_SDD_JOB\",\r\n    \"customFields\" : {\r\n    \t\"customField\": [ \r\n    \t\t{ \"code\":\"SepaJob_ddRequestBuilder\", \r\n    \t\t   \"entityReferenceValue\" : {\r\n    \t\t        \"classname\" : \"org.meveo.model.payments.DDRequestBuilder\" ,\r\n    \t\t        \"code\" : \"EKKO_Sepa_Pain08_Camt54\"\r\n    \t\t   }\r\n    \t\t}\r\n    \t] \r\n    }\r\n}"
						},
						"url": {
							"raw": "{{opencell.url}}/jobInstance/createOrUpdate",
							"host": [
								"{{opencell.url}}"
							],
							"path": [
								"jobInstance",
								"createOrUpdate"
							]
						}
					},
					"response": []
				}
			]
		},
		{
			"name": "jobs flow",
			"item": [
				{
					"name": "Timer Daily-2H",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Successful request\", () => {",
									"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
									"});",
									"",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"code\": \"Daily-2H\",\n    \"hour\": \"2\",\n    \"minute\": \"0\",\n    \"second\": \"0\"\n}"
						},
						"url": {
							"raw": "{{opencell.url}}/timerEntity/createOrUpdate",
							"host": [
								"{{opencell.url}}"
							],
							"path": [
								"timerEntity",
								"createOrUpdate"
							]
						}
					},
					"response": []
				},
				{
					"name": "RecurringRatingJob",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Successful request\", () => {",
									"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
									"});",
									"",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n\t\"code\": \"RR_Job\",\n\t\"jobTemplate\": \"RecurringRatingJob\",\n\t\"followingJob\": \"RT_Job\",    \n\t\"timerCode\": \"Daily-2H\"\n}"
						},
						"url": {
							"raw": "{{opencell.url}}/jobInstance/createOrUpdate",
							"host": [
								"{{opencell.url}}"
							],
							"path": [
								"jobInstance",
								"createOrUpdate"
							]
						}
					},
					"response": []
				},
				{
					"name": "RatedTransactionsJob",
					"event": [
						{
							"script": {
								"exec": [
									"pm.test(\"Successful request\", () => {",
									"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
									"});",
									"",
									""
								],
								"type": "text/javascript"
							},
							"listen": "test"
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"value": "application/json",
								"key": "Content-Type"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n\t\"code\": \"RT_Job\",\n\t\"jobTemplate\": \"RatedTransactionsJob\",\n\t\"followingJob\": \"BillingRunJob\"\n}"
						},
						"url": {
							"raw": "{{opencell.url}}/jobInstance/createOrUpdate",
							"host": [
								"{{opencell.url}}"
							],
							"path": [
								"jobInstance",
								"createOrUpdate"
							]
						}
					},
					"response": []
				},
				{
					"name": "BillingRunJob",
					"event": [
						{
							"script": {
								"exec": [
									"pm.test(\"Successful request\", () => {",
									"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
									"});",
									"",
									""
								],
								"type": "text/javascript"
							},
							"listen": "test"
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"value": "application/json",
								"key": "Content-Type"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n\t\"code\": \"BillingRunJob\",\n\t\"jobTemplate\": \"BillingRunJob\",\n\t\"followingJob\": \"Inv_Job\",\n\t\"customFields\": {\n\t\t\"customField\": [\n\t\t\t{\n\t\t\t\t\"code\": \"BillingRunJob_billingRun_Process\",\n\t\t\t\t\"stringValue\": \"3\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"code\": \"BillingRunJob_billingCycle\",\n\t\t\t\t\"fieldType\": \"ENTITY\",\n\t\t\t\t\"value\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"value\": {\n\t\t\t\t\t\t\t\"entityReferenceValue\": {\n\t\t\t\t\t\t\t\t\"classname\": \"org.meveo.model.billing.BillingCycle\",\n\t\t\t\t\t\t\t\t\"code\": \"MENSUEL\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t]\n\t}\n}"
						},
						"url": {
							"raw": "{{opencell.url}}/jobInstance/createOrUpdate",
							"host": [
								"{{opencell.url}}"
							],
							"path": [
								"jobInstance",
								"createOrUpdate"
							]
						}
					},
					"response": []
				},
				{
					"name": "InvoicingJob",
					"event": [
						{
							"script": {
								"exec": [
									"pm.test(\"Successful request\", () => {",
									"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
									"});",
									"",
									""
								],
								"type": "text/javascript"
							},
							"listen": "test"
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"value": "application/json",
								"key": "Content-Type"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n\t\"code\": \"Inv_Job\",\n\t\"jobTemplate\": \"InvoicingJob\",\n\t\"followingJob\": \"XML_Job\"\n}"
						},
						"url": {
							"raw": "{{opencell.url}}/jobInstance/createOrUpdate",
							"host": [
								"{{opencell.url}}"
							],
							"path": [
								"jobInstance",
								"createOrUpdate"
							]
						}
					},
					"response": []
				},
				{
					"name": "PDFInvoiceGenerationJob",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Successful request\", () => {",
									"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
									"});",
									"",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n\t\"code\": \"PDF_Job\",\n\t\"jobTemplate\": \"PDFInvoiceGenerationJob\",\n\t\"followingJob\": \"AO_Job\"\n}"
						},
						"url": {
							"raw": "{{opencell.url}}/jobInstance/createOrUpdate",
							"host": [
								"{{opencell.url}}"
							],
							"path": [
								"jobInstance",
								"createOrUpdate"
							]
						}
					},
					"response": []
				},
				{
					"name": "XMLInvoiceGenerationJob",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Successful request\", () => {",
									"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
									"});",
									"",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n\t\"code\": \"XML_Job\",\n\t\"jobTemplate\": \"XMLInvoiceGenerationJob\",\n\t\"followingJob\": \"PDF_Job\"\n}"
						},
						"url": {
							"raw": "{{opencell.url}}/jobInstance/createOrUpdate",
							"host": [
								"{{opencell.url}}"
							],
							"path": [
								"jobInstance",
								"createOrUpdate"
							]
						}
					},
					"response": []
				},
				{
					"name": "AccountOperationsGenerationJob",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Successful request\", () => {",
									"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
									"});",
									"",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n\t\"code\": \"AO_Job\",\n\t\"jobTemplate\": \"AccountOperationsGenerationJob\",\n\t\"followingJob\": \"EKKO_SDD_JOB\"\n}"
						},
						"url": {
							"raw": "{{opencell.url}}/jobInstance/createOrUpdate",
							"host": [
								"{{opencell.url}}"
							],
							"path": [
								"jobInstance",
								"createOrUpdate"
							]
						}
					},
					"response": []
				},
				{
					"name": "Export Rapsodie",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Successful request\", () => {",
									"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
									"});",
									"",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"code\": \"EkkoExportRapsodieJob\",\n    \"description\": \"Ekko export Rapsodie Job\",\n    \"jobCategory\": \"MEDIATION\",\n    \"jobTemplate\": \"ScriptingJob\",\n    \"customFields\": {\n        \"customField\": [\n            {\n                \"code\": \"ScriptingJob_script\",\n                \"entityReferenceValue\": {\n                    \"classname\": \"org.meveo.model.scripts.ScriptInstance\",\n                    \"code\": \"com.opencellsoft.service.ekko.compta.ExportRapsodieScript\"\n                }\n            },\n            {\n                \"code\": \"ScriptingJob_variables\",\n                \"mapValue\": {\n                    \"outputDir\": {\n                        \"value\": \"/ekko/octopus/rapsodie/out\"\n                    },\n                    \"archivedDir\": {\n                        \"value\": \"/ekko/octopus/rapsodie/archived\"\n                    }\n                }\n            }\n        ]\n    }\n}"
						},
						"url": {
							"raw": "{{opencell.url}}/jobInstance/createOrUpdate",
							"host": [
								"{{opencell.url}}"
							],
							"path": [
								"jobInstance",
								"createOrUpdate"
							]
						}
					},
					"response": []
				},
				{
					"name": "MercanetPaymentJob",
					"event": [
						{
							"listen": "test",
							"script": {
								"exec": [
									"pm.test(\"Successful request\", () => {",
									"  pm.expect(pm.response.code).to.be.oneOf([201,200,202]);",
									"});",
									"",
									""
								],
								"type": "text/javascript"
							}
						}
					],
					"request": {
						"method": "POST",
						"header": [
							{
								"key": "Content-Type",
								"value": "application/json"
							}
						],
						"body": {
							"mode": "raw",
							"raw": "{\n    \"code\": \"EkkoMercanetPaymentJob\",\n    \"description\": \"Ekko MercanetPaymentJob\",\n    \"jobCategory\": \"MEDIATION\",\n    \"jobTemplate\": \"ScriptingJob\",\n    \"customFields\": {\n        \"customField\": [\n            {\n                \"code\": \"ScriptingJob_script\",\n                \"entityReferenceValue\": {\n                    \"classname\": \"org.meveo.model.scripts.ScriptInstance\",\n                    \"code\": \"com.opencellsoft.service.ekko.payment.MercanetIntegrationScript\"\n                }\n            },\n            {\n                \"code\": \"ScriptingJob_variables\",\n                \"mapValue\": {\n                    \"MERCANET_INPUT_DIR\": {\n                        \"value\": \"/ekko/octopus/cb/in\"\n                    },\n                    \"MERCANET_ARCH_DIR\": {\n                        \"value\": \"/ekko/octopus/cb/archived\"\n                    },\n                    \"MERCANET_ERR_DIR\": {\n                        \"value\": \"/ekko/octopus/cb/errord\"\n                    },\n                    \"MERCANET_WARN_DIR\": {\n                        \"value\": \"/ekko/octopus/cb/warn\"\n                    },\n                    \"MERCANET_REPORT_DIR\": {\n                        \"value\": \"/ekko/octopus/cb/report\"\n                    },\n                    \"MERCANET_FILE_EXT\": {\n                        \"value\": \"txt\"\n                    },\n                    \"MERCANET_DELIMITER\": {\n                        \"value\": \"\\t\"\n                    }\n                }\n            }\n        ]\n    }\n}"
						},
						"url": {
							"raw": "{{opencell.url}}/jobInstance/createOrUpdate",
							"host": [
								"{{opencell.url}}"
							],
							"path": [
								"jobInstance",
								"createOrUpdate"
							]
						}
					},
					"response": []
				}
			]
		},
		{
			"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    \"code\": \"{{request.label}}\",\r\n    \"description\": \"Salesforce Object Syncing\",\r\n    \"license\": \"COM\",\r\n    \"moduleItems\": [\r\n    \t{\r\n    \t\t\"script\": {\r\n                \"description\": \"Salesforce object syncing script\",\r\n                \"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.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.billing.impl.SubscriptionService;\\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_PARAM_GRANT_TYPE_PASSWORD = \\\"password\\\";\\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 SubscriptionService subscriptionService = (SubscriptionService) getServiceInterface(SubscriptionService.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\\n\\t\\t\\t\\tCompositeSubRequestDto attachmentReq = new CompositeSubRequestDto();\\n\\t\\t\\t\\tattachmentReq.setMethod(HttpMethod.POST);\\n\\t\\t\\t\\tattachmentReq.setReferenceId(SFDC_REFERENCE_ID);\\n\\t\\t\\t\\tattachmentReq.setUrl(getEndPoint(END_POINT_SOBJECT_ATTACHMENT));\\n\\t\\t\\t\\tattachmentReq.setBody(toAttachmentJson(invoice, (String) invoiceId));\\n\\t\\t\\t\\trequest.addSubRequest(attachmentReq);\\n\\t\\t\\t}\\n\\n\\t\\t\\trequest.setAllOrNone(false);\\n\\t\\t\\trequest.setCollateSubrequests(false);\\n\\n\\t\\t\\tsendRequest(request, invoice, CF_SFDC_ATTACHMENT_ID);\\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 (ErrorMessage.AUTHENTICATION_ERROR.equals(ex.getMessage()) ||\\n\\t\\t\\t\\t\\t\\tErrorMessage.AUTHENTICATION_ERROR_UNKNOWN.equals(ex.getMessage())) {\\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\\tthrow new SObjectSyncingException(ErrorMessage.ENTITY_SYNCING_ERROR, entity, result);\\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\\tthrow new SObjectSyncingException(ErrorMessage.ENTITY_SYNCING_ERROR, entity, errorResponse);\\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\\tsubscriptionJson.addProperty(\\\"opencell__AccountID__c\\\", subscription.getUserAccount().getCode());\\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\\tinvoiceJson.addProperty(\\\"opencell__Account_Name__c\\\", invoice.getBillingAccount().getCode());\\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\\taccountOperationJson.addProperty(\\\"opencell__AccountId__c\\\", accountOperation.getCustomerAccount().getCode());\\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(\\\"Error occured while requesting new token : [{0}:{1}] ==> Response got : {2}\\\"),\\n\\n\\t\\tAUTHENTICATION_ERROR_UNKNOWN(\\\"Unknown 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                \"type\": \"JAVA\"\r\n            }\r\n        },\r\n        {\r\n        \t\"notification\" : {\r\n\t\t\t    \"code\": \"SalesforceInvoiceSyncing\",\r\n\t\t\t\t\"runAsync\": false,\r\n\t\t\t    \"description\": \"Invoice syncing with Salesforce\",\r\n\t\t\t    \"classNameFilter\": \"org.meveo.model.billing.Invoice\",\r\n\t\t\t    \"eventTypeFilter\": \"UPDATED\",\r\n\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    \"scriptInstanceCode\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n        \t}\r\n        },\r\n\t\t{\r\n        \t\"notification\" : {\r\n\t\t\t    \"code\": \"SalesforceAccountOperationSyncing\",\r\n\t\t\t\t\"runAsync\": false,\r\n\t\t\t    \"description\": \"AO syncing with Salesforce\",\r\n\t\t\t    \"classNameFilter\": \"org.meveo.model.payments.AccountOperation\",\r\n\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}\r\n        },\r\n\t\t{\r\n        \t\"notification\" : {\r\n\t\t\t    \"code\": \"SalesforceMatchedAccountOperationSyncing\",\r\n\t\t\t\t\"runAsync\": false,\r\n\t\t\t    \"description\": \"Update AO already sent to SFDC after being matched on OC\",\r\n\t\t\t    \"classNameFilter\": \"org.meveo.model.payments.MatchingCode\",\r\n\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    \"scriptInstanceCode\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n        \t}\r\n        },\r\n\t\t{\r\n        \t\"notification\" : {\r\n\t\t\t    \"code\": \"SalesforceCreatedSubscriptionSyncing\",\r\n\t\t\t\t\"runAsync\": false,\r\n\t\t\t    \"description\": \"Subscription syncing with Salesforce\",\r\n\t\t\t    \"classNameFilter\": \"org.meveo.model.billing.Subscription\",\r\n\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}\r\n        },\r\n\t\t{\r\n        \t\"notification\" : {\r\n\t\t\t    \"code\": \"SalesforceUpdatedSubscriptionSyncing\",\r\n\t\t\t\t\"runAsync\": false,\r\n\t\t\t    \"description\": \"Subscription syncing with Salesforce\",\r\n\t\t\t    \"classNameFilter\": \"org.meveo.model.billing.Subscription\",\r\n\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    \"scriptInstanceCode\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n        \t}\r\n        },\r\n\t\t{\r\n            \"filter\": {\r\n                \"code\": \"SFDC_INVOICE_TO_SYNC_FILTER\",\r\n                \"disabled\": false,\r\n                \"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                \"inputXml\": \"<filter>\\r\\n   <disabled>false<\\/disabled><secondarySelectors\\/><\\/filter>\"\r\n            }\r\n        },\r\n\t\t{\r\n            \"filter\": {\r\n                \"code\": \"SFDC_SUBSCRIPTION_TO_SYNC_FILTER\",\r\n                \"disabled\": false,\r\n                \"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                \"inputXml\": \"<filter>\\r\\n   <disabled>false<\\/disabled><secondarySelectors\\/><\\/filter>\"\r\n            }\r\n        },\t\t\r\n\t\t{\r\n            \"filter\": {\r\n                \"code\": \"SFDC_ACCOUNT_OPERATION_TO_SYNC_FILTER\",\r\n                \"disabled\": false,\r\n                \"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                \"inputXml\": \"<filter>\\r\\n   <disabled>false<\\/disabled><secondarySelectors\\/><\\/filter>\"\r\n            }\r\n        },\r\n        {\r\n            \"jobInstance\": {\r\n                \"code\": \"SalesforceInvoiceSyncingJob\",\r\n                \"jobTemplate\": \"FilteringJob\",\r\n\t\t\t\t\"disabled\": true,\r\n                \"customFields\": {\r\n                    \"customField\": [\r\n                        {\r\n                            \"code\": \"FilteringJob_recordVariableName\",\r\n                            \"stringValue\": \"CONTEXT_ENTITY\"\r\n                        },\r\n                        {\r\n                            \"code\": \"FilteringJob_filter\",\r\n                            \"entityReferenceValue\": {\r\n                                \"classname\": \"org.meveo.model.filter.Filter\",\r\n                                \"code\": \"SFDC_INVOICE_TO_SYNC_FILTER\"\r\n                            }\r\n                        },\r\n                        {\r\n                            \"code\": \"FilteringJob_script\",\r\n                            \"entityReferenceValue\": {\r\n                                \"classname\": \"org.meveo.model.scripts.ScriptInstance\",\r\n                                \"code\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n                            }\r\n                        }\r\n                    ]\r\n                },\r\n                \"limitToSingleNode\": true,\r\n                \"verboseReport\": true\r\n            }\r\n        },\r\n\t\t{\r\n            \"jobInstance\": {\r\n                \"code\": \"SalesforceSubscriptionSyncingJob\",\r\n                \"jobTemplate\": \"FilteringJob\",\r\n\t\t\t\t\"disabled\": true,\r\n                \"customFields\": {\r\n                    \"customField\": [\r\n                        {\r\n                            \"code\": \"FilteringJob_recordVariableName\",\r\n                            \"stringValue\": \"CONTEXT_ENTITY\"\r\n                        },\r\n                        {\r\n                            \"code\": \"FilteringJob_filter\",\r\n                            \"entityReferenceValue\": {\r\n                                \"classname\": \"org.meveo.model.filter.Filter\",\r\n                                \"code\": \"SFDC_SUBSCRIPTION_TO_SYNC_FILTER\"\r\n                            }\r\n                        },\r\n                        {\r\n                            \"code\": \"FilteringJob_script\",\r\n                            \"entityReferenceValue\": {\r\n                                \"classname\": \"org.meveo.model.scripts.ScriptInstance\",\r\n                                \"code\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n                            }\r\n                        }\r\n                    ]\r\n                },\r\n                \"limitToSingleNode\": true,\r\n                \"verboseReport\": true\r\n            }\r\n\t\t},\r\n \t\t{\r\n            \"jobInstance\": {\r\n                \"code\": \"SalesforceAccountOperationSyncingJob\",\r\n                \"jobTemplate\": \"FilteringJob\",\r\n\t\t\t\t\"disabled\": true,\r\n                \"customFields\": {\r\n                    \"customField\": [\r\n                        {\r\n                            \"code\": \"FilteringJob_filter\",\r\n                            \"entityReferenceValue\": {\r\n                                \"classname\": \"org.meveo.model.filter.Filter\",\r\n                                \"code\": \"SFDC_ACCOUNT_OPERATION_TO_SYNC_FILTER\"\r\n                            }\r\n                        },\r\n                        {\r\n                            \"code\": \"FilteringJob_recordVariableName\",\r\n                            \"stringValue\": \"CONTEXT_ENTITY\"\r\n                        },\r\n                        {\r\n                            \"code\": \"FilteringJob_script\",\r\n                            \"entityReferenceValue\": {\r\n                                \"classname\": \"org.meveo.model.scripts.ScriptInstance\",\r\n                                \"code\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n                            }\r\n                        }\r\n                    ]\r\n                },\r\n                \"limitToSingleNode\": true,\r\n                \"verboseReport\": true\r\n            }\r\n        },\r\n\t\t{\r\n            \"customFieldTemplate\": {\r\n                \"code\": \"CF_SFDC_ACCOUNT_FIELDS\",\r\n                \"description\": \"Salesforce account fields\",\r\n                \"disabled\": false,\r\n                \"fieldType\": \"STRING\",\r\n                \"appliesTo\": \"Customer\",\r\n                \"useInheritedAsDefaultValue\": false,\r\n                \"storageType\": \"MAP\",\r\n                \"valueRequired\": false,\r\n                \"uniqueConstraint\": false,\r\n                \"versionable\": false,\r\n                \"triggerEndPeriodEvent\": false,\r\n                \"allowEdit\": true,\r\n                \"hideOnNew\": false,\r\n                \"maxValue\": 200\r\n            }\r\n        },\r\n\t\t{\r\n            \"entityCustomAction\": {\r\n                \"code\": \"INOICE_SYNCING_ACTION\",\r\n                \"appliesTo\": \"Invoice\",\r\n                \"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                \"script\": {\r\n                    \"code\": \"org.opencell.eeko.service.script.syncing.SObjectSyncingScript\"\r\n                }\r\n            }\r\n        },\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                \"code\": \"SYNCING_ERRORS\",\r\n                \"name\": \"SFDC Syncing errors\",\r\n                \"storeAsTable\": true,\r\n                \"fields\": [\r\n                    {\r\n                        \"code\": \"entity_id\",\r\n                        \"description\": \"Entity id\",\r\n                        \"fieldType\": \"STRING\",\r\n                        \"appliesTo\": \"CE_SYNCING_ERRORS\",\r\n                        \"storageType\": \"SINGLE\",\r\n                        \"allowEdit\": false,\r\n                        \"maxValue\": 50\r\n                    },\r\n                    {\r\n                        \"code\": \"entity_code\",\r\n                        \"description\": \"Entity code\",\r\n                        \"fieldType\": \"STRING\",\r\n                        \"appliesTo\": \"CE_SYNCING_ERRORS\",\r\n                        \"storageType\": \"SINGLE\",\r\n                        \"allowEdit\": false,\r\n                        \"maxValue\": 255\r\n                    },\r\n                    {\r\n                        \"code\": \"entity_type\",\r\n                        \"description\": \"Entity type\",\r\n                        \"fieldType\": \"STRING\",\r\n                        \"appliesTo\": \"CE_SYNCING_ERROS\",\r\n                        \"storageType\": \"SINGLE\",\r\n                        \"allowEdit\": false,\r\n                        \"maxValue\": 50\r\n                    },\r\n                    {\r\n                        \"code\": \"syncing_date\",\r\n                        \"description\": \"Syncing date\",\r\n                        \"fieldType\": \"STRING\",\r\n                        \"appliesTo\": \"CE_SYNCING_ERROS\",\r\n                        \"storageType\": \"SINGLE\",\r\n                        \"allowEdit\": false,\r\n                        \"maxValue\": 50\r\n                    },\r\n\t\t\t\t\t{\r\n                        \"code\": \"request_path_info\",\r\n                        \"description\": \"Request path info\",\r\n                        \"fieldType\": \"STRING\",\r\n                        \"appliesTo\": \"CE_SYNCING_ERROS\",\r\n                        \"storageType\": \"SINGLE\",\r\n                        \"allowEdit\": false,\r\n                        \"maxValue\": 255\r\n                    },\r\n\t\t\t\t\t{\r\n                        \"code\": \"request_body\",\r\n                        \"description\": \"Request body\",\r\n                        \"fieldType\": \"STRING\",\r\n                        \"appliesTo\": \"CE_SYNCING_ERROS\",\r\n                        \"storageType\": \"SINGLE\",\r\n                        \"allowEdit\": false,\r\n                        \"maxValue\": 1024\r\n                    },\r\n\t\t\t\t\t{\r\n                        \"code\": \"response_status\",\r\n                        \"description\": \"Response status\",\r\n                        \"fieldType\": \"STRING\",\r\n                        \"appliesTo\": \"CE_SYNCING_ERROS\",\r\n                        \"storageType\": \"SINGLE\",\r\n                        \"allowEdit\": false,\r\n                        \"maxValue\": 100\r\n                    },     \r\n\t\t\t\t\t{\r\n                        \"code\": \"response_message\",\r\n                        \"description\": \"Response message\",\r\n                        \"fieldType\": \"STRING\",\r\n                        \"appliesTo\": \"CE_SYNCING_ERROS\",\r\n                        \"storageType\": \"SINGLE\",\r\n                        \"allowEdit\": false,\r\n                        \"maxValue\": 255\r\n                    },  \r\n\t\t\t\t\t{\r\n                        \"code\": \"response_body\",\r\n                        \"description\": \"Response body\",\r\n                        \"fieldType\": \"STRING\",\r\n                        \"appliesTo\": \"CE_SYNCING_ERROS\",\r\n                        \"storageType\": \"SINGLE\",\r\n                        \"allowEdit\": false,\r\n                        \"maxValue\": 1024\r\n                    } \t\t\t\t\t                          \r\n                ]\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": []
						},
						{
							"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": []
						}
					]
				},
				{
					"name": "Global properties",
					"item": [
						{
							"name": "salesforce.url",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \t\"property\": \"{{request.label}}\",\r\n\t\"value\": \"{{{{request.label}}}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{opencell.url}}/configurations",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"configurations"
									]
								}
							},
							"response": []
						},
						{
							"name": "salesforce.username",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \t\"property\": \"{{request.label}}\",\r\n\t\"value\": \"{{{{request.label}}}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{opencell.url}}/configurations",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"configurations"
									]
								}
							},
							"response": []
						},
						{
							"name": "salesforce.password",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \t\"property\": \"{{request.label}}\",\r\n\t\"value\": \"{{{{request.label}}}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{opencell.url}}/configurations",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"configurations"
									]
								}
							},
							"response": []
						},
						{
							"name": "salesforce.clientId",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \t\"property\": \"{{request.label}}\",\r\n\t\"value\": \"{{{{request.label}}}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{opencell.url}}/configurations",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"configurations"
									]
								}
							},
							"response": []
						},
						{
							"name": "salesforce.clientSecret",
							"event": [
								{
									"listen": "test",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								},
								{
									"listen": "prerequest",
									"script": {
										"exec": [
											""
										],
										"type": "text/javascript"
									}
								}
							],
							"request": {
								"method": "POST",
								"header": [],
								"body": {
									"mode": "raw",
									"raw": "{\r\n  \t\"property\": \"{{request.label}}\",\r\n\t\"value\": \"{{{{request.label}}}}\"\r\n}",
									"options": {
										"raw": {
											"language": "json"
										}
									}
								},
								"url": {
									"raw": "{{opencell.url}}/configurations",
									"host": [
										"{{opencell.url}}"
									],
									"path": [
										"configurations"
									]
								}
							},
							"response": []
						}
					]
				}
			]
		}
	],
	"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\");",
					"    }",
					"}));"
				]
			}
		}
	]
}