{
	"info": {
		"_postman_id": "d1bda964-1c35-4f58-97f3-41c3f43b0c4a",
		"name": "KEOBIZ_FIX_1083",
		"description": "KEOBIZ_FIX_667",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
	},
	"item": [
		{
			"name": "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=\"org.opencell.keobiz.service.script.payment.SepaDDRequestBuilderScript\" description=\"Sepa Pain08 and camt54 Script\">\r\n            <type>JAVA</type>\r\n            <script>\r\n            <![CDATA[\r\npackage org.opencell.keobiz.service.script.payment;\r\n\r\nimport java.io.File;\r\nimport java.math.BigDecimal;\r\nimport java.math.RoundingMode;\r\nimport java.util.Arrays;\r\nimport java.util.Date;\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.BankToCustomerDebitCreditNotificationV02;\r\nimport org.meveo.admin.sepa.jaxb.camt054.ReportEntry2;\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.PersistenceUtils;\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.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.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\n * \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 Constant NUMBER_OF_TRANSACTIONS. */\r\n\tprivate static final String NUMBER_OF_TRANSACTIONS_1 = \"1\";\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\r\n\t/** The recorded invoice service. */\r\n\tprivate RecordedInvoiceService recordedInvoiceService = (RecordedInvoiceService) EjbUtils.getServiceInterface(RecordedInvoiceService.class.getSimpleName());\r\n\r\n\t@Override\r\n\tpublic List<AccountOperation> findListAoToPay(Map<String, Object> methodContext) throws BusinessException {\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\treturn aos.stream().filter(ao -> (ao.getPaymentInfo6() == null && ao.getUnMatchingAmount().intValue() != 0)).collect(Collectors.toList());\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\t\t\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\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\tParamBean paramBean = ParamBean.getInstanceByProvider(appProvider.getCode());\r\n\t\t\tString fileName = fileNamePrefix + ddRequestLot.getId();\r\n\t\t\tSeller seller = ddRequestLot.getSeller();\r\n\t\t\tif (seller != null) {\r\n\t\t\t\tfileName = fileName + UNDERSCORE_SEPARATOR + seller.getCode();\r\n\t\t\t} else {\r\n\t\t\t\tfileName = fileName + UNDERSCORE_SEPARATOR + appProvider.getCode();\r\n\t\t\t}\r\n\r\n\t\t\tfileName = fileName + UNDERSCORE_SEPARATOR + DateUtils.formatDateWithPattern(new Date(), SIMPLE_DATE_PATTERN) + fileNameExtension;\r\n\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);\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\t//ddRequestLOTService.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) {\r\n\t\t\tinitgPty.setNm(format(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\r\n\t\tDate customerRequestedDate = ddRequestLot.getSendDate();\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(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\t\t\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\t\t\r\n\t\treturn isEmptyLot;\r\n\t\t\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) {\r\n\t\t\tpreferedPaymentMethod = PersistenceUtils.initializeAndUnproxy(preferedPaymentMethod);\r\n\t\t}\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) {\r\n\t\t\tfullName = name.getFullName();\r\n\t\t} else {\r\n\t\t\tfullName = ca.getCustomer().getName().getFullName();\r\n\t\t}\r\n\t\treturn fullName;\r\n\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 reportEntry2 the report Entry 2\r\n\t * @return the end to end id\r\n\t * @throws Exception \r\n\t */\r\n\tprivate String getEndToEndId(ReportEntry2 reportEntry2) throws Exception {\r\n\t\tString endToEndId = null;\r\n\t\ttry {\r\n\t\t\tendToEndId = reportEntry2.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 Exception(\"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 * @throws Exception \r\n\t */\r\n\tprivate Long getDdItemIdFromEndToEnd(String endToEnd) throws Exception {\r\n\t\tendToEnd = formatEndToEnd(endToEnd);\r\n\t\tif (StringUtils.isBlank(endToEnd) || endToEnd.indexOf(\"_\") == -1) {\r\n\t\t\tthrow new Exception(\"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 Exception(\"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 * @throws Exception \r\n\t */\r\n\tprivate Long getAIdFromEndToEnd(String endToEnd) throws Exception {\r\n\t\tendToEnd = formatEndToEnd(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 Exception(\"Invalid type END_TO_END :\" + endToEnd);\r\n\t\t}\r\n\r\n\t}\r\n\r\n\tprivate String formatEndToEnd(String endToEnd) {\r\n\t\tif(StringUtils.isBlank(endToEnd)) {\r\n\t\t\treturn endToEnd;\r\n\t\t}\r\n\t\treturn endToEnd.replaceAll(\"-\", \"_\");\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\t\t\tList<ReportEntry2> listNtry = bkToCstmrDbtCdtNtfctn.getNtfctn().get(0).getNtry();\t\t\t\t\t\t\r\n\t\t\t\r\n\t\t\tfor (ReportEntry2 reportEntry2 : listNtry) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tlog.info(\"processing reportEntry2.NtryRef:{}...\" , reportEntry2.getNtryRef());\r\n\t\t\t\t\tString endToEnd = getEndToEndId(reportEntry2);\r\n\t\t\t\t\tlog.info(\"processing reportEntry2.NtryRef:{} endToEnd:{} ...\" , reportEntry2.getNtryRef(),endToEnd);\r\n\t\t\t\t\tString rejectReason = getRejectReason(reportEntry2);\r\n\t\t\t\t\tLong ddItemIdFromEndToEnd = getDdItemIdFromEndToEnd(endToEnd);\r\n\t\t\t\t\tlog.info(\"processing reportEntry2.NtryRef:{} endToEnd:{}  rejectReason:{} ddItemIdFromEndToEnd:{} ...\" , reportEntry2.getNtryRef(),endToEnd,rejectReason,ddItemIdFromEndToEnd);\t\t\r\n\t\t\t\t\tDDRequestItem ddRequestItem =  ddRequestItemService.findById(ddItemIdFromEndToEnd);\r\n\t\t\t\t\tif(ddRequestItem == null) {\r\n\t\t\t\t\t\tthrow new Exception(\"Cant found DDRequestItem by id:\"+ddItemIdFromEndToEnd);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tddRejectFileInfos.getListInvoiceRefsRejected().put(ddItemIdFromEndToEnd, rejectReason);\r\n\t\t\t\t\t\r\n\t\t\t\t\tddRequestLOTService.rejectPayment(ddRequestItem, 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\t\t\t\t\tlog.info(\"processing reportEntry2.NtryRef:{} Done.\" , reportEntry2.getNtryRef());\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     * @param reportEntry2 the report Entry 2\r\n\t * @return the reject reason\r\n\t * @throws Exception \r\n\t */\r\n\tprivate String getRejectReason(ReportEntry2 reportEntry2 ) throws Exception {\r\n\t\tString rejectReason = null;\r\n\t\ttry {\r\n\t\t\trejectReason = reportEntry2.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 Exception(\"Can't found rejectReason \");\r\n\t\t}\r\n\t}\r\n}\r\n\t\t\t\t\t   ]]>\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": []
		}
	],
	"auth": {
		"type": "basic",
		"basic": [
			{
				"key": "password",
				"value": "opencell.admin",
				"type": "string"
			},
			{
				"key": "username",
				"value": "opencell.admin",
				"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\");",
					"    }",
					"}));"
				]
			}
		}
	]
}