Merge pull request #854 from hongwei1/develop

implement new way to create Counterparty and CounterpartyMetadata.
This commit is contained in:
Simon Redfern 2017-12-05 10:29:35 +01:00 committed by GitHub
commit f1276ce3e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 243 additions and 174 deletions

View File

@ -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")
}

View File

@ -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
/**

View File

@ -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="",

View File

@ -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="",

View File

@ -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(""))

View File

@ -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="",

View File

@ -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="",

View File

@ -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),

View File

@ -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",

View File

@ -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)

View File

@ -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)

View File

@ -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)
}
}

View File

@ -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)

View File

@ -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 {

View File

@ -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

View File

@ -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))

View File

@ -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+")")

View File

@ -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,

View File

@ -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);

View File

@ -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