diff --git a/src/main/scala/code/api/util/APIUtil.scala b/src/main/scala/code/api/util/APIUtil.scala index 5f850da76..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 @@ -1846,7 +1847,7 @@ Versions are groups of endpoints in a file * We also can create the Id manually. * eg: CounterpartyId, because we use this Id both for Counterparty and counterpartyMetaData by some input fields. */ - def createOrGetOBPId(in:String)= { + 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("=") @@ -1854,4 +1855,38 @@ Versions are groups of endpoints in a file 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 4fd415148..3af7d59e7 100644 --- a/src/main/scala/code/bankconnectors/Connector.scala +++ b/src/main/scala/code/bankconnectors/Connector.scala @@ -295,13 +295,40 @@ trait Connector extends MdcLoggable{ val x = for { transaction <- transactions - counterpartyId <- List(APIUtil.createOrGetOBPId(bankId.value+accountId.value+transaction.description.getOrElse(""))) + 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, 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) @@ -347,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(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 - ) - ) - } //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 3cd72ea9f..191645017 100644 --- a/src/main/scala/code/bankconnectors/KafkaMappedConnector.scala +++ b/src/main/scala/code/bankconnectors/KafkaMappedConnector.scala @@ -1180,7 +1180,7 @@ object KafkaMappedConnector extends Connector with KafkaHelper with MdcLoggable kind = "", // otherBankId = o.bankId, // otherAccountId = o.accountId, - alreadyFoundMetadata = alreadyFoundMetadata, +// 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 c72e22a32..dfe7ac60f 100644 --- a/src/main/scala/code/bankconnectors/KafkaMappedConnector_JVMcompatible.scala +++ b/src/main/scala/code/bankconnectors/KafkaMappedConnector_JVMcompatible.scala @@ -1384,7 +1384,7 @@ object KafkaMappedConnector_JVMcompatible extends Connector with KafkaHelper wit kind = "", // otherBankId = o.bankId, // otherAccountId = o.accountId, - alreadyFoundMetadata = alreadyFoundMetadata, +// alreadyFoundMetadata = alreadyFoundMetadata, name = "", otherBankRoutingScheme = "", otherAccountRoutingScheme="", diff --git a/src/main/scala/code/bankconnectors/LocalMappedConnector.scala b/src/main/scala/code/bankconnectors/LocalMappedConnector.scala index 45ae08239..e39fcbaab 100644 --- a/src/main/scala/code/bankconnectors/LocalMappedConnector.scala +++ b/src/main/scala/code/bankconnectors/LocalMappedConnector.scala @@ -335,7 +335,7 @@ object LocalMappedConnector extends Connector with MdcLoggable { kind = "", // otherBankId = thisBankId, // otherAccountId = thisAccountId, - alreadyFoundMetadata = Some(t), +// alreadyFoundMetadata = Some(t), name = "", otherBankRoutingScheme = "", otherAccountRoutingScheme="", diff --git a/src/main/scala/code/bankconnectors/LocalRecordConnector.scala b/src/main/scala/code/bankconnectors/LocalRecordConnector.scala index f068693ca..5a38e4440 100644 --- a/src/main/scala/code/bankconnectors/LocalRecordConnector.scala +++ b/src/main/scala/code/bankconnectors/LocalRecordConnector.scala @@ -239,7 +239,7 @@ private object LocalRecordConnector extends Connector with MdcLoggable { kind = otherAccount_.kind.get, // otherBankId = theAccount.bankId, // otherAccountId = theAccount.accountId, - alreadyFoundMetadata = Some(metadata), +// alreadyFoundMetadata = Some(metadata), name = "", otherBankRoutingScheme = "", otherAccountRoutingScheme="", @@ -394,7 +394,7 @@ private object LocalRecordConnector extends Connector with MdcLoggable { kind = "", // otherBankId = originalPartyBankId, // otherAccountId = originalPartyAccountId, - alreadyFoundMetadata = Some(otherAccount), +// 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 89b937ea5..503b6a2bb 100644 --- a/src/main/scala/code/bankconnectors/ObpJvmMappedConnector.scala +++ b/src/main/scala/code/bankconnectors/ObpJvmMappedConnector.scala @@ -1144,7 +1144,7 @@ object ObpJvmMappedConnector extends Connector with MdcLoggable { kind = "", // otherBankId = o.bankId, // otherAccountId = o.accountId, - alreadyFoundMetadata = alreadyFoundMetadata, +// 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 a2aabca5c..3db036f05 100644 --- a/src/main/scala/code/bankconnectors/vJune2017/KafkaMappedConnector_vJune2017.scala +++ b/src/main/scala/code/bankconnectors/vJune2017/KafkaMappedConnector_vJune2017.scala @@ -1454,7 +1454,7 @@ trait KafkaMappedConnector_vJune2017 extends Connector with KafkaHelper with Mdc // 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 3645cc92f..9a47f623b 100644 --- a/src/main/scala/code/bankconnectors/vMar2017/KafkaMappedConnector_vMar2017.scala +++ b/src/main/scala/code/bankconnectors/vMar2017/KafkaMappedConnector_vMar2017.scala @@ -1787,7 +1787,7 @@ trait KafkaMappedConnector_vMar2017 extends Connector with KafkaHelper with MdcL kind = "1234", // otherBankId = o.bankId, // otherAccountId = o.accountId, - alreadyFoundMetadata = alreadyFoundMetadata, +// alreadyFoundMetadata = alreadyFoundMetadata, name = "sushan", otherBankRoutingScheme = "obp", otherAccountRoutingScheme="obp", diff --git a/src/main/scala/code/metadata/counterparties/MapperCounterparties.scala b/src/main/scala/code/metadata/counterparties/MapperCounterparties.scala index c0ad350ec..ccb8ebd2b 100644 --- a/src/main/scala/code/metadata/counterparties/MapperCounterparties.scala +++ b/src/main/scala/code/metadata/counterparties/MapperCounterparties.scala @@ -18,6 +18,7 @@ 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 { + //TODO, this method need to be cached later. override def getOrCreateMetadata(bankId: BankId, accountId: AccountId, counterpartyId: String, counterpartyName:String): Box[CounterpartyMetadata] = { /** @@ -148,11 +149,24 @@ object MapperCounterparties extends Counterparties with MdcLoggable { bespoke: List[PostCounterpartyBespoke] ): Box[CounterpartyTrait] = { - val counterpartyId = APIUtil.createOrGetOBPId(s"EXPLICIT" + - s"$thisBankId$thisAccountId$thisViewId$name$otherAccountRoutingScheme" + - s"$otherAccountRoutingAddress$otherBankRoutingScheme$otherBankRoutingAddress$otherBranchRoutingScheme" + - s"$otherBranchRoutingAddress$isBeneficiary$otherAccountSecondaryRoutingScheme$otherAccountSecondaryRoutingAddress" + - s"$description${bespoke.map(_.value)}") + 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 !") diff --git a/src/main/scala/code/model/BankingData.scala b/src/main/scala/code/model/BankingData.scala index 597777aad..225ddae97 100644 --- a/src/main/scala/code/model/BankingData.scala +++ b/src/main/scala/code/model/BankingData.scala @@ -657,40 +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 => - val counterpartyId = APIUtil.createOrGetOBPId(thisBankId.value+thisAccountId.value+label) - val counterpartyName = label - Counterparties.counterparties.vend.getOrCreateMetadata(thisBankId, thisAccountId, counterpartyId, counterpartyName).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/transaction/MappedTransaction.scala b/src/main/scala/code/transaction/MappedTransaction.scala index 125f71e18..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 @@ -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), //TODO? explain why map this?? - thisBankId = BankId(counterpartyBankName.get), //TODO? explain why map this?? + counterPartyId = counterpartyId, kind = counterpartyAccountKind.get, -// otherBankId = theBankId, //TODO? explain why map this?? -// otherAccountId = theAccountId, //TODO? explain why map this?? - 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,