diff --git a/src/main/scala/code/api/util/APIUtil.scala b/src/main/scala/code/api/util/APIUtil.scala index 997c23f1c..5d3116b5b 100644 --- a/src/main/scala/code/api/util/APIUtil.scala +++ b/src/main/scala/code/api/util/APIUtil.scala @@ -44,6 +44,7 @@ import code.api.OAuthHandshake._ import code.api._ import code.api.util.APIUtil.ApiVersion.ApiVersion import code.api.v1_2.ErrorMessage +import code.api.v2_1_0.PostCounterpartyBespoke import code.bankconnectors._ import code.consumer.Consumers import code.customer.Customer @@ -1841,4 +1842,51 @@ Versions are groups of endpoints in a file Props.get(s"connector.cache.ttl.seconds.$cacheType", "0").toInt } + /** + * Normally, we create the AccountId, BankId automatically in database. Because they are the UUIDString in the table. + * We also can create the Id manually. + * eg: CounterpartyId, because we use this Id both for Counterparty and counterpartyMetaData by some input fields. + */ + def createOBPId(in:String)= { + import net.liftweb.util.SecurityHelpers._ + import java.security.MessageDigest + def base64EncodedSha256(in: String) = base64EncodeURLSafe(MessageDigest.getInstance("SHA-256").digest(in.getBytes("UTF-8"))).stripSuffix("=") + + base64EncodedSha256(in) + } + + /** + * Create the explicit CounterpartyId, we can get info data from api level. (Used in `Create counterparty for an account` endpoint ) + */ + def createExplicitCounterpartyId( + createdByUserId: String, + thisBankId: String, + thisAccountId : String, + thisViewId : String, + name: String, + otherAccountRoutingScheme : String, + otherAccountRoutingAddress : String, + otherBankRoutingScheme : String, + otherBankRoutingAddress : String, + otherBranchRoutingScheme: String, + otherBranchRoutingAddress: String, + isBeneficiary: Boolean, + otherAccountSecondaryRoutingScheme: String, + otherAccountSecondaryRoutingAddress: String, + description: String, + bespoke: List[PostCounterpartyBespoke] + )= createOBPId(s"$thisBankId$thisAccountId$thisViewId$name$otherAccountRoutingScheme" + + s"$otherAccountRoutingAddress$otherBankRoutingScheme$otherBankRoutingAddress$otherBranchRoutingScheme" + + s"$otherBranchRoutingAddress$isBeneficiary$otherAccountSecondaryRoutingScheme$otherAccountSecondaryRoutingAddress" + + s"$description${bespoke.map(_.value)}") + + /** + * Create the implicit CounterpartyId, we can only get limit data from Adapter. (Used in `getTransactions` endpoint, we create the counterparty implicitly.) + * Note: The caller should take care of the `counterpartyName`,it depends how you get the data from transaction. and can gernerate the `counterpartyName` + */ + def createImplicitCounterpartyId( + thisBankId: String, + thisAccountId : String, + counterpartyName: String + )= createOBPId(s"$thisBankId$thisAccountId$counterpartyName") } diff --git a/src/main/scala/code/bankconnectors/Connector.scala b/src/main/scala/code/bankconnectors/Connector.scala index acb74b6ec..3af7d59e7 100644 --- a/src/main/scala/code/bankconnectors/Connector.scala +++ b/src/main/scala/code/bankconnectors/Connector.scala @@ -5,7 +5,7 @@ import java.util.{Date, UUID} import code.accountholder.{AccountHolders, MapperAccountHolders} import code.api.util.APIUtil._ import code.api.util.ApiRole._ -import code.api.util.{ErrorMessages, SessionContext} +import code.api.util.{APIUtil, ErrorMessages, SessionContext} import code.api.util.ErrorMessages._ import code.api.v2_1_0._ import code.api.v3_0_0.CoreAccountJsonV300 @@ -273,13 +273,13 @@ trait Connector extends MdcLoggable{ def getCounterpartyFromTransaction(bankId: BankId, accountId: AccountId, counterpartyID: String): Box[Counterparty] = { // Please note that Metadata and Transaction can be at different locations // Obtain all necessary data and then intersect they - val metadata: List[CounterpartyMetadata] = Counterparties.counterparties.vend.getMetadata(bankId, accountId, counterpartyID).toList - val list: List[Transaction] = getTransactions(bankId, accountId).toList.flatten + val counterpartyMetadatas = Counterparties.counterparties.vend.getMetadata(bankId, accountId, counterpartyID).toList + val transactions = getTransactions(bankId, accountId).toList.flatten val x = for { - l <- list - m <- metadata if l.otherAccount.thisAccountId.value == m.getAccountNumber + transaction <- transactions + counterpartyMetadata <- counterpartyMetadatas if counterpartyID == counterpartyMetadata.metadataId } yield { - getCounterpartyFromTransaction(bankId, accountId, m, l).toList + getCounterpartyFromTransaction(bankId, accountId, counterpartyMetadata, transaction).toList } x.flatten match { case List() => Empty @@ -290,16 +290,45 @@ trait Connector extends MdcLoggable{ def getCounterpartiesFromTransaction(bankId: BankId, accountId: AccountId): Box[List[Counterparty]] = { // Please note that Metadata and Transaction can be at different locations // Obtain all necessary data and then intersect they - val metadata: List[CounterpartyMetadata] = Counterparties.counterparties.vend.getMetadatas(bankId, accountId) - val list: List[Transaction] = getTransactions(bankId, accountId).toList.flatten + val counterpartyMetadatas= Counterparties.counterparties.vend.getMetadatas(bankId, accountId) + val transactions= getTransactions(bankId, accountId).toList.flatten + val x = for { - l <- list - m <- metadata if l.otherAccount.thisAccountId.value == m.getAccountNumber + transaction <- transactions + counterpartyName <- List(transaction+transaction.description.getOrElse("")+transaction.otherAccount.otherAccountRoutingAddress.getOrElse("")+transaction.otherAccount.thisAccountId.value) + counterpartyId <- List(APIUtil.createImplicitCounterpartyId(bankId.value,accountId.value,counterpartyName)) + counterpartyMetadata <- counterpartyMetadatas if counterpartyId == counterpartyMetadata.metadataId } yield { - getCounterpartyFromTransaction(bankId, accountId, m, l).toList + getCounterpartyFromTransaction(bankId, accountId, counterpartyMetadata, transaction).toList } Full(x.flatten) } + + def getCounterpartyFromTransaction(thisBankId : BankId, thisAccountId : AccountId, metadata : CounterpartyMetadata, t: Transaction) : Box[Counterparty] = { + //because we don't have a db backed model for OtherBankAccounts, we need to construct it from an + //OtherBankAccountMetadata and a transaction + Full( + new Counterparty( + //counterparty id is defined to be the id of its metadata as we don't actually have an id for the counterparty itself + counterPartyId = metadata.metadataId, + label = metadata.getHolder, + nationalIdentifier = t.otherAccount.nationalIdentifier, + otherBankRoutingAddress = None, + otherAccountRoutingAddress = t.otherAccount.otherAccountRoutingAddress, + thisAccountId = AccountId(t.thisAccount.accountId.value), //tis commit: set the thisAccountId from transaction, not from MetaData + thisBankId = t.otherAccount.thisBankId, + kind = t.otherAccount.kind, + // otherBankId = thisBankId, + // otherAccountId = thisAccountId, +// alreadyFoundMetadata = Some(metadata), + name = "", + otherBankRoutingScheme = "", + otherAccountRoutingScheme="", + otherAccountProvider = "", + isBeneficiary = true + ) + ) + } def getCounterparty(thisBankId: BankId, thisAccountId: AccountId, couterpartyId: String): Box[Counterparty]= Failure(NotImplemented + currentMethodName) @@ -345,31 +374,6 @@ trait Connector extends MdcLoggable{ posted: Option[CardPostedInfo] ) : Box[PhysicalCard] = Failure(NotImplemented + currentMethodName) - def getCounterpartyFromTransaction(thisBankId : BankId, thisAccountId : AccountId, metadata : CounterpartyMetadata, t: Transaction) : Box[Counterparty] = { - //because we don't have a db backed model for OtherBankAccounts, we need to construct it from an - //OtherBankAccountMetadata and a transaction - Full( - new Counterparty( - //counterparty id is defined to be the id of its metadata as we don't actually have an id for the counterparty itself - counterPartyId = metadata.metadataId, - label = metadata.getHolder, - nationalIdentifier = t.otherAccount.nationalIdentifier, - otherBankRoutingAddress = None, - otherAccountRoutingAddress = t.otherAccount.otherAccountRoutingAddress, - thisAccountId = AccountId(metadata.getAccountNumber), - thisBankId = t.otherAccount.thisBankId, - kind = t.otherAccount.kind, - otherBankId = thisBankId, - otherAccountId = thisAccountId, - alreadyFoundMetadata = Some(metadata), - name = "", - otherBankRoutingScheme = "", - otherAccountRoutingScheme="", - otherAccountProvider = "", - isBeneficiary = true - ) - ) - } //Payments api: just return Failure("not supported") from makePaymentImpl if you don't want to implement it /** diff --git a/src/main/scala/code/bankconnectors/KafkaMappedConnector.scala b/src/main/scala/code/bankconnectors/KafkaMappedConnector.scala index 8036eb9f7..191645017 100644 --- a/src/main/scala/code/bankconnectors/KafkaMappedConnector.scala +++ b/src/main/scala/code/bankconnectors/KafkaMappedConnector.scala @@ -1178,9 +1178,9 @@ object KafkaMappedConnector extends Connector with KafkaHelper with MdcLoggable thisAccountId = AccountId(counterpartyId), thisBankId = BankId(""), kind = "", - otherBankId = o.bankId, - otherAccountId = o.accountId, - alreadyFoundMetadata = alreadyFoundMetadata, +// otherBankId = o.bankId, +// otherAccountId = o.accountId, +// alreadyFoundMetadata = alreadyFoundMetadata, name = "", otherBankRoutingScheme = "", otherAccountRoutingScheme="", diff --git a/src/main/scala/code/bankconnectors/KafkaMappedConnector_JVMcompatible.scala b/src/main/scala/code/bankconnectors/KafkaMappedConnector_JVMcompatible.scala index 02def7ef0..dfe7ac60f 100644 --- a/src/main/scala/code/bankconnectors/KafkaMappedConnector_JVMcompatible.scala +++ b/src/main/scala/code/bankconnectors/KafkaMappedConnector_JVMcompatible.scala @@ -1382,9 +1382,9 @@ object KafkaMappedConnector_JVMcompatible extends Connector with KafkaHelper wit thisAccountId = AccountId(counterpartyId), thisBankId = BankId(""), kind = "", - otherBankId = o.bankId, - otherAccountId = o.accountId, - alreadyFoundMetadata = alreadyFoundMetadata, +// otherBankId = o.bankId, +// otherAccountId = o.accountId, +// alreadyFoundMetadata = alreadyFoundMetadata, name = "", otherBankRoutingScheme = "", otherAccountRoutingScheme="", diff --git a/src/main/scala/code/bankconnectors/LocalMappedConnector.scala b/src/main/scala/code/bankconnectors/LocalMappedConnector.scala index aca3832b9..e39fcbaab 100644 --- a/src/main/scala/code/bankconnectors/LocalMappedConnector.scala +++ b/src/main/scala/code/bankconnectors/LocalMappedConnector.scala @@ -330,12 +330,12 @@ object LocalMappedConnector extends Connector with MdcLoggable { nationalIdentifier = "", otherBankRoutingAddress = None, otherAccountRoutingAddress = None, - thisAccountId = AccountId(t.getAccountNumber), + thisAccountId = thisAccountId, thisBankId = BankId(""), kind = "", - otherBankId = thisBankId, - otherAccountId = thisAccountId, - alreadyFoundMetadata = Some(t), +// otherBankId = thisBankId, +// otherAccountId = thisAccountId, +// alreadyFoundMetadata = Some(t), name = "", otherBankRoutingScheme = "", otherAccountRoutingScheme="", @@ -535,7 +535,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { .description(description) //Old data: other BankAccount(toAccount: BankAccount)simulate counterparty .counterpartyAccountHolder(toAccount.accountHolder) - .counterpartyAccountNumber(toAccount.number) + .counterpartyAccountNumber(toAccount.number)//TODO if there is no number??? .counterpartyAccountKind(toAccount.accountType) .counterpartyBankName(toAccount.bankName) .counterpartyIban(toAccount.iban.getOrElse("")) diff --git a/src/main/scala/code/bankconnectors/LocalRecordConnector.scala b/src/main/scala/code/bankconnectors/LocalRecordConnector.scala index fc103cb32..5a38e4440 100644 --- a/src/main/scala/code/bankconnectors/LocalRecordConnector.scala +++ b/src/main/scala/code/bankconnectors/LocalRecordConnector.scala @@ -96,7 +96,8 @@ private object LocalRecordConnector extends Connector with MdcLoggable { } yield{ val query = QueryBuilder .start("obp_transaction.other_account.holder").is(otherAccountmetadata.holder.get) - .put("obp_transaction.other_account.number").is(otherAccountmetadata.accountNumber.get).get() +// .put("obp_transaction.other_account.number").is(otherAccountmetadata.accountNumber.get) + .get() val otherAccountFromTransaction : OBPAccount = OBPEnvelope.find(query) match { case Full(envelope) => envelope.obp_transaction.get.other_account.get @@ -121,7 +122,8 @@ private object LocalRecordConnector extends Connector with MdcLoggable { //so we need first to get a transaction that match to have the rest of the data val query = QueryBuilder .start("obp_transaction.other_account.holder").is(meta.getHolder) - .put("obp_transaction.other_account.number").is(meta.getAccountNumber).get() +// .put("obp_transaction.other_account.number").is(meta.getAccountNumber) + .get() val otherAccountFromTransaction : OBPAccount = OBPEnvelope.find(query) match { case Full(envelope) => { @@ -235,9 +237,9 @@ private object LocalRecordConnector extends Connector with MdcLoggable { thisAccountId = AccountId(otherAccount_.number.get), thisBankId = BankId(otherAccount_.bank.get.name.get), kind = otherAccount_.kind.get, - otherBankId = theAccount.bankId, - otherAccountId = theAccount.accountId, - alreadyFoundMetadata = Some(metadata), +// otherBankId = theAccount.bankId, +// otherAccountId = theAccount.accountId, +// alreadyFoundMetadata = Some(metadata), name = "", otherBankRoutingScheme = "", otherAccountRoutingScheme="", @@ -390,9 +392,9 @@ private object LocalRecordConnector extends Connector with MdcLoggable { thisAccountId = AccountId(otherAccountFromTransaction.number.get), thisBankId = BankId(otherAccountFromTransaction.bank.get.name.get), kind = "", - otherBankId = originalPartyBankId, - otherAccountId = originalPartyAccountId, - alreadyFoundMetadata = Some(otherAccount), +// otherBankId = originalPartyBankId, +// otherAccountId = originalPartyAccountId, +// alreadyFoundMetadata = Some(otherAccount), name = "", otherBankRoutingScheme = "", otherAccountRoutingScheme="", diff --git a/src/main/scala/code/bankconnectors/ObpJvmMappedConnector.scala b/src/main/scala/code/bankconnectors/ObpJvmMappedConnector.scala index c39c40503..503b6a2bb 100644 --- a/src/main/scala/code/bankconnectors/ObpJvmMappedConnector.scala +++ b/src/main/scala/code/bankconnectors/ObpJvmMappedConnector.scala @@ -1142,9 +1142,9 @@ object ObpJvmMappedConnector extends Connector with MdcLoggable { thisAccountId = AccountId(c.account_number.getOrElse("")), thisBankId = BankId(""), kind = "", - otherBankId = o.bankId, - otherAccountId = o.accountId, - alreadyFoundMetadata = alreadyFoundMetadata, +// otherBankId = o.bankId, +// otherAccountId = o.accountId, +// alreadyFoundMetadata = alreadyFoundMetadata, name = "", otherBankRoutingScheme = "", otherAccountRoutingScheme="", diff --git a/src/main/scala/code/bankconnectors/vJune2017/KafkaMappedConnector_vJune2017.scala b/src/main/scala/code/bankconnectors/vJune2017/KafkaMappedConnector_vJune2017.scala index 85a57977d..4f5cfe7af 100644 --- a/src/main/scala/code/bankconnectors/vJune2017/KafkaMappedConnector_vJune2017.scala +++ b/src/main/scala/code/bankconnectors/vJune2017/KafkaMappedConnector_vJune2017.scala @@ -1467,11 +1467,11 @@ trait KafkaMappedConnector_vJune2017 extends Connector with KafkaHelper with Mdc thisAccountId = bankAccount.accountId, //This will be used mapping `MappedCounterpartyMetadata.accountNumber` // these define the obp account to which this counterparty belongs - otherBankId = bankAccount.bankId, //This will be used mapping MappedCounterpartyMetadata.thisBankId - otherAccountId = bankAccount.accountId, // This will be used mapping MappedCounterpartyMetadata.thisAccountId +// otherBankId = bankAccount.bankId, //This will be used mapping MappedCounterpartyMetadata.thisBankId +// otherAccountId = bankAccount.accountId, // This will be used mapping MappedCounterpartyMetadata.thisAccountId //This two will be generated in obp side implicitly - alreadyFoundMetadata = alreadyFoundMetadata, +// alreadyFoundMetadata = alreadyFoundMetadata, counterPartyId = alreadyFoundMetadata.map(_.metadataId).getOrElse(""), thisBankId = BankId(null), diff --git a/src/main/scala/code/bankconnectors/vMar2017/KafkaMappedConnector_vMar2017.scala b/src/main/scala/code/bankconnectors/vMar2017/KafkaMappedConnector_vMar2017.scala index 8ce278cdc..9a47f623b 100644 --- a/src/main/scala/code/bankconnectors/vMar2017/KafkaMappedConnector_vMar2017.scala +++ b/src/main/scala/code/bankconnectors/vMar2017/KafkaMappedConnector_vMar2017.scala @@ -1785,9 +1785,9 @@ trait KafkaMappedConnector_vMar2017 extends Connector with KafkaHelper with MdcL thisAccountId = AccountId(counterpartyId), thisBankId = BankId(""), kind = "1234", - otherBankId = o.bankId, - otherAccountId = o.accountId, - alreadyFoundMetadata = alreadyFoundMetadata, +// otherBankId = o.bankId, +// otherAccountId = o.accountId, +// alreadyFoundMetadata = alreadyFoundMetadata, name = "sushan", otherBankRoutingScheme = "obp", otherAccountRoutingScheme="obp", diff --git a/src/main/scala/code/metadata/counterparties/Counterparties.scala b/src/main/scala/code/metadata/counterparties/Counterparties.scala index 386938f23..7ab94bdc3 100644 --- a/src/main/scala/code/metadata/counterparties/Counterparties.scala +++ b/src/main/scala/code/metadata/counterparties/Counterparties.scala @@ -22,7 +22,7 @@ object Counterparties extends SimpleInjector { trait Counterparties { - def getOrCreateMetadata(originalPartyBankId: BankId, originalPartyAccountId : AccountId, otherParty : Counterparty) : Box[CounterpartyMetadata] + def getOrCreateMetadata(bankId: BankId, accountId : AccountId, counterpartyId:String, counterpartyName:String) : Box[CounterpartyMetadata] //get all counterparty metadatas for a single OBP account def getMetadatas(originalPartyBankId: BankId, originalPartyAccountId : AccountId) : List[CounterpartyMetadata] @@ -102,7 +102,7 @@ trait CounterpartyTrait { } class RemotedataCounterpartiesCaseClasses { - case class getOrCreateMetadata(originalPartyBankId: BankId, originalPartyAccountId: AccountId, otherParty: Counterparty) + case class getOrCreateMetadata(bankId: BankId, accountId: AccountId, counterpartyId:String, counterpartyName:String) case class getMetadatas(originalPartyBankId: BankId, originalPartyAccountId: AccountId) diff --git a/src/main/scala/code/metadata/counterparties/MapperCounterparties.scala b/src/main/scala/code/metadata/counterparties/MapperCounterparties.scala index 70936c335..ccb8ebd2b 100644 --- a/src/main/scala/code/metadata/counterparties/MapperCounterparties.scala +++ b/src/main/scala/code/metadata/counterparties/MapperCounterparties.scala @@ -2,6 +2,7 @@ package code.metadata.counterparties import java.util.{Date, UUID} +import code.api.util.APIUtil import code.api.v2_1_0.PostCounterpartyBespoke import code.model._ import code.model.dataAccess.ResourceUser @@ -17,7 +18,8 @@ import net.liftweb.util.Helpers.tryo // 2nd is generated by obp implicitly, when use `getTransactions` endpoint. This will not be stored in database, but we create the CounterpartyMetadata for it. And the CounterpartyMetadata is in database. // They are relevant somehow, but they are different data for now. Both data can be get by the following `MapperCounterparties` object. object MapperCounterparties extends Counterparties with MdcLoggable { - override def getOrCreateMetadata(originalPartyBankId: BankId, originalPartyAccountId: AccountId, otherParty: Counterparty): Box[CounterpartyMetadata] = { + //TODO, this method need to be cached later. + override def getOrCreateMetadata(bankId: BankId, accountId: AccountId, counterpartyId: String, counterpartyName:String): Box[CounterpartyMetadata] = { /** * Generates a new alias name that is guaranteed not to collide with any existing public alias names @@ -25,17 +27,14 @@ object MapperCounterparties extends Counterparties with MdcLoggable { */ def newPublicAliasName(): String = { val firstAliasAttempt = "ALIAS_" + UUID.randomUUID.toString.toUpperCase.take(6) - - /** - * Returns true if @publicAlias is already the name of a public alias within @account - */ - def isDuplicate(publicAlias: String) : Boolean = { - MappedCounterpartyMetadata.find( - By(MappedCounterpartyMetadata.thisBankId, originalPartyBankId.value), - By(MappedCounterpartyMetadata.thisAccountId, originalPartyAccountId.value), - By(MappedCounterpartyMetadata.publicAlias, publicAlias) - ).isDefined - } + + val counterpartyMetadatasPublicAlias = MappedCounterpartyMetadata + .findAll( + By(MappedCounterpartyMetadata.thisBankId, bankId.value), + By(MappedCounterpartyMetadata.thisAccountId, accountId.value)) + .map(_.addPublicAlias) + + def isDuplicate(publicAlias: String) = counterpartyMetadatasPublicAlias.contains(publicAlias) /** * Appends things to @publicAlias until it a unique public alias name within @account @@ -54,30 +53,31 @@ object MapperCounterparties extends Counterparties with MdcLoggable { //can't find by MappedCounterpartyMetadata.counterpartyId = otherParty.id because in this implementation //if the metadata doesn't exist, the id field of the OtherBankAccount is not known yet, and will be empty - def findMappedCounterpartyMetadata(originalPartyBankId: BankId, originalPartyAccountId: AccountId, - otherParty: Counterparty) : Box[MappedCounterpartyMetadata] = { + def findMappedCounterpartyMetadata( + counterpartyId: String + ) : Box[MappedCounterpartyMetadata] = { MappedCounterpartyMetadata.find( - By(MappedCounterpartyMetadata.thisBankId, originalPartyBankId.value), - By(MappedCounterpartyMetadata.thisAccountId, originalPartyAccountId.value), - By(MappedCounterpartyMetadata.holder, otherParty.label), - By(MappedCounterpartyMetadata.accountNumber, otherParty.thisAccountId.value)) + By(MappedCounterpartyMetadata.counterpartyId, counterpartyId)) } - val existing = findMappedCounterpartyMetadata(originalPartyBankId, originalPartyAccountId, otherParty) + val existing = findMappedCounterpartyMetadata(counterpartyId) existing match { - case Full(e) => Full(e) + case Full(e) => + logger.debug(s"Getting MappedCounterpartyMetadata counterpartyId($counterpartyId)") + Full(e) // Create it! case _ => { - logger.debug("Before creating MappedCounterpartyMetadata") + logger.debug(s"Creating MappedCounterpartyMetadata counterpartyId($counterpartyId)") // Store a record that contains counterparty information from the perspective of an account at a bank Full(MappedCounterpartyMetadata.create // Core info - .thisBankId(originalPartyBankId.value) - .thisAccountId(originalPartyAccountId.value) - .holder(otherParty.label) // The main human readable identifier for this counter party from the perspective of the account holder + .counterpartyId(counterpartyId) + .thisBankId(bankId.value) + .thisAccountId(accountId.value) + .holder(counterpartyName) // The main human readable identifier for this counter party from the perspective of the account holder .publicAlias(newPublicAliasName()) // The public alias this account gives to the counterparty. - .accountNumber(otherParty.thisAccountId.value) +// .accountNumber(otherPartyThisAccountId) // otherParty.metadata is None at this point //.imageUrl("www.example.com/image.jpg") //.moreInfo("This is hardcoded moreInfo") @@ -148,12 +148,29 @@ object MapperCounterparties extends Counterparties with MdcLoggable { description: String, bespoke: List[PostCounterpartyBespoke] ): Box[CounterpartyTrait] = { - val metadata = MappedCounterpartyMetadata.create - .thisBankId(thisBankId) - .thisAccountId(thisAccountId) - .holder(name) - .saveMe + + val counterpartyId = APIUtil.createExplicitCounterpartyId( + createdByUserId: String, + thisBankId: String, + thisAccountId : String, + thisViewId : String, + name: String, + otherAccountRoutingScheme : String, + otherAccountRoutingAddress : String, + otherBankRoutingScheme : String, + otherBankRoutingAddress : String, + otherBranchRoutingScheme: String, + otherBranchRoutingAddress: String, + isBeneficiary: Boolean, + otherAccountSecondaryRoutingScheme: String, + otherAccountSecondaryRoutingAddress: String, + description: String, + bespoke: List[PostCounterpartyBespoke] + ) + //This is the `EXPLICIT` Counterparty, we also create the metaData for it + val metadata = Counterparties.counterparties.vend.getOrCreateMetadata(BankId(thisBankId), AccountId(thisAccountId), counterpartyId, name).openOrThrowException("Can not getOrCreateMetadata !") + val mappedCounterparty = MappedCounterparty.create .mCounterPartyId(metadata.metadataId) .mName(name) @@ -297,7 +314,7 @@ object MapperCounterparties extends Counterparties with MdcLoggable { class MappedCounterpartyMetadata extends CounterpartyMetadata with LongKeyedMapper[MappedCounterpartyMetadata] with IdPK with CreatedUpdated { override def getSingleton = MappedCounterpartyMetadata - object counterpartyId extends MappedUUID(this) + object counterpartyId extends UUIDString(this) //these define the obp account to which this counterparty belongs object thisBankId extends UUIDString(this) @@ -305,7 +322,8 @@ class MappedCounterpartyMetadata extends CounterpartyMetadata with LongKeyedMapp //these define the counterparty object holder extends MappedString(this, 255) // Is this the name of the counterparty? - object accountNumber extends MappedAccountNumber(this) +// @deprecated("old version, security hole, not good to store core banking data in obp") +// object accountNumber extends MappedAccountNumber(this) //this is the counterparty's metadata object publicAlias extends MappedString(this, 64) @@ -362,7 +380,7 @@ class MappedCounterpartyMetadata extends CounterpartyMetadata with LongKeyedMapp } override def metadataId: String = counterpartyId.get - override def getAccountNumber: String = accountNumber.get +// override def getAccountNumber: String = accountNumber.get override def getHolder: String = holder.get override def getPublicAlias: String = publicAlias.get override def getCorporateLocation: Option[GeoTag] = @@ -436,7 +454,7 @@ class MappedCounterparty extends CounterpartyTrait with LongKeyedMapper[MappedCo object mThisBankId extends MappedString(this, 36) object mThisAccountId extends AccountIdString(this) object mThisViewId extends MappedString(this, 36) - object mCounterPartyId extends MappedString(this, 36) + object mCounterPartyId extends UUIDString(this) object mOtherAccountRoutingScheme extends MappedString(this, 255) object mOtherAccountRoutingAddress extends MappedString(this, 255) object mOtherBankRoutingScheme extends MappedString(this, 255) diff --git a/src/main/scala/code/metadata/counterparties/MongoCounterparties.scala b/src/main/scala/code/metadata/counterparties/MongoCounterparties.scala index 89aa7ec69..38fb23128 100644 --- a/src/main/scala/code/metadata/counterparties/MongoCounterparties.scala +++ b/src/main/scala/code/metadata/counterparties/MongoCounterparties.scala @@ -31,17 +31,17 @@ object MongoCounterparties extends Counterparties with MdcLoggable { } yield m } - def getOrCreateMetadata(originalPartyBankId: BankId, originalPartyAccountId : AccountId, otherParty : Counterparty) : Box[CounterpartyMetadata] = { + def getOrCreateMetadata(bankId: BankId, accountId : AccountId, counterpartyId:String, counterpartyName:String) : Box[CounterpartyMetadata] = { /** * This particular implementation requires the metadata id to be the same as the otherParty (OtherBankAccount) id */ - val existing = getMetadata(originalPartyBankId, originalPartyAccountId, otherParty.counterPartyId) + val existing = getMetadata(bankId, accountId, counterpartyId) val metadata = existing match { case Full(m) => m - case _ => createMetadata(originalPartyBankId, originalPartyAccountId, otherParty.label, otherParty.thisAccountId.value) + case _ => createMetadata(bankId, accountId, counterpartyId, counterpartyName) } Full(metadata) @@ -50,25 +50,27 @@ object MongoCounterparties extends Counterparties with MdcLoggable { /** * This only exists for OBPEnvelope. Avoid using it for any other reason outside of this class */ - def createMetadata(originalPartyBankId: BankId, originalPartyAccountId : AccountId, otherAccountHolder : String, otherAccountNumber : String) : Metadata = { + def createMetadata(originalPartyBankId: BankId, originalPartyAccountId : AccountId, counterpartyId:String, otherPartyLabel:String) : Metadata = { //create it - if(otherAccountHolder.isEmpty){ + if(otherPartyLabel.isEmpty){ logger.info("other account holder is Empty. creating a metadata record with private alias") //no holder name, nothing to hide, so we don't need to create a public alias Metadata .createRecord + .counterpartyId(counterpartyId) .originalPartyBankId(originalPartyBankId.value) .originalPartyAccountId(originalPartyAccountId.value) - .accountNumber(otherAccountNumber) +// .accountNumber(otherAccountNumber)//Not good to save core banking data in obp .holder("") .save(true) } else { Metadata.createRecord. + counterpartyId(counterpartyId). originalPartyBankId(originalPartyBankId.value). originalPartyAccountId(originalPartyAccountId.value). - holder(otherAccountHolder). - accountNumber(otherAccountNumber). + holder(otherPartyLabel). +// accountNumber(otherAccountNumber). //Not good to save core banking data in obp publicAlias(newPublicAliasName(originalPartyBankId, originalPartyAccountId)).save(true) } } diff --git a/src/main/scala/code/metadata/counterparties/MongoMetadata.scala b/src/main/scala/code/metadata/counterparties/MongoMetadata.scala index 5e0065f8d..92e089113 100644 --- a/src/main/scala/code/metadata/counterparties/MongoMetadata.scala +++ b/src/main/scala/code/metadata/counterparties/MongoMetadata.scala @@ -17,9 +17,10 @@ class Metadata private() extends CounterpartyMetadata with MongoRecord[Metadata] //which has the counterparty this metadata is associated with object originalPartyBankId extends StringField(this, 100) object originalPartyAccountId extends StringField(this, 100) + object counterpartyId extends StringField(this,100) object holder extends StringField(this, 255) - object accountNumber extends StringField(this, 100) +// object accountNumber extends StringField(this, 100) object publicAlias extends StringField(this, 100) object privateAlias extends StringField(this, 100) object moreInfo extends StringField(this, 100) @@ -70,9 +71,9 @@ class Metadata private() extends CounterpartyMetadata with MongoRecord[Metadata] Some(loc) } - override def metadataId = id.get.toString + override def metadataId = counterpartyId.get override def getHolder = holder.get - override def getAccountNumber = accountNumber.get +// override def getAccountNumber = accountNumber.get override def getUrl = url.get override def getCorporateLocation = locationTag(corporateLocation.get) override def getPhysicalLocation = locationTag(physicalLocation.get) diff --git a/src/main/scala/code/model/BankingData.scala b/src/main/scala/code/model/BankingData.scala index 067992334..225ddae97 100644 --- a/src/main/scala/code/model/BankingData.scala +++ b/src/main/scala/code/model/BankingData.scala @@ -37,7 +37,7 @@ import scala.math.BigDecimal import java.util.Date import code.accountholder.AccountHolders -import code.api.util.SessionContext +import code.api.util.{APIUtil, SessionContext} import code.bankconnectors.vJune2017.AccountRules import scala.collection.immutable.{List, Set} @@ -657,38 +657,33 @@ as see from the perspective of the original party. // Note: See also CounterpartyTrait class Counterparty( - - @deprecated("older version, please first consider the V210, account scheme and address") - val nationalIdentifier : String, // This is the scheme a consumer would use to instruct a payment e.g. IBAN - val alreadyFoundMetadata : Option[CounterpartyMetadata], - val label : String, // Reference given to the counterparty by the original party. - val kind : String, // Type of bank account. - - // The following fields started from V210 - val counterPartyId: String, - val name: String, - val otherAccountRoutingScheme :String, // This is the scheme a consumer would use to instruct a payment e.g. IBAN - val otherAccountRoutingAddress : Option[String], // The (IBAN) value e.g. 2349870987820374 - val otherBankRoutingScheme: String, // This is the scheme a consumer would use to specify the bank e.g. BIC - val otherBankRoutingAddress : Option[String], // The (BIC) value e.g. 67895 - val thisBankId : BankId, // i.e. the Account that sends/receives money to/from this Counterparty - val thisAccountId: AccountId, // These 2 fields specify the account that uses this Counterparty - val otherBankId : BankId, // These 3 fields specify the internal locaiton of the account for the - val otherAccountId: AccountId, //counterparty if it is known. It could be at OBP in which case - val otherAccountProvider: String, // hasBankId and hasAccountId would refer to an OBP account - val isBeneficiary: Boolean // True if the originAccount can send money to the Counterparty - ) -{ - - val metadata : CounterpartyMetadata = { - // If we already have alreadyFoundMetadata, return it, else get or create it. - alreadyFoundMetadata match { - case Some(meta) => - meta - case None => - Counterparties.counterparties.vend.getOrCreateMetadata(otherBankId, otherAccountId, this).openOrThrowException("Can not getOrCreateMetadata !") - } - } + + @deprecated("older version, please first consider the V210, account scheme and address") + val nationalIdentifier: String, // This is the scheme a consumer would use to instruct a payment e.g. IBAN +// @deprecated("older version, please first consider the V210, account scheme and address") + //val alreadyFoundMetadata : Option[CounterpartyMetadata], + @deprecated("older version, please use name instead") + val label: String, // Reference given to the counterparty by the original party. + val kind: String, // Type of bank account. + + // The following fields started from V210 + val counterPartyId: String, + val name: String, + val otherAccountRoutingScheme: String, // This is the scheme a consumer would use to instruct a payment e.g. IBAN + val otherAccountRoutingAddress: Option[String], // The (IBAN) value e.g. 2349870987820374 + val otherBankRoutingScheme: String, // This is the scheme a consumer would use to specify the bank e.g. BIC + val otherBankRoutingAddress: Option[String], // The (BIC) value e.g. 67895 + val thisBankId: BankId, // i.e. the Account that sends/receives money to/from this Counterparty + val thisAccountId: AccountId, // These 2 fields specify the account that uses this Counterparty + val otherAccountProvider: String, // hasBankId and hasAccountId would refer to an OBP account + val isBeneficiary: Boolean // True if the originAccount can send money to the Counterparty +) { + val metadata: CounterpartyMetadata = Counterparties.counterparties.vend.getOrCreateMetadata( + thisBankId, + thisAccountId, + counterPartyId, + name + ).openOrThrowException("Can not getOrCreateMetadata !") } trait TransactionUUID { diff --git a/src/main/scala/code/model/Metadata.scala b/src/main/scala/code/model/Metadata.scala index 34c9ee2b1..7d68c9087 100644 --- a/src/main/scala/code/model/Metadata.scala +++ b/src/main/scala/code/model/Metadata.scala @@ -106,7 +106,7 @@ Counterparty metadata trait CounterpartyMetadata { def metadataId: String def getHolder: String - def getAccountNumber: String +// def getAccountNumber: String def getPublicAlias: String def getPrivateAlias: String def getMoreInfo: String diff --git a/src/main/scala/code/remotedata/RemotedataCounterparties.scala b/src/main/scala/code/remotedata/RemotedataCounterparties.scala index 1170f67e8..5cf807f96 100644 --- a/src/main/scala/code/remotedata/RemotedataCounterparties.scala +++ b/src/main/scala/code/remotedata/RemotedataCounterparties.scala @@ -16,8 +16,8 @@ object RemotedataCounterparties extends ObpActorInit with Counterparties { val cc = RemotedataCounterpartiesCaseClasses - override def getOrCreateMetadata(originalPartyBankId: BankId, originalPartyAccountId: AccountId, otherParty: Counterparty): Box[CounterpartyMetadata] = - extractFutureToBox(actor ? cc.getOrCreateMetadata(originalPartyBankId: BankId, originalPartyAccountId: AccountId, otherParty: Counterparty)) + override def getOrCreateMetadata(bankId: BankId, accountId: AccountId, counterpartyId:String, counterpartyName:String): Box[CounterpartyMetadata] = + extractFutureToBox(actor ? cc.getOrCreateMetadata(bankId: BankId, accountId: AccountId, counterpartyId:String, counterpartyName:String)) override def getMetadatas(originalPartyBankId: BankId, originalPartyAccountId: AccountId): List[CounterpartyMetadata] = extractFuture(actor ? cc.getMetadatas(originalPartyBankId: BankId, originalPartyAccountId: AccountId)) diff --git a/src/main/scala/code/remotedata/RemotedataCounterpartiesActor.scala b/src/main/scala/code/remotedata/RemotedataCounterpartiesActor.scala index 70fc3a3d4..f1eb574f4 100644 --- a/src/main/scala/code/remotedata/RemotedataCounterpartiesActor.scala +++ b/src/main/scala/code/remotedata/RemotedataCounterpartiesActor.scala @@ -53,9 +53,9 @@ class RemotedataCounterpartiesActor extends Actor with ObpActorHelper with MdcLo bespoke: List[PostCounterpartyBespoke] )) - case cc.getOrCreateMetadata(originalPartyBankId: BankId, originalPartyAccountId: AccountId, otherParty: Counterparty) => - logger.debug("getOrCreateMetadata(" + originalPartyBankId +", " +originalPartyAccountId+otherParty+")") - sender ! extractResult(mapper.getOrCreateMetadata(originalPartyBankId: BankId, originalPartyAccountId: AccountId, otherParty: Counterparty)) + case cc.getOrCreateMetadata(bankId: BankId, accountId: AccountId, counterpartyId:String, counterpartyName:String) => + logger.debug("getOrCreateMetadata(" + bankId +", " +accountId+counterpartyName+")") + sender ! extractResult(mapper.getOrCreateMetadata(bankId: BankId, accountId: AccountId, counterpartyId:String, counterpartyName:String)) case cc.getMetadatas(originalPartyBankId: BankId, originalPartyAccountId: AccountId) => logger.debug("getOrCreateMetadata(" + originalPartyBankId +", "+originalPartyAccountId+")") diff --git a/src/main/scala/code/transaction/MappedTransaction.scala b/src/main/scala/code/transaction/MappedTransaction.scala index fe80570b7..12723dca2 100644 --- a/src/main/scala/code/transaction/MappedTransaction.scala +++ b/src/main/scala/code/transaction/MappedTransaction.scala @@ -2,6 +2,7 @@ package code.transaction import java.util.UUID +import code.api.util.APIUtil import code.bankconnectors.Connector import code.util._ import net.liftweb.common.Logger @@ -55,7 +56,7 @@ class MappedTransaction extends LongKeyedMapper[MappedTransaction] with IdPK wit object CPOtherBankId extends MappedString(this, 36) object CPOtherAccountId extends AccountIdString(this) object CPOtherAccountProvider extends MappedString(this, 36) - object CPCounterPartyId extends MappedString(this, 36) + object CPCounterPartyId extends UUIDString(this) object CPOtherAccountRoutingScheme extends MappedString(this, 255) object CPOtherAccountRoutingAddress extends MappedString(this, 255) object CPOtherBankRoutingScheme extends MappedString(this, 255) @@ -100,23 +101,21 @@ class MappedTransaction extends LongKeyedMapper[MappedTransaction] with IdPK wit val amt = Helper.smallestCurrencyUnitToBigDecimal(amount.get, transactionCurrency) val newBalance = Helper.smallestCurrencyUnitToBigDecimal(newAccountBalance.get, transactionCurrency) - def createCounterparty(alreadyFoundMetadata : Option[CounterpartyMetadata]) = { + //TODO This method should be as general as possible, need move to general object, not here. + def createCounterparty(counterpartyId : String) = { new Counterparty( - counterPartyId = alreadyFoundMetadata.map(_.metadataId).getOrElse(""), - label = counterpartyAccountHolder.get, - nationalIdentifier = counterpartyNationalId.get, - otherBankRoutingAddress = None, - otherAccountRoutingAddress = getCounterpartyIban(), - thisAccountId = AccountId(counterpartyAccountNumber.get), - thisBankId = BankId(counterpartyBankName.get), + counterPartyId = counterpartyId, kind = counterpartyAccountKind.get, - otherBankId = theBankId, - otherAccountId = theAccountId, - alreadyFoundMetadata = alreadyFoundMetadata, - name = "", - otherBankRoutingScheme = "", - otherAccountRoutingScheme="", + nationalIdentifier = counterpartyNationalId.get, + label = counterpartyAccountHolder.get, + name = counterpartyAccountHolder.get, + thisAccountId = AccountId(counterpartyAccountNumber.get), //TODO? explain why map this?? we need create counterparty for all connectors, can not get it sometimes. + thisBankId = BankId(counterpartyBankName.get), //TODO? explain why map this??we need create counterparty for all connectors, can not get it sometimes. otherAccountProvider = "", + otherBankRoutingScheme = "", + otherBankRoutingAddress = None, + otherAccountRoutingScheme="", + otherAccountRoutingAddress = getCounterpartyIban(), isBeneficiary = true ) } @@ -125,13 +124,10 @@ class MappedTransaction extends LongKeyedMapper[MappedTransaction] with IdPK wit //it doesn't exist when an OtherBankAccount object is created. The issue here is that for legacy reasons //otherAccount ids are metadata ids, so the metadata needs to exist before we created the OtherBankAccount //so that we know what id to give it. - - //creates a dummy OtherBankAccount without an OtherBankAccountMetadata, which results in one being generated (in OtherBankAccount init) - val dummyOtherBankAccount = createCounterparty(None) - - //and create the proper OtherBankAccount with the correct "id" attribute set to the metadataId of the OtherBankAccountMetadata object - //note: as we are passing in the OtherBankAccountMetadata we don't incur another db call to get it in OtherBankAccount init - val otherAccount = createCounterparty(Some(dummyOtherBankAccount.metadata)) + //--> now it is clear, we create the counterpartyId first, and assign it to metadata.counterpartyId and counterparty.counterpartyId manually + val counterpartyName = description+CPOtherAccountRoutingAddress.get+counterpartyAccountNumber.get + val counterpartyId = APIUtil.createImplicitCounterpartyId(theBankId.value, theAccountId.value, counterpartyName) + val otherAccount = createCounterparty(counterpartyId) Some(new Transaction( transactionUUID.get, diff --git a/src/main/scripts/migrate/migrate_00000010.sql b/src/main/scripts/migrate/migrate_00000010.sql new file mode 100644 index 000000000..73a989822 --- /dev/null +++ b/src/main/scripts/migrate/migrate_00000010.sql @@ -0,0 +1,3 @@ +ALTER TABLE "mappedcounterpartymetadata" ALTER COLUMN "counterpartyid" type varchar(44); +ALTER TABLE "mappedcounterparty" ALTER COLUMN "mcounterpartyid" type varchar(44); +ALTER TABLE "mappedtransaction" ALTER COLUMN "cpcounterpartyid" type varchar(44); \ No newline at end of file diff --git a/src/test/scala/code/sandbox/SandboxDataLoadingTest.scala b/src/test/scala/code/sandbox/SandboxDataLoadingTest.scala index e35257f5d..efdea180a 100644 --- a/src/test/scala/code/sandbox/SandboxDataLoadingTest.scala +++ b/src/test/scala/code/sandbox/SandboxDataLoadingTest.scala @@ -338,8 +338,8 @@ class SandboxDataLoadingTest extends FlatSpec with SendServerRequests with Match //a counterparty should exist val otherAcc = foundTransaction.otherAccount otherAcc.counterPartyId should not be empty - otherAcc.otherAccountId should equal(accountId) - otherAcc.otherBankId should equal(bankId) +// otherAcc.otherAccountId should equal(accountId) +// otherAcc.otherBankId should equal(bankId) val otherAccMeta = otherAcc.metadata otherAccMeta.getPublicAlias should not be empty