mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 13:07:02 +00:00
feature/Remove Record support (mongo DB support) so we can update to Liftweb 3.5.0
This commit is contained in:
parent
3b53b4689a
commit
7dc98ee938
@ -169,16 +169,6 @@
|
||||
<version>${jetty.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.liftweb</groupId>
|
||||
<artifactId>lift-mongodb_${scala.version}</artifactId>
|
||||
<version>${lift.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.liftweb</groupId>
|
||||
<artifactId>lift-mongodb-record_${scala.version}</artifactId>
|
||||
<version>${lift.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib</artifactId>
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
|
||||
#which data connector to use
|
||||
|
||||
#connector=mongodb
|
||||
#connector=rest
|
||||
#connector=kafka
|
||||
#connector=obpjvm
|
||||
|
||||
@ -332,12 +332,8 @@ class Boot extends MdcLoggable {
|
||||
|
||||
// ensure our relational database's tables are created/fit the schema
|
||||
val connector = APIUtil.getPropsValue("connector").openOrThrowException("no connector set")
|
||||
if(connector != "mongodb")
|
||||
schemifyAll()
|
||||
schemifyAll()
|
||||
|
||||
// This sets up MongoDB config (for the mongodb connector)
|
||||
if( connector == "mongodb")
|
||||
MongoConfig.init
|
||||
|
||||
val runningMode = Props.mode match {
|
||||
case Props.RunModes.Production => "Production mode"
|
||||
|
||||
@ -79,7 +79,6 @@ object Connector extends SimpleInjector {
|
||||
val nameToConnector: Map[String, () => Connector] = Map(
|
||||
"mapped" -> lazyValue(LocalMappedConnector),
|
||||
"akka_vDec2018" -> lazyValue(AkkaConnector_vDec2018),
|
||||
"mongodb" -> lazyValue(LocalRecordConnector),
|
||||
"kafka_vSept2018" -> lazyValue(KafkaMappedConnector_vSept2018),
|
||||
"kafka_vMay2019" -> lazyValue(KafkaMappedConnector_vMay2019),
|
||||
"rest_vMar2019" -> lazyValue(RestConnector_vMar2019),
|
||||
|
||||
@ -1,540 +0,0 @@
|
||||
package code.bankconnectors
|
||||
|
||||
import java.util.{Date, TimeZone}
|
||||
|
||||
import code.api.util.ErrorMessages._
|
||||
import code.api.util._
|
||||
import code.management.ImporterAPI.ImporterTransaction
|
||||
import code.metadata.counterparties.{Counterparties, Metadata, MongoCounterparties}
|
||||
import code.model._
|
||||
import code.model.dataAccess._
|
||||
import code.util.Helper
|
||||
import code.util.Helper.MdcLoggable
|
||||
import com.mongodb.QueryBuilder
|
||||
import com.openbankproject.commons.model._
|
||||
import com.tesobe.model.UpdateBankAccount
|
||||
import net.liftweb.common.{Box, Empty, Failure, Full}
|
||||
import net.liftweb.json.Extraction
|
||||
import net.liftweb.json.JsonAST.JValue
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
import net.liftweb.util.Helpers._
|
||||
import org.bson.types.ObjectId
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import com.openbankproject.commons.model.enums.AccountRoutingScheme
|
||||
|
||||
import scala.collection.immutable.List
|
||||
import scala.concurrent._
|
||||
|
||||
private object LocalRecordConnector extends Connector with MdcLoggable {
|
||||
|
||||
implicit override val nameOfConnector = LocalRecordConnector.getClass.getSimpleName
|
||||
|
||||
override def getBankLegacy(bankId : BankId, callContext: Option[CallContext]) =
|
||||
getHostedBank(bankId).map(bank =>(bank, callContext))
|
||||
|
||||
//gets banks handled by this connector
|
||||
override def getBanksLegacy(callContext: Option[CallContext]) =
|
||||
Full(HostedBank.findAll, callContext)
|
||||
|
||||
override def getBankAccountLegacy(bankId : BankId, accountId : AccountId, callContext: Option[CallContext]) : Box[(BankAccount, Option[CallContext])] = {
|
||||
for{
|
||||
bank <- getHostedBank(bankId)
|
||||
account <- bank.getAccount(accountId)
|
||||
} yield (account,callContext)
|
||||
}
|
||||
|
||||
|
||||
override def getCounterpartyFromTransaction(bankId: BankId, accountId : AccountId, counterpartyID : String): Box[Counterparty] = {
|
||||
|
||||
/**
|
||||
* In this implementation (for legacy reasons), the "otherAccountID" is actually the mongodb id of the
|
||||
* "other account metadata" object.
|
||||
*/
|
||||
|
||||
for{
|
||||
objId <- tryo{ new ObjectId(counterpartyID) }
|
||||
otherAccountmetadata <- {
|
||||
//"otherAccountID" is actually the mongodb id of the other account metadata" object.
|
||||
val query = QueryBuilder.
|
||||
start("_id").is(objId)
|
||||
.put("originalPartyBankId").is(bankId.value)
|
||||
.put("originalPartyAccountId").is(accountId.value).get()
|
||||
Metadata.find(query)
|
||||
}
|
||||
} 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()
|
||||
|
||||
val otherAccountFromTransaction : OBPAccount = OBPEnvelope.find(query) match {
|
||||
case Full(envelope) => envelope.obp_transaction.get.other_account.get
|
||||
case _ => {
|
||||
logger.warn("no other account found")
|
||||
OBPAccount.createRecord
|
||||
}
|
||||
}
|
||||
createOtherBankAccount(bankId, accountId, otherAccountmetadata, otherAccountFromTransaction)
|
||||
}
|
||||
}
|
||||
|
||||
override def getCounterpartiesFromTransaction(bankId: BankId, accountId : AccountId) = {
|
||||
|
||||
/**
|
||||
* In this implementation (for legacy reasons), the "otherAccountID" is actually the mongodb id of the
|
||||
* "other account metadata" object.
|
||||
*/
|
||||
|
||||
Full(Counterparties.counterparties.vend.getMetadatas(bankId, accountId).map(meta => {
|
||||
//for legacy reasons some of the data about the "other account" are stored only on the transactions
|
||||
//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.getCounterpartyName)
|
||||
// .put("obp_transaction.other_account.number").is(meta.getAccountNumber)
|
||||
.get()
|
||||
|
||||
val otherAccountFromTransaction : OBPAccount = OBPEnvelope.find(query) match {
|
||||
case Full(envelope) => {
|
||||
envelope.obp_transaction.get.other_account.get
|
||||
}
|
||||
case _ => {
|
||||
logger.warn(s"envelope not found for other account ${meta.getCounterpartyId}")
|
||||
OBPAccount.createRecord
|
||||
}
|
||||
}
|
||||
createOtherBankAccount(bankId, accountId, meta, otherAccountFromTransaction)
|
||||
}))
|
||||
}
|
||||
|
||||
override def getTransactionsLegacy(bankId: BankId, accountId: AccountId, callContext: Option[CallContext], queryParams: List[OBPQueryParam]) = {
|
||||
logger.debug("getTransactions for " + bankId + "/" + accountId)
|
||||
val transactions = for{
|
||||
bank <- getHostedBank(bankId)
|
||||
account <- bank.getAccount(accountId)
|
||||
} yield {
|
||||
updateAccountTransactions(bank, account)
|
||||
account.envelopes(queryParams).map(createTransaction(_, account))
|
||||
}
|
||||
transactions.map( transactions => (transactions, callContext))
|
||||
}
|
||||
|
||||
override def getTransactionLegacy(bankId: BankId, accountId : AccountId, transactionId : TransactionId, callContext: Option[CallContext])= {
|
||||
for{
|
||||
bank <- getHostedBank(bankId) ?~! s"Transaction not found: bank $bankId not found"
|
||||
account <- bank.getAccount(accountId) ?~! s"Transaction not found: account $accountId not found"
|
||||
envelope <- OBPEnvelope.find(account.transactionsForAccount.put("transactionId").is(transactionId.value).get)
|
||||
} yield {
|
||||
updateAccountTransactions(bank, account)
|
||||
(createTransaction(envelope,account), callContext)
|
||||
}
|
||||
}
|
||||
|
||||
override protected def makePaymentImpl(fromAccount: BankAccount, toAccount: BankAccount, transactionRequestCommonBody: TransactionRequestCommonBodyJSON, amt: BigDecimal, description: String, transactionRequestType: TransactionRequestType, chargePolicy: String): Box[TransactionId] = {
|
||||
val fromTransAmt = -amt //from account balance should decrease
|
||||
val toTransAmt = amt //to account balance should increase
|
||||
|
||||
//this is the transaction that gets attached to the account of the person making the payment
|
||||
val createdFromTrans = saveNewTransaction(fromAccount, fromTransAmt, description)
|
||||
|
||||
// this creates the transaction that gets attached to the account of the person receiving the payment
|
||||
// saveNewTransaction(toAccount, fromAccount, toTransAmt, description)
|
||||
|
||||
//assumes OBPEnvelope id is what gets used as the Transaction id in the API. If that gets changed, this needs to
|
||||
//be updated (the tests should fail if it doesn't)
|
||||
createdFromTrans.map(t => TransactionId(t.transactionId.get))
|
||||
}
|
||||
|
||||
private def createTransaction(env: OBPEnvelope, theAccount: Account): Transaction = {
|
||||
val transaction: OBPTransaction = env.obp_transaction.get
|
||||
val otherAccount_ = transaction.other_account.get
|
||||
|
||||
val id = TransactionId(env.transactionId.get)
|
||||
val uuid = id.value
|
||||
|
||||
//slight hack required: otherAccount id is, for legacy reasons, the mongodb id of its metadata object
|
||||
//so we have to find that
|
||||
val query = QueryBuilder.start("originalPartyBankId").is(theAccount.bankId.value).
|
||||
put("originalPartyAccountId").is(theAccount.permalink.get).
|
||||
put("accountNumber").is(otherAccount_.number.get).
|
||||
put("holder").is(otherAccount_.holder.get).get
|
||||
|
||||
|
||||
//it's a bit confusing what's going on here, as normally metadata should be automatically generated if
|
||||
//it doesn't exist when an OtherBankAccount object is created. The issue here is that for legacy reasons
|
||||
//otherAccount ids are mongo metadata ids, so the metadata needs to exist before we created the OtherBankAccount
|
||||
//so that we know what id to give it. That's why there's a hardcoded dependency on MongoCounterparties.
|
||||
val metadata = Metadata.find(query) match {
|
||||
case Full(m) => m
|
||||
case _ => MongoCounterparties.createMetadata(
|
||||
theAccount.bankId,
|
||||
theAccount.accountId,
|
||||
otherAccount_.holder.get,
|
||||
otherAccount_.number.get)
|
||||
}
|
||||
|
||||
val otherAccount = new Counterparty(
|
||||
counterpartyId = metadata.getCounterpartyId,
|
||||
counterpartyName = otherAccount_.holder.get,
|
||||
nationalIdentifier = otherAccount_.bank.get.national_identifier.get,
|
||||
otherBankRoutingAddress = None,
|
||||
otherAccountRoutingAddress = Some(otherAccount_.bank.get.IBAN.get),
|
||||
thisAccountId = AccountId(otherAccount_.number.get),
|
||||
thisBankId = BankId(otherAccount_.bank.get.name.get),
|
||||
kind = otherAccount_.kind.get,
|
||||
otherBankRoutingScheme = "",
|
||||
otherAccountRoutingScheme="",
|
||||
otherAccountProvider = "",
|
||||
isBeneficiary = true
|
||||
)
|
||||
val transactionType = transaction.details.get.kind.get
|
||||
val amount = transaction.details.get.value.get.amount.get
|
||||
val currency = transaction.details.get.value.get.currency.get
|
||||
val label = Some(transaction.details.get.label.get)
|
||||
val startDate = transaction.details.get.posted.get
|
||||
val finishDate = transaction.details.get.completed.get
|
||||
val balance = transaction.details.get.new_balance.get.amount.get
|
||||
|
||||
new Transaction(
|
||||
uuid,
|
||||
id,
|
||||
theAccount,
|
||||
otherAccount,
|
||||
transactionType,
|
||||
amount,
|
||||
currency,
|
||||
label,
|
||||
startDate,
|
||||
finishDate,
|
||||
balance)
|
||||
}
|
||||
|
||||
private def saveNewTransaction(account : BankAccount, amount : BigDecimal, description : String) : Box[OBPEnvelope] = {
|
||||
|
||||
val oldBalance = account.balance
|
||||
|
||||
def saveAndUpdateAccountBalance(transactionJS : JValue, thisAccount : BankAccount) : Box[OBPEnvelope] = {
|
||||
|
||||
val envelope: Box[OBPEnvelope] = OBPEnvelope.envelopesFromJValue(transactionJS)
|
||||
|
||||
val account = thisAccount.asInstanceOf[Account]
|
||||
if(envelope.isDefined) {
|
||||
val e : OBPEnvelope = envelope.openOrThrowException(attemptedToOpenAnEmptyBox)
|
||||
logger.debug(s"Updating current balance for ${account.bankName} / ${account.accountNumber} / ${account.accountType}")
|
||||
account.accountBalance(e.obp_transaction.get.details.get.new_balance.get.amount.get).save(true)
|
||||
logger.debug("Saving new transaction")
|
||||
Full(e.save(true))
|
||||
} else {
|
||||
Failure("couldn't save transaction")
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
// otherBank <- Connector.connector.vend.getBank(otherAccount.bankId) ?~! "no other bank found"
|
||||
transTime <- Full(now)
|
||||
//mongodb/the lift mongo thing wants a literal Z in the timestamp, apparently
|
||||
envJsonDateFormat = {
|
||||
val simpleDateFormat = APIUtil.DateWithMsFormat
|
||||
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"))
|
||||
simpleDateFormat
|
||||
}
|
||||
|
||||
envJson =
|
||||
"obp_transaction" ->
|
||||
("this_account" ->
|
||||
// ("holder" -> account.owners.headOption.map(_.name).getOrElse("")) ~ //TODO: this is rather fragile...
|
||||
("number" -> account.number) ~
|
||||
("kind" -> account.accountType) ~
|
||||
("bank" ->
|
||||
("IBAN" -> account.accountRoutings.find(_.scheme == AccountRoutingScheme.IBAN.toString).map(_.address).getOrElse("")) ~
|
||||
("national_identifier" -> account.nationalIdentifier) ~
|
||||
("name" -> account.bankId.value))) ~
|
||||
// ("other_account" ->
|
||||
//// ("holder" -> otherAccount.accountHolder) ~
|
||||
//// ("number" -> otherAccount.number) ~
|
||||
//// ("kind" -> otherAccount.accountType) ~
|
||||
// ("bank" ->
|
||||
// ("IBAN" -> "") ~
|
||||
//// ("national_identifier" -> otherBank.nationalIdentifier) ~
|
||||
//// ("name" -> otherBank.fullName))) ~
|
||||
("details" ->
|
||||
("type_en" -> "") ~
|
||||
("type_de" -> "") ~
|
||||
("posted" ->
|
||||
("$dt" -> envJsonDateFormat.format(transTime))
|
||||
) ~
|
||||
("completed" ->
|
||||
("$dt" -> envJsonDateFormat.format(transTime))
|
||||
) ~
|
||||
("new_balance" ->
|
||||
("currency" -> account.currency) ~
|
||||
("amount" -> (oldBalance + amount).toString)) ~
|
||||
("value" ->
|
||||
("currency" -> account.currency) ~
|
||||
("amount" -> amount.toString)))
|
||||
saved <- saveAndUpdateAccountBalance(envJson, account)
|
||||
} yield {
|
||||
saved
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the last update of the account was made more than one hour ago.
|
||||
* if it is the case we put a message in the message queue to ask for
|
||||
* transactions updates
|
||||
*
|
||||
* It will be used each time we fetch transactions from the DB. But the test
|
||||
* is performed in a different thread.
|
||||
*/
|
||||
|
||||
private def updateAccountTransactions(bank: HostedBank, account: Account): Unit = {
|
||||
Future {
|
||||
val useMessageQueue = APIUtil.getPropsAsBoolValue("messageQueue.updateBankAccountsTransaction", false)
|
||||
val outDatedTransactions = now after time(account.accountLastUpdate.get.getTime + hours(APIUtil.getPropsAsIntValue("messageQueue.updateTransactionsInterval", 1)))
|
||||
if(outDatedTransactions && useMessageQueue) {
|
||||
UpdatesRequestSender.sendMsg(UpdateBankAccount(account.accountNumber.get, bank.national_identifier.get))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private def createOtherBankAccount(originalPartyBankId: BankId, originalPartyAccountId: AccountId,
|
||||
otherAccount : CounterpartyMetadata, otherAccountFromTransaction : OBPAccount) : Counterparty = {
|
||||
new Counterparty(
|
||||
counterpartyId = otherAccount.getCounterpartyId,
|
||||
counterpartyName = otherAccount.getCounterpartyName,
|
||||
nationalIdentifier = otherAccountFromTransaction.bank.get.national_identifier.get,
|
||||
otherBankRoutingAddress = None,
|
||||
otherAccountRoutingAddress = Some(otherAccountFromTransaction.bank.get.IBAN.get),
|
||||
thisAccountId = AccountId(otherAccountFromTransaction.number.get),
|
||||
thisBankId = BankId(otherAccountFromTransaction.bank.get.name.get),
|
||||
kind = "",
|
||||
otherBankRoutingScheme = "",
|
||||
otherAccountRoutingScheme="",
|
||||
otherAccountProvider = "",
|
||||
isBeneficiary = true
|
||||
)
|
||||
}
|
||||
|
||||
private def getHostedBank(bankId : BankId) : Box[HostedBank] = {
|
||||
HostedBank.find("permalink", bankId.value) ?~ {"bank " + bankId + " not found"}
|
||||
}
|
||||
|
||||
//Need to pass in @hostedBank because the Account model doesn't have any references to BankId, just to the mongo id of the Bank object (which itself does have the bank id)
|
||||
private def createAccount(hostedBank : HostedBank, accountId : AccountId, accountNumber: String,
|
||||
accountType: String, accountLabel: String, currency : String, initialBalance : BigDecimal, holderName : String) : BankAccount = {
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
Account.find(
|
||||
(Account.accountNumber.name -> accountNumber)~
|
||||
(Account.bankID.name -> hostedBank.id.get)
|
||||
) match {
|
||||
case Full(bankAccount) => {
|
||||
logger.debug(s"account with number ${bankAccount.accountNumber} at bank ${hostedBank.bankId} already exists. No need to create a new one.")
|
||||
bankAccount
|
||||
}
|
||||
case _ => {
|
||||
logger.debug("creating account record ")
|
||||
val bankAccount =
|
||||
Account
|
||||
.createRecord
|
||||
.accountBalance(initialBalance)
|
||||
.holder(holderName)
|
||||
.accountNumber(accountNumber)
|
||||
.kind(accountType)
|
||||
.accountLabel(accountLabel)
|
||||
.accountName("")
|
||||
.permalink(accountId.value)
|
||||
.bankID(hostedBank.id.get)
|
||||
.accountCurrency(currency)
|
||||
.accountIban("")
|
||||
.accountLastUpdate(now)
|
||||
.save(true)
|
||||
bankAccount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//creates a bank account (if it doesn't exist) and creates a bank (if it doesn't exist)
|
||||
override def createBankAndAccount(
|
||||
bankName: String,
|
||||
bankNationalIdentifier: String,
|
||||
accountNumber: String,
|
||||
accountType: String,
|
||||
accountLabel: String,
|
||||
currency: String,
|
||||
accountHolderName: String,
|
||||
branchId: String,
|
||||
accountRoutingScheme: String,
|
||||
accountRoutingAddress: String
|
||||
) = {
|
||||
|
||||
// TODO: use a more unique id for the long term
|
||||
val hostedBank = {
|
||||
// TODO: use a more unique id for the long term
|
||||
HostedBank.find(HostedBank.national_identifier.name, bankNationalIdentifier) match {
|
||||
case Full(b)=> {
|
||||
logger.debug(s"bank ${b.name} found")
|
||||
b
|
||||
}
|
||||
case _ =>{
|
||||
//TODO: if name is empty use bank id as name alias
|
||||
|
||||
//TODO: need to handle the case where generatePermalink returns a permalink that is already used for another bank
|
||||
|
||||
logger.debug(s"creating HostedBank")
|
||||
HostedBank
|
||||
.createRecord
|
||||
.name(bankName)
|
||||
.alias(bankName)
|
||||
.permalink(Helper.generatePermalink(bankName))
|
||||
.national_identifier(bankNationalIdentifier)
|
||||
.save(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val createdAccount = createAccount(hostedBank, AccountId(APIUtil.generateUUID()),
|
||||
accountNumber, accountType, accountLabel, currency, BigDecimal("0.00"), accountHolderName)
|
||||
|
||||
Full((hostedBank, createdAccount))
|
||||
}
|
||||
|
||||
|
||||
//for sandbox use -> allows us to check if we can generate a new test account with the given number
|
||||
override def accountExists(bankId: BankId, accountNumber: String) = {
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
|
||||
getHostedBank(bankId).map(_.id.get) match {
|
||||
case Full(mongoId) =>
|
||||
Full(Account.count((Account.accountNumber.name -> accountNumber) ~ (Account.bankID.name -> mongoId)) > 0)
|
||||
case _ =>
|
||||
logger.warn("tried to check account existence for an account at a bank that doesn't exist")
|
||||
Full(false)
|
||||
}
|
||||
}
|
||||
|
||||
override def removeAccount(bankId: BankId, accountId: AccountId) = {
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
for {
|
||||
account <- Account.find((Account.bankID.name -> bankId.value) ~ (Account.accountId.value -> accountId.value)) ?~
|
||||
s"No account found with number ${accountId} at bank with id ${bankId}: could not save envelope"
|
||||
} yield {
|
||||
account.delete_!
|
||||
}
|
||||
|
||||
Full(false)
|
||||
/* account
|
||||
} match {
|
||||
case Full(acc) => acc.
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//creates a bank account for an existing bank, with the appropriate values set
|
||||
override def createSandboxBankAccount(
|
||||
bankId: BankId,
|
||||
accountId: AccountId,
|
||||
accountNumber: String,
|
||||
accountType: String,
|
||||
accountLabel: String,
|
||||
currency: String,
|
||||
initialBalance: BigDecimal,
|
||||
accountHolderName: String,
|
||||
branchId: String,
|
||||
accountRoutings: List[AccountRouting]
|
||||
): Box[BankAccount] = {
|
||||
HostedBank.find(bankId) match {
|
||||
case Full(b) => Full(createAccount(b, accountId, accountNumber, accountType, accountLabel, currency, initialBalance, accountHolderName))
|
||||
case _ => Failure(s"Bank with id ${bankId.value} not found. Cannot create account at non-existing bank.")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//used by transaction import api call to check for duplicates
|
||||
override def getMatchingTransactionCount(bankNationalIdentifier : String, accountNumber : String, amount: String, completed: Date, otherAccountHolder: String) = {
|
||||
|
||||
val baseQuery = QueryBuilder.start("obp_transaction.details.value.amount")
|
||||
.is(amount)
|
||||
.put("obp_transaction.details.completed")
|
||||
.is(completed)
|
||||
.put("obp_transaction.this_account.bank.national_identifier")
|
||||
.is(bankNationalIdentifier)
|
||||
.put("obp_transaction.this_account.number")
|
||||
.is(accountNumber)
|
||||
|
||||
//this is refactored legacy code, and it seems the empty account holder check had to do with potentially missing
|
||||
//fields in the db. not sure if this is still required.
|
||||
if(otherAccountHolder.isEmpty){
|
||||
def emptyHolderOrEmptyString(holder: Box[String]): Boolean = {
|
||||
holder match {
|
||||
case Full(s) => s.isEmpty
|
||||
case _ => true
|
||||
}
|
||||
}
|
||||
|
||||
val partialMatches = OBPEnvelope.findAll(baseQuery.get())
|
||||
|
||||
Full(partialMatches.filter(e => {
|
||||
emptyHolderOrEmptyString(e.obp_transaction.get.other_account.get.holder.valueBox)
|
||||
}).size)
|
||||
}
|
||||
else{
|
||||
val qry = baseQuery.put("obp_transaction.other_account.holder").is(otherAccountHolder).get
|
||||
|
||||
val partialMatches = OBPEnvelope.count(qry)
|
||||
Full(partialMatches.toInt)//icky
|
||||
}
|
||||
}
|
||||
|
||||
//used by transaction import api
|
||||
override def createImportedTransaction(transaction: ImporterTransaction): Box[Transaction] = {
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
|
||||
implicit val formats = CustomJsonFormats.losslessFormats
|
||||
val asJValue = Extraction.decompose(transaction)
|
||||
|
||||
for {
|
||||
env <- OBPEnvelope.envelopesFromJValue(asJValue)
|
||||
nationalIdentifier = transaction.obp_transaction.this_account.bank.national_identifier
|
||||
bank <- HostedBank.find(HostedBank.national_identifier.name -> nationalIdentifier) ?~
|
||||
s"No bank found with national identifier ${nationalIdentifier} could not save envelope"
|
||||
accountNumber = transaction.obp_transaction.this_account.number
|
||||
account <- Account.find((Account.bankID.name -> bank.id.get) ~ (Account.accountNumber.name -> accountNumber)) ?~
|
||||
s"No account found with number ${accountNumber} at bank with id ${bank.bankId}: could not save envelope"
|
||||
savedEnv <- env.saveTheRecord() ?~ "Could not save envelope"
|
||||
} yield {
|
||||
createTransaction(savedEnv, account)
|
||||
}
|
||||
}
|
||||
|
||||
//used by the transaction import api
|
||||
override def updateAccountBalance(bankId: BankId, accountId: AccountId, newBalance: BigDecimal) = {
|
||||
getBankAccountOld(bankId, accountId).map(_.asInstanceOf[Account]) match {
|
||||
case Full(acc) =>
|
||||
acc.accountBalance(newBalance).saveTheRecord().isDefined
|
||||
Full(true)
|
||||
case _ =>
|
||||
Full(false)
|
||||
}
|
||||
}
|
||||
|
||||
override def setBankAccountLastUpdated(bankNationalIdentifier: String, accountNumber : String, updateDate: Date) = {
|
||||
Account.find(
|
||||
(Account.accountNumber.name -> accountNumber)~
|
||||
(Account.nationalIdentifier -> bankNationalIdentifier)
|
||||
) match {
|
||||
case Full(acc) => Full(acc.accountLastUpdate(updateDate).saveTheRecord().isDefined)
|
||||
case _ => logger.warn("can't set bank account.lastUpdated because the account was not found"); Full(false)
|
||||
}
|
||||
}
|
||||
|
||||
override def updateAccountLabel(bankId: BankId, accountId: AccountId, label: String) = {
|
||||
getBankAccountOld(bankId, accountId).map(_.asInstanceOf[Account]) match {
|
||||
case Full(acc) =>
|
||||
acc.accountLabel(label).saveTheRecord().isDefined
|
||||
Full(true)
|
||||
case _ =>
|
||||
Full(false)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,81 +0,0 @@
|
||||
package code.metadata.comments
|
||||
|
||||
import code.model._
|
||||
import java.util.Date
|
||||
|
||||
import code.util.Helper.MdcLoggable
|
||||
import net.liftweb.common.{Box, Full}
|
||||
import org.bson.types.ObjectId
|
||||
import com.mongodb.{DBObject, QueryBuilder}
|
||||
import com.openbankproject.commons.model._
|
||||
import net.liftweb.mongodb.record.{MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.mongodb.record.field.{DateField, ObjectIdPk}
|
||||
import net.liftweb.record.field.{LongField, StringField}
|
||||
|
||||
private object MongoTransactionComments extends Comments {
|
||||
|
||||
|
||||
def getComments(bankId : BankId, accountId : AccountId, transactionId : TransactionId)(viewId : ViewId) : List[Comment] = {
|
||||
OBPComment.findAll(bankId, accountId, transactionId, viewId)
|
||||
}
|
||||
def addComment(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(userId: UserPrimaryKey, viewId : ViewId, text : String, datePosted : Date) : Box[Comment] = {
|
||||
OBPComment.createRecord.userId(userId.value).
|
||||
transactionId(transactionId.value).
|
||||
accountId(accountId.value).
|
||||
bankId(bankId.value).
|
||||
textField(text).
|
||||
date(datePosted).
|
||||
forView(viewId.value).saveTheRecord()
|
||||
}
|
||||
|
||||
def deleteComment(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(commentId : String) : Box[Boolean] = {
|
||||
//use delete with find query to avoid concurrency issues
|
||||
OBPComment.delete(OBPComment.getFindQuery(bankId, accountId, transactionId, commentId))
|
||||
|
||||
//we don't have any useful information here so just assume it worked
|
||||
Full(true)
|
||||
}
|
||||
|
||||
def bulkDeleteComments(bankId: BankId, accountId: AccountId): Boolean = ???
|
||||
def bulkDeleteCommentsOnTransaction(bankId: BankId, accountId: AccountId, transactionId: TransactionId) : Boolean = ???
|
||||
}
|
||||
|
||||
private class OBPComment private() extends MongoRecord[OBPComment] with ObjectIdPk[OBPComment] with Comment {
|
||||
def meta = OBPComment
|
||||
|
||||
//These fields are used to link this to its transaction
|
||||
object transactionId extends StringField(this, 255)
|
||||
object accountId extends StringField(this, 255)
|
||||
object bankId extends StringField(this, 255)
|
||||
|
||||
def postedBy = UserX.findByResourceUserId(userId.get)
|
||||
def viewId = ViewId(forView.get)
|
||||
def text = textField.get
|
||||
def datePosted = date.get
|
||||
def id_ = id.get.toString
|
||||
def replyToID = replyTo.get
|
||||
object userId extends LongField(this)
|
||||
|
||||
object forView extends StringField(this, 255)
|
||||
|
||||
object textField extends StringField(this, 255)
|
||||
object date extends DateField(this)
|
||||
object replyTo extends StringField(this,255)
|
||||
}
|
||||
|
||||
private object OBPComment extends OBPComment with MongoMetaRecord[OBPComment] with MdcLoggable {
|
||||
def findAll(bankId : BankId, accountId : AccountId, transactionId : TransactionId, viewId : ViewId) : List[OBPComment] = {
|
||||
val query = QueryBuilder.
|
||||
start("bankId").is(bankId.value).
|
||||
put("accountId").is(accountId.value).
|
||||
put("transactionId").is(transactionId.value).
|
||||
put("forView").is(viewId.value).get
|
||||
findAll(query)
|
||||
}
|
||||
|
||||
def getFindQuery(bankId : BankId, accountId : AccountId, transactionId : TransactionId, commentId : String) : DBObject = {
|
||||
//in theory commentId should be enough as we're just using the mongoId
|
||||
QueryBuilder.start("_id").is(new ObjectId(commentId)).put("transactionId").is(transactionId.value).
|
||||
put("accountId").is(accountId.value).put("bankId").is(bankId.value).get()
|
||||
}
|
||||
}
|
||||
@ -1,182 +0,0 @@
|
||||
package code.metadata.counterparties
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.api.util.CallContext
|
||||
import code.model._
|
||||
import code.util.Helper.MdcLoggable
|
||||
import com.mongodb.QueryBuilder
|
||||
import com.openbankproject.commons.model._
|
||||
import net.liftweb.common.{Box, Empty, Full}
|
||||
import net.liftweb.util.Helpers.tryo
|
||||
import org.bson.types.ObjectId
|
||||
|
||||
object MongoCounterparties extends Counterparties with MdcLoggable {
|
||||
|
||||
|
||||
def getMetadatas(originalPartyBankId: BankId, originalPartyAccountId : AccountId) : List[CounterpartyMetadata] = {
|
||||
val query = QueryBuilder.start("originalPartyBankId").is(originalPartyBankId.value).put("originalPartyAccountId").is(originalPartyAccountId.value).get
|
||||
Metadata.findAll(query)
|
||||
}
|
||||
|
||||
def getMetadata(originalPartyBankId: BankId, originalPartyAccountId : AccountId, counterpartyMetadataId : String) : Box[CounterpartyMetadata] = {
|
||||
/**
|
||||
* This particular implementation requires the metadata id to be the same as the otherParty (OtherBankAccount) id
|
||||
*/
|
||||
for {
|
||||
objId <- tryo { new ObjectId(counterpartyMetadataId) }
|
||||
query = QueryBuilder.start("originalPartyBankId").is(originalPartyBankId.value).put("originalPartyAccountId").is(originalPartyAccountId.value).
|
||||
put("_id").is(objId).get()
|
||||
m <- Metadata.find(query)
|
||||
} yield m
|
||||
}
|
||||
|
||||
def deleteMetadata(originalPartyBankId: BankId, originalPartyAccountId: AccountId, counterpartyMetadataId: String): Box[Boolean] = Empty
|
||||
|
||||
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(bankId, accountId, counterpartyId)
|
||||
|
||||
val metadata = existing match {
|
||||
case Full(m) => m
|
||||
case _ => createMetadata(bankId, accountId, counterpartyName, counterpartyId)
|
||||
}
|
||||
|
||||
Full(metadata)
|
||||
}
|
||||
|
||||
/**
|
||||
* This only exists for OBPEnvelope. Avoid using it for any other reason outside of this class
|
||||
*/
|
||||
def createMetadata(originalPartyBankId: BankId, originalPartyAccountId : AccountId, otherAccountHolder : String, counterpartyId : String) : Metadata = {
|
||||
//create it
|
||||
if(otherAccountHolder.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)
|
||||
.holder("")
|
||||
.save(true)
|
||||
|
||||
} else {
|
||||
Metadata.createRecord.
|
||||
counterpartyId(counterpartyId).
|
||||
originalPartyBankId(originalPartyBankId.value).
|
||||
originalPartyAccountId(originalPartyAccountId.value).
|
||||
holder(otherAccountHolder).
|
||||
// accountNumber(otherAccountNumber).
|
||||
publicAlias(newPublicAliasName(originalPartyBankId, originalPartyAccountId)).save(true)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a new alias name that is guaranteed not to collide with any existing public alias names
|
||||
* for the account in question
|
||||
*/
|
||||
def newPublicAliasName(originalPartyBankId : BankId, originalPartyAccountId : AccountId): String = {
|
||||
import scala.util.Random
|
||||
|
||||
val firstAliasAttempt = "ALIAS_" + Random.nextLong().toString.take(6)
|
||||
|
||||
/**
|
||||
* Returns true if @publicAlias is already the name of a public alias within @account
|
||||
*/
|
||||
def isDuplicate(publicAlias: String) = {
|
||||
val query = QueryBuilder.start("originalPartyBankId").is(originalPartyBankId.value).put("originalPartyAccountId").is(originalPartyAccountId.value).get()
|
||||
Metadata.findAll(query).exists(m => {
|
||||
m.publicAlias.get == publicAlias
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends things to @publicAlias until it a unique public alias name within @account
|
||||
*/
|
||||
def appendUntilUnique(publicAlias: String): String = {
|
||||
val newAlias = publicAlias + Random.nextLong().toString.take(1)
|
||||
if (isDuplicate(newAlias)) appendUntilUnique(newAlias)
|
||||
else newAlias
|
||||
}
|
||||
|
||||
if (isDuplicate(firstAliasAttempt)) appendUntilUnique(firstAliasAttempt)
|
||||
else firstAliasAttempt
|
||||
}
|
||||
|
||||
override def getCounterparty(counterpartyId : String): Box[CounterpartyTrait] = Empty
|
||||
|
||||
override def deleteCounterparty(counterpartyId : String): Box[Boolean] = Empty
|
||||
|
||||
override def getCounterpartyByIban(iban : String): Box[CounterpartyTrait] = Empty
|
||||
|
||||
override def getCounterpartyByIbanAndBankAccountId(iban : String, bankId: BankId, accountId: AccountId): Box[CounterpartyTrait] = Empty
|
||||
|
||||
override def getCounterpartyByRoutings(
|
||||
otherBankRoutingScheme: String,
|
||||
otherBankRoutingAddress: String,
|
||||
otherBranchRoutingScheme: String,
|
||||
otherBranchRoutingAddress: String,
|
||||
otherAccountRoutingScheme: String,
|
||||
otherAccountRoutingAddress: String
|
||||
): Box[CounterpartyTrait] = Empty
|
||||
|
||||
override def getCounterpartyBySecondaryRouting(
|
||||
otherAccountSecondaryRoutingScheme: String,
|
||||
otherAccountSecondaryRoutingAddress: String
|
||||
): Box[CounterpartyTrait] = Empty
|
||||
|
||||
override def createCounterparty(
|
||||
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,
|
||||
currency: String,
|
||||
bespoke: List[CounterpartyBespoke]
|
||||
): Box[CounterpartyTrait] = Empty
|
||||
|
||||
override def checkCounterpartyExists(
|
||||
name: String,
|
||||
thisBankId: String,
|
||||
thisAccountId: String,
|
||||
thisViewId: String
|
||||
): Box[CounterpartyTrait] = Empty
|
||||
|
||||
override def getCounterparties(thisBankId: BankId, thisAccountId: AccountId, viewId: ViewId): Box[List[CounterpartyTrait]] = ???
|
||||
|
||||
override def addPublicAlias(counterpartyId : String, alias: String): Box[Boolean] = ???
|
||||
override def addPrivateAlias(counterpartyId : String, alias: String): Box[Boolean] = ???
|
||||
override def addURL(counterpartyId : String, url: String): Box[Boolean] = ???
|
||||
override def addImageURL(counterpartyId : String, imageUrl: String): Box[Boolean] = ???
|
||||
override def addOpenCorporatesURL(counterpartyId : String, url: String): Box[Boolean] = ???
|
||||
override def addMoreInfo(counterpartyId : String, moreInfo: String): Box[Boolean] = ???
|
||||
override def addPhysicalLocation(counterpartyId : String, userId: UserPrimaryKey, datePosted : Date, longitude : Double, latitude : Double): Box[Boolean] = ???
|
||||
override def addCorporateLocation(counterpartyId : String, userId: UserPrimaryKey, datePosted : Date, longitude : Double, latitude : Double): Box[Boolean] = ???
|
||||
override def deletePhysicalLocation(counterpartyId : String): Box[Boolean] = ???
|
||||
override def deleteCorporateLocation(counterpartyId : String): Box[Boolean] = ???
|
||||
override def getCorporateLocation(counterpartyId : String): Box[GeoTag] = ???
|
||||
override def getPhysicalLocation(counterpartyId : String): Box[GeoTag] = ???
|
||||
override def getOpenCorporatesURL(counterpartyId : String): Box[String] = ???
|
||||
override def getImageURL(counterpartyId : String): Box[String] = ???
|
||||
override def getUrl(counterpartyId : String): Box[String] = ???
|
||||
override def getMoreInfo(counterpartyId : String): Box[String] = ???
|
||||
override def getPublicAlias(counterpartyId : String): Box[String] = ???
|
||||
override def getPrivateAlias(counterpartyId : String): Box[String] = ???
|
||||
override def bulkDeleteAllCounterparties(): Box[Boolean] = ???
|
||||
}
|
||||
@ -1,156 +0,0 @@
|
||||
package code.metadata.counterparties
|
||||
|
||||
|
||||
import code.model.UserX
|
||||
import net.liftweb.mongodb.record.{BsonMetaRecord, BsonRecord, MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.mongodb.record.field.ObjectIdPk
|
||||
import net.liftweb.record.field.StringField
|
||||
import com.openbankproject.commons.model.{CounterpartyMetadata, GeoTag, UserPrimaryKey}
|
||||
//TODO: this should be private
|
||||
class Metadata private() extends CounterpartyMetadata with MongoRecord[Metadata] with ObjectIdPk[Metadata] {
|
||||
import net.liftweb.mongodb.record.field.BsonRecordField
|
||||
import java.util.Date
|
||||
|
||||
def meta = Metadata
|
||||
|
||||
//originalPartyBankId and originalPartyAccountId are used to identify the account
|
||||
//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 publicAlias extends StringField(this, 100)
|
||||
object privateAlias extends StringField(this, 100)
|
||||
object moreInfo extends StringField(this, 100)
|
||||
object url extends StringField(this, 100)
|
||||
object imageUrl extends StringField(this, 100)
|
||||
object openCorporatesUrl extends StringField(this, 100) {
|
||||
override def optional_? = true
|
||||
}
|
||||
object corporateLocation extends BsonRecordField(this, OBPGeoTag)
|
||||
object physicalLocation extends BsonRecordField(this, OBPGeoTag)
|
||||
|
||||
def addCorporateLocationFn(userId: UserPrimaryKey, datePosted : Date, longitude : Double, latitude : Double) : Boolean = {
|
||||
val newTag = OBPGeoTag.createRecord.
|
||||
userId(userId.value).
|
||||
date(datePosted).
|
||||
geoLongitude(longitude).
|
||||
geoLatitude(latitude)
|
||||
corporateLocation(newTag).saveTheRecord()
|
||||
true
|
||||
}
|
||||
|
||||
def deleteCorporateLocationFn : Boolean = {
|
||||
corporateLocation.clear
|
||||
this.saveTheRecord()
|
||||
true
|
||||
}
|
||||
|
||||
def addPhysicalLocationFn(userId: UserPrimaryKey, datePosted : Date, longitude : Double, latitude : Double) : Boolean = {
|
||||
val newTag = OBPGeoTag.createRecord.
|
||||
userId(userId.value).
|
||||
date(datePosted).
|
||||
geoLongitude(longitude).
|
||||
geoLatitude(latitude)
|
||||
physicalLocation(newTag).saveTheRecord()
|
||||
true
|
||||
}
|
||||
|
||||
def deletePhysicalLocationFn : Boolean = {
|
||||
physicalLocation.clear
|
||||
this.saveTheRecord()
|
||||
true
|
||||
}
|
||||
|
||||
private def locationTag(loc: OBPGeoTag): Option[GeoTag]={
|
||||
if(loc.longitude==0 && loc.latitude==0)
|
||||
None
|
||||
else
|
||||
Some(loc)
|
||||
}
|
||||
|
||||
override def getCounterpartyId = counterpartyId.get
|
||||
override def getCounterpartyName = holder.get
|
||||
// override def getAccountNumber = accountNumber.get
|
||||
override def getUrl = url.get
|
||||
override def getCorporateLocation = locationTag(corporateLocation.get)
|
||||
override def getPhysicalLocation = locationTag(physicalLocation.get)
|
||||
override val deleteCorporateLocation = deleteCorporateLocationFn _
|
||||
override val deletePhysicalLocation = deletePhysicalLocationFn _
|
||||
override def getPrivateAlias = privateAlias.get
|
||||
override def getPublicAlias = publicAlias.get
|
||||
override def getMoreInfo = moreInfo.get
|
||||
override def getImageURL: String = imageUrl.get
|
||||
override val addPrivateAlias: (String) => Boolean = (alias => {
|
||||
privateAlias(alias).saveTheRecord()
|
||||
//the save method does not return a Boolean to inform about the saving state,
|
||||
//so we a true
|
||||
true
|
||||
})
|
||||
override val addURL: (String) => Boolean = (text => {
|
||||
url(text).saveTheRecord()
|
||||
//the save method does not return a Boolean to inform about the saving state,
|
||||
//so we a true
|
||||
true
|
||||
})
|
||||
override val addPhysicalLocation: (UserPrimaryKey, Date, Double, Double) => Boolean = addPhysicalLocationFn _
|
||||
override val addCorporateLocation: (UserPrimaryKey, Date, Double, Double) => Boolean = addCorporateLocationFn _
|
||||
override val addMoreInfo: (String) => Boolean = (text => {
|
||||
moreInfo(text).saveTheRecord()
|
||||
//the save method does not return a Boolean to inform about the saving state,
|
||||
//so we a true
|
||||
true
|
||||
})
|
||||
override def getOpenCorporatesURL: String = openCorporatesUrl.get
|
||||
override val addPublicAlias: (String) => Boolean = (alias => {
|
||||
publicAlias(alias).saveTheRecord()
|
||||
//the save method does not return a Boolean to inform about the saving state,
|
||||
//so we a true
|
||||
true
|
||||
})
|
||||
override val addOpenCorporatesURL: (String) => Boolean = (text => {
|
||||
openCorporatesUrl(text).saveTheRecord()
|
||||
//the save method does not return a Boolean to inform about the saving state,
|
||||
//so we a true
|
||||
true
|
||||
})
|
||||
override val addImageURL: (String) => Boolean = (text => {
|
||||
imageUrl(text).saveTheRecord()
|
||||
//the save method does not return a Boolean to inform about the saving state,
|
||||
//so we a true
|
||||
true
|
||||
})
|
||||
}
|
||||
|
||||
//TODO: this should be private
|
||||
object Metadata extends Metadata with MongoMetaRecord[Metadata]
|
||||
|
||||
class OBPGeoTag private() extends BsonRecord[OBPGeoTag] with GeoTag {
|
||||
import com.openbankproject.commons.model.User
|
||||
import net.liftweb.record.field.{DoubleField, LongField}
|
||||
import net.liftweb.mongodb.record.field.DateField
|
||||
|
||||
def meta = OBPGeoTag
|
||||
|
||||
//These fields are used to link this to its transaction
|
||||
object transactionId extends StringField(this, 255)
|
||||
object accountId extends StringField(this, 255)
|
||||
object bankId extends StringField(this, 255)
|
||||
|
||||
object userId extends LongField(this)
|
||||
|
||||
object date extends DateField(this)
|
||||
|
||||
object geoLongitude extends DoubleField(this,0)
|
||||
object geoLatitude extends DoubleField(this,0)
|
||||
|
||||
override def datePosted = date.get
|
||||
override def postedBy = UserX.findByResourceUserId(userId.get)
|
||||
override def longitude = geoLongitude.get
|
||||
override def latitude = geoLatitude.get
|
||||
|
||||
}
|
||||
//TODO: this should be private
|
||||
object OBPGeoTag extends OBPGeoTag with BsonMetaRecord[OBPGeoTag]
|
||||
@ -1,78 +0,0 @@
|
||||
package code.metadata.narrative
|
||||
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
import net.liftweb.mongodb.record.{MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.mongodb.record.field.ObjectIdPk
|
||||
import net.liftweb.record.field.StringField
|
||||
import com.mongodb.{DBObject, QueryBuilder}
|
||||
import com.openbankproject.commons.model.{AccountId, BankId, TransactionId}
|
||||
|
||||
private object MongoTransactionNarrative extends Narrative {
|
||||
|
||||
def getNarrative(bankId: BankId, accountId: AccountId, transactionId: TransactionId)() : String = {
|
||||
OBPNarrative.find(OBPNarrative.getFindQuery(bankId, accountId, transactionId)) match {
|
||||
case Full(n) => n.narrative.get
|
||||
case _ => ""
|
||||
}
|
||||
}
|
||||
|
||||
def setNarrative(bankId: BankId, accountId: AccountId, transactionId: TransactionId)(narrative: String) : Boolean = {
|
||||
|
||||
val findQuery = OBPNarrative.getFindQuery(bankId, accountId, transactionId)
|
||||
|
||||
if(narrative.isEmpty) {
|
||||
//if we're setting the value of the narrative to "" then we can just delete it
|
||||
|
||||
//use delete with find query to avoid concurrency issues
|
||||
OBPNarrative.delete(findQuery)
|
||||
} else {
|
||||
|
||||
//avoiding upsert for now as it seemed to behave a little strangely
|
||||
val found = OBPNarrative.find(findQuery)
|
||||
found match {
|
||||
case Full(f) => f.narrative(narrative).save(true)
|
||||
case _ => {
|
||||
OBPNarrative.createRecord
|
||||
.transactionId(transactionId.value)
|
||||
.accountId(accountId.value)
|
||||
.bankId(bankId.value)
|
||||
.narrative(narrative).save(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//we don't have any useful information here so just assume it worked
|
||||
true
|
||||
}
|
||||
|
||||
override def bulkDeleteNarrativeOnTransaction(bankId: BankId, accountId: AccountId, transactionId: TransactionId): Boolean = ???
|
||||
|
||||
override def bulkDeleteNarratives(bankId: BankId, accountId: AccountId): Boolean = ???
|
||||
|
||||
}
|
||||
|
||||
private class OBPNarrative private() extends MongoRecord[OBPNarrative] with ObjectIdPk[OBPNarrative] {
|
||||
|
||||
def meta = OBPNarrative
|
||||
|
||||
//These fields are used to link this to its transaction
|
||||
object transactionId extends StringField(this, 255)
|
||||
object accountId extends StringField(this, 255)
|
||||
object bankId extends StringField(this, 255)
|
||||
|
||||
object narrative extends StringField(this, 255)
|
||||
}
|
||||
|
||||
private object OBPNarrative extends OBPNarrative with MongoMetaRecord[OBPNarrative] {
|
||||
|
||||
def init = createIndex((transactionId.name -> 1) ~ (accountId.name -> 1) ~ (bankId.name -> 1), true)
|
||||
|
||||
def getFindQuery(bankId : BankId, accountId : AccountId, transactionId : TransactionId) : DBObject = {
|
||||
QueryBuilder.start("bankId").is(bankId.value).put("accountId").is(accountId.value).put("transactionId").is(transactionId.value).get
|
||||
}
|
||||
}
|
||||
|
||||
object OBPNarrativeInit {
|
||||
def init = OBPNarrative.init
|
||||
}
|
||||
@ -1,96 +0,0 @@
|
||||
package code.metadata.tags
|
||||
|
||||
import code.model._
|
||||
import java.util.Date
|
||||
|
||||
import code.util.Helper
|
||||
import net.liftweb.common.{Box, Full}
|
||||
import org.bson.types.ObjectId
|
||||
import net.liftweb.mongodb.record.{MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.mongodb.record.field.{DateField, ObjectIdPk}
|
||||
import net.liftweb.record.field.{LongField, StringField}
|
||||
import com.mongodb.{DBObject, QueryBuilder}
|
||||
import com.openbankproject.commons.model._
|
||||
|
||||
private object MongoTransactionTags extends Tags {
|
||||
|
||||
def getTags(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(viewId : ViewId) : List[TransactionTag] = {
|
||||
OBPTag.findAll(bankId, accountId, transactionId, viewId)
|
||||
}
|
||||
def getTagsOnAccount(bankId : BankId, accountId : AccountId)(viewId : ViewId) : List[TransactionTag] = {
|
||||
OBPTag.findAll(bankId, accountId, TransactionId(""), viewId)
|
||||
}
|
||||
def addTag(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(userId: UserPrimaryKey, viewId : ViewId, tagText : String, datePosted : Date) : Box[TransactionTag] = {
|
||||
OBPTag.createRecord.
|
||||
bankId(bankId.value).
|
||||
accountId(accountId.value).
|
||||
transactionId(transactionId.value).
|
||||
userId(userId.value).
|
||||
forView(viewId.value).
|
||||
tag(tagText).
|
||||
date(datePosted).saveTheRecord()
|
||||
}
|
||||
def addTagOnAccount(bankId : BankId, accountId : AccountId)(userId: UserPrimaryKey, viewId : ViewId, tagText : String, datePosted : Date) : Box[TransactionTag] = {
|
||||
OBPTag.createRecord.
|
||||
bankId(bankId.value).
|
||||
accountId(accountId.value).
|
||||
userId(userId.value).
|
||||
forView(viewId.value).
|
||||
tag(tagText).
|
||||
date(datePosted).saveTheRecord()
|
||||
}
|
||||
def deleteTag(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(tagId : String) : Box[Boolean] = {
|
||||
//use delete with find query to avoid concurrency issues
|
||||
OBPTag.delete(OBPTag.getFindQuery(bankId, accountId, transactionId, tagId))
|
||||
|
||||
//we don't have any useful information here so just assume it worked
|
||||
Full(true)
|
||||
}
|
||||
def deleteTagOnAccount(bankId : BankId, accountId : AccountId)(tagId : String) : Box[Boolean] = {
|
||||
deleteTag(bankId, accountId, TransactionId(""))(tagId)
|
||||
}
|
||||
|
||||
def bulkDeleteTags(bankId: BankId, accountId: AccountId): Boolean = ???
|
||||
def bulkDeleteTagsOnTransaction(bankId: BankId, accountId: AccountId, transactionId: TransactionId) : Boolean = ???
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class OBPTag private() extends MongoRecord[OBPTag] with ObjectIdPk[OBPTag] with TransactionTag {
|
||||
def meta = OBPTag
|
||||
|
||||
//These fields are used to link this to its transaction
|
||||
object transactionId extends StringField(this, 255)
|
||||
object accountId extends StringField(this, 255)
|
||||
object bankId extends StringField(this, 255)
|
||||
|
||||
object userId extends LongField(this)
|
||||
|
||||
object forView extends StringField(this, 255)
|
||||
|
||||
object tag extends StringField(this, 255)
|
||||
object date extends DateField(this)
|
||||
|
||||
def id_ = id.get.toString
|
||||
def datePosted = date.get
|
||||
def postedBy = UserX.findByResourceUserId(userId.get)
|
||||
def viewId = ViewId(forView.get)
|
||||
def value = tag.get
|
||||
}
|
||||
|
||||
private object OBPTag extends OBPTag with MongoMetaRecord[OBPTag] {
|
||||
def findAll(bankId : BankId, accountId : AccountId, transactionId : TransactionId, viewId : ViewId) : List[OBPTag] = {
|
||||
val query = QueryBuilder.
|
||||
start("bankId").is(bankId.value).
|
||||
put("accountId").is(accountId.value).
|
||||
put("transactionId").is(transactionId.value).
|
||||
put("forView").is(viewId.value).get
|
||||
findAll(query)
|
||||
}
|
||||
|
||||
//in theory commentId should be enough as we're just using the mongoId
|
||||
def getFindQuery(bankId : BankId, accountId : AccountId, transactionId : TransactionId, tagId : String) : DBObject = {
|
||||
QueryBuilder.start("_id").is(new ObjectId(tagId)).put("transactionId").is(transactionId.value).
|
||||
put("accountId").is(accountId.value).put("bankId").is(bankId.value).get()
|
||||
}
|
||||
}
|
||||
@ -1,95 +0,0 @@
|
||||
package code.metadata.transactionimages
|
||||
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import net.liftweb.common.Box
|
||||
import code.util.Helper.MdcLoggable
|
||||
import java.net.URL
|
||||
import java.util.Date
|
||||
|
||||
import org.bson.types.ObjectId
|
||||
import net.liftweb.mongodb.record.{MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.mongodb.record.field.{DateField, ObjectIdPk}
|
||||
import net.liftweb.record.field.{LongField, StringField}
|
||||
import net.liftweb.util.Helpers._
|
||||
import net.liftweb.common.Full
|
||||
import com.mongodb.{DBObject, QueryBuilder}
|
||||
import com.openbankproject.commons.model._
|
||||
|
||||
private object MongoTransactionImages extends TransactionImages with MdcLoggable {
|
||||
|
||||
def getImagesForTransaction(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(viewId : ViewId) : List[TransactionImage] = {
|
||||
OBPTransactionImage.findAll(bankId, accountId, transactionId, viewId)
|
||||
}
|
||||
|
||||
def addTransactionImage(bankId : BankId, accountId : AccountId, transactionId: TransactionId)
|
||||
(userId: UserPrimaryKey, viewId : ViewId, description : String, datePosted : Date, imageURL: String) : Box[TransactionImage] = {
|
||||
OBPTransactionImage.createRecord.
|
||||
bankId(bankId.value).
|
||||
accountId(accountId.value).
|
||||
transactionId(transactionId.value).
|
||||
userId(userId.value).
|
||||
forView(viewId.value).
|
||||
imageComment(description).
|
||||
date(datePosted).
|
||||
url(imageURL.toString).saveTheRecord()
|
||||
}
|
||||
|
||||
def deleteTransactionImage(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(imageId : String) : Box[Boolean] = {
|
||||
//use delete with find query to avoid concurrency issues
|
||||
OBPTransactionImage.delete(OBPTransactionImage.getFindQuery(bankId, accountId, transactionId, imageId))
|
||||
|
||||
//we don't have any useful information here so just assume it worked
|
||||
Full(true)
|
||||
}
|
||||
|
||||
def bulkDeleteImagesOnTransaction(bankId : BankId, accountId : AccountId, transactionId: TransactionId) : Boolean = ???
|
||||
def bulkDeleteTransactionImage(bankId: BankId, accountId: AccountId): Boolean = ???
|
||||
|
||||
}
|
||||
|
||||
private class OBPTransactionImage private() extends MongoRecord[OBPTransactionImage]
|
||||
with ObjectIdPk[OBPTransactionImage] with TransactionImage {
|
||||
def meta = OBPTransactionImage
|
||||
|
||||
//These fields are used to link this to its transaction
|
||||
object transactionId extends StringField(this, 255)
|
||||
object accountId extends StringField(this, 255)
|
||||
object bankId extends StringField(this, 255)
|
||||
|
||||
object userId extends LongField(this)
|
||||
|
||||
object forView extends StringField(this, 255)
|
||||
|
||||
object imageComment extends StringField(this, 1000)
|
||||
object date extends DateField(this)
|
||||
object url extends StringField(this, 500)
|
||||
|
||||
def id_ = id.get.toString
|
||||
def datePosted = date.get
|
||||
def postedBy = UserX.findByResourceUserId(userId.get)
|
||||
def viewId = ViewId(forView.get)
|
||||
def description = imageComment.get
|
||||
def imageUrl = {
|
||||
tryo {new URL(url.get)} getOrElse OBPTransactionImage.notFoundUrl
|
||||
}
|
||||
}
|
||||
|
||||
private object OBPTransactionImage extends OBPTransactionImage with MongoMetaRecord[OBPTransactionImage] {
|
||||
val notFoundUrl = new URL("http://example.com/notfound.png") //TODO: Make this image exist?
|
||||
|
||||
def findAll(bankId : BankId, accountId : AccountId, transactionId : TransactionId, viewId : ViewId) : List[OBPTransactionImage] = {
|
||||
val query = QueryBuilder.
|
||||
start("bankId").is(bankId.value).
|
||||
put("accountId").is(accountId.value).
|
||||
put("transactionId").is(transactionId.value).
|
||||
put("forView").is(viewId.value).get
|
||||
findAll(query)
|
||||
}
|
||||
|
||||
//in theory commentId should be enough as we're just using the mongoId
|
||||
def getFindQuery(bankId : BankId, accountId : AccountId, transactionId : TransactionId, imageId : String) : DBObject = {
|
||||
QueryBuilder.start("_id").is(new ObjectId(imageId)).put("transactionId").is(transactionId.value).
|
||||
put("accountId").is(accountId.value).put("bankId").is(bankId.value).get()
|
||||
}
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
package code.metadata.wheretags
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.model._
|
||||
import net.liftweb.common.{Box, Full}
|
||||
import code.util.Helper.MdcLoggable
|
||||
import com.openbankproject.commons.model._
|
||||
|
||||
|
||||
private object MongoTransactionWhereTags extends WhereTags with MdcLoggable {
|
||||
|
||||
def addWhereTag(bankId : BankId, accountId : AccountId, transactionId: TransactionId)
|
||||
(userId: UserPrimaryKey, viewId : ViewId, datePosted : Date, longitude : Double, latitude : Double) : Boolean = {
|
||||
|
||||
//avoiding upsert for now as it seemed to behave a little strangely
|
||||
val findQuery = OBPWhereTag.getFindQuery(bankId, accountId, transactionId, viewId)
|
||||
val found = OBPWhereTag.find(findQuery)
|
||||
found match {
|
||||
case Full(f) => {
|
||||
f.date(datePosted).
|
||||
geoLongitude(longitude).
|
||||
geoLatitude(latitude).save(true)
|
||||
}
|
||||
case _ => {
|
||||
OBPWhereTag.createRecord.
|
||||
bankId(bankId.value).
|
||||
accountId(accountId.value).
|
||||
transactionId(transactionId.value).
|
||||
userId(userId.value).
|
||||
forView(viewId.value).
|
||||
date(datePosted).
|
||||
geoLongitude(longitude).
|
||||
geoLatitude(latitude).save(true)
|
||||
}
|
||||
}
|
||||
//we don't have any useful information here so just return true
|
||||
true
|
||||
}
|
||||
|
||||
def deleteWhereTag(bankId: BankId, accountId: AccountId, transactionId: TransactionId)(viewId: ViewId): Boolean = {
|
||||
//use delete with find query to avoid concurrency issues
|
||||
OBPWhereTag.delete(OBPWhereTag.getFindQuery(bankId, accountId, transactionId, viewId))
|
||||
|
||||
//we don't have any useful information here so just return true
|
||||
true
|
||||
}
|
||||
|
||||
def getWhereTagForTransaction(bankId : BankId, accountId : AccountId, transactionId: TransactionId)(viewId : ViewId) : Box[GeoTag] = {
|
||||
OBPWhereTag.find(bankId, accountId, transactionId, viewId)
|
||||
}
|
||||
|
||||
def bulkDeleteWhereTagsOnTransaction(bankId: BankId, accountId: AccountId, transactionId: TransactionId) : Boolean = ???
|
||||
|
||||
def bulkDeleteWhereTags(bankId: BankId, accountId: AccountId) : Boolean = ???
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
package code.metadata.wheretags
|
||||
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
import net.liftweb.mongodb.record.{MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.mongodb.record.field.{DateField, ObjectIdPk}
|
||||
import net.liftweb.record.field.{DoubleField, LongField, StringField}
|
||||
import code.model._
|
||||
import com.mongodb.{DBObject, QueryBuilder}
|
||||
import com.openbankproject.commons.model._
|
||||
|
||||
private class OBPWhereTag private() extends MongoRecord[OBPWhereTag] with ObjectIdPk[OBPWhereTag] with GeoTag {
|
||||
def meta = OBPWhereTag
|
||||
|
||||
//These fields are used to link this to its transaction
|
||||
object transactionId extends StringField(this, 255)
|
||||
object accountId extends StringField(this, 255)
|
||||
object bankId extends StringField(this, 255)
|
||||
|
||||
object userId extends LongField(this)
|
||||
|
||||
object forView extends StringField(this, 255)
|
||||
|
||||
object date extends DateField(this)
|
||||
|
||||
object geoLongitude extends DoubleField(this,0)
|
||||
object geoLatitude extends DoubleField(this,0)
|
||||
|
||||
override def datePosted = date.get
|
||||
override def postedBy = UserX.findByResourceUserId(userId.get)
|
||||
override def longitude = geoLongitude.get
|
||||
override def latitude = geoLatitude.get
|
||||
}
|
||||
|
||||
private object OBPWhereTag extends OBPWhereTag with MongoMetaRecord[OBPWhereTag] {
|
||||
|
||||
def init = createIndex((transactionId.name -> 1) ~ (accountId.name -> 1) ~ (bankId.name -> 1) ~ (forView.name -> 1), true)
|
||||
|
||||
def find(bankId : BankId, accountId : AccountId, transactionId : TransactionId, viewId : ViewId) : Option[OBPWhereTag] = {
|
||||
val query = getFindQuery(bankId, accountId, transactionId, viewId)
|
||||
find(query)
|
||||
}
|
||||
|
||||
//in theory commentId should be enough as we're just using the mongoId
|
||||
def getFindQuery(bankId : BankId, accountId : AccountId, transactionId : TransactionId, viewId : ViewId) : DBObject = {
|
||||
QueryBuilder.start("forView").is(viewId.value).put("transactionId").is(transactionId.value).
|
||||
put("accountId").is(accountId.value).put("bankId").is(bankId.value).get()
|
||||
}
|
||||
}
|
||||
|
||||
object OBPWhereTagInit {
|
||||
def init = OBPWhereTag.init
|
||||
}
|
||||
@ -1,122 +0,0 @@
|
||||
/**
|
||||
Open Bank Project - API
|
||||
Copyright (C) 2011-2019, TESOBE GmbH.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Email: contact@tesobe.com
|
||||
TESOBE GmbH.
|
||||
Osloer Strasse 16/17
|
||||
Berlin 13359, Germany
|
||||
|
||||
This product includes software developed at
|
||||
TESOBE (http://www.tesobe.com/)
|
||||
|
||||
*/
|
||||
|
||||
package code.metrics
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.api.util.OBPQueryParam
|
||||
import net.liftweb.common.Box
|
||||
import net.liftweb.mongodb.record.field.{DateField, LongPk}
|
||||
import net.liftweb.mongodb.record.{MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.record.field.{IntField, LongField, StringField}
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
private class MongoAPIMetric extends MongoRecord[MongoAPIMetric] with LongPk[MongoAPIMetric] with APIMetric {
|
||||
def meta = MongoAPIMetric
|
||||
object userId extends StringField(this,255)
|
||||
object url extends StringField(this,255)
|
||||
object date extends DateField(this)
|
||||
object duration extends LongField(this)
|
||||
object userName extends StringField(this,255)
|
||||
object appName extends StringField(this,255)
|
||||
object developerEmail extends StringField(this,255)
|
||||
//The consumerId, Foreign key to Consumer not key
|
||||
object consumerId extends StringField(this,255)
|
||||
//name of the Scala Partial Function being used for the endpoint
|
||||
object implementedByPartialFunction extends StringField(this,255)
|
||||
//name of version where the call is implemented) -- S.request.get.view
|
||||
object implementedInVersion extends StringField(this,255)
|
||||
//(GET, POST etc.) --S.request.get.requestType
|
||||
object verb extends StringField(this,255)
|
||||
object httpCode extends IntField(this)
|
||||
object correlationId extends StringField(this,255)
|
||||
|
||||
|
||||
def getMetricId(): Long = id.get
|
||||
def getUrl() = url.get
|
||||
def getDate() = date.get
|
||||
def getDuration(): Long = duration.get
|
||||
def getUserId() = userId.get
|
||||
def getUserName(): String = userName.get
|
||||
def getAppName(): String = appName.get
|
||||
def getDeveloperEmail(): String = developerEmail.get
|
||||
override def getConsumerId(): String = consumerId.get
|
||||
override def getImplementedByPartialFunction(): String = implementedByPartialFunction.get
|
||||
override def getImplementedInVersion(): String = implementedInVersion.get
|
||||
override def getVerb(): String = verb.get
|
||||
override def getHttpCode(): Int = httpCode.get
|
||||
override def getCorrelationId(): String = correlationId.get
|
||||
}
|
||||
|
||||
private object MongoAPIMetric extends MongoAPIMetric with MongoMetaRecord[MongoAPIMetric] with APIMetrics {
|
||||
|
||||
def saveMetric(userId: String, url: String, date: Date, duration: Long, userName: String, appName: String, developerEmail: String, consumerId: String, implementedByPartialFunction: String, implementedInVersion: String, verb: String, httpCode: Option[Int], correlationId: String): Unit = {
|
||||
MongoAPIMetric.createRecord.
|
||||
userId(userId).
|
||||
url(url).
|
||||
date(date).
|
||||
duration(duration).
|
||||
userName(userName).
|
||||
appName(appName).
|
||||
developerEmail(developerEmail).
|
||||
consumerId(consumerId).
|
||||
implementedByPartialFunction(implementedByPartialFunction).
|
||||
implementedInVersion(implementedInVersion).
|
||||
verb(verb).
|
||||
correlationId(correlationId)
|
||||
saveTheRecord()
|
||||
}
|
||||
override def saveMetricsArchive(primaryKey: Long, userId: String, url: String, date: Date, duration: Long, userName: String, appName: String, developerEmail: String, consumerId: String, implementedByPartialFunction: String, implementedInVersion: String, verb: String, httpCode: Option[Int], correlationId: String): Unit = ???
|
||||
|
||||
|
||||
// def getAllGroupedByUrl() : Map[String, List[APIMetric]] = {
|
||||
// MongoAPIMetric.findAll.groupBy[String](_.url.get)
|
||||
// }
|
||||
//
|
||||
// def getAllGroupedByDay() : Map[Date, List[APIMetric]] = {
|
||||
// MongoAPIMetric.findAll.groupBy[Date](APIMetrics.getMetricDay)
|
||||
// }
|
||||
//
|
||||
// def getAllGroupedByUserId() : Map[String, List[APIMetric]] = {
|
||||
// MongoAPIMetric.findAll.groupBy[String](_.getUserId)
|
||||
// }
|
||||
|
||||
override def getAllMetrics(queryParams: List[OBPQueryParam]): List[APIMetric] = {
|
||||
MongoAPIMetric.findAll
|
||||
}
|
||||
|
||||
override def bulkDeleteMetrics(): Boolean = ???
|
||||
|
||||
override def getAllAggregateMetricsFuture(queryParams: List[OBPQueryParam]): Future[Box[List[AggregateMetrics]]] = ???
|
||||
|
||||
override def getTopApisFuture(queryParams: List[OBPQueryParam]): Future[Box[List[TopApi]]] = ???
|
||||
|
||||
override def getTopConsumersFuture(queryParams: List[OBPQueryParam]): Future[Box[List[TopConsumer]]] = ???
|
||||
|
||||
}
|
||||
@ -1,249 +0,0 @@
|
||||
/**
|
||||
Open Bank Project - API
|
||||
Copyright (C) 2011-2019, TESOBE GmbH.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Email: contact@tesobe.com
|
||||
TESOBE GmbH.
|
||||
Osloer Strasse 16/17
|
||||
Berlin 13359, Germany
|
||||
|
||||
This product includes software developed at
|
||||
TESOBE (http://www.tesobe.com/)
|
||||
|
||||
*/
|
||||
|
||||
package code.model.dataAccess
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.api.util._
|
||||
import code.model._
|
||||
import code.util.Helper
|
||||
import code.util.Helper.MdcLoggable
|
||||
import com.mongodb.QueryBuilder
|
||||
import com.openbankproject.commons.model._
|
||||
import net.liftweb.common._
|
||||
import net.liftweb.mapper.By
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
import net.liftweb.mongodb.record.field.{DateField, ObjectIdPk, ObjectIdRefField}
|
||||
import net.liftweb.mongodb.record.{MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.mongodb.{Limit, Skip}
|
||||
import net.liftweb.record.field.{DecimalField, StringField}
|
||||
|
||||
import scala.collection.immutable.List
|
||||
|
||||
class Account extends BankAccount with MongoRecord[Account] with ObjectIdPk[Account] with MdcLoggable{
|
||||
def meta = Account
|
||||
|
||||
object accountBalance extends DecimalField(this, 0) {
|
||||
//this is the legacy db field name
|
||||
override def name = "balance"
|
||||
}
|
||||
object holder extends StringField(this, 255)
|
||||
object accountNumber extends StringField(this, 255){
|
||||
//this is the legacy db field name
|
||||
override def name = "number"
|
||||
}
|
||||
object kind extends StringField(this, 255)
|
||||
|
||||
// object productCode extends StringField(this, 255)
|
||||
|
||||
object accountName extends StringField(this, 255){
|
||||
//this is the legacy db field name
|
||||
override def name = "name"
|
||||
}
|
||||
object permalink extends StringField(this, 255)
|
||||
object bankID extends ObjectIdRefField(this, HostedBank)
|
||||
object accountLabel extends StringField(this, 255){
|
||||
//this is the legacy db field name
|
||||
override def name = "label"
|
||||
}
|
||||
object accountCurrency extends StringField(this, 255){
|
||||
//this is the legacy db field name
|
||||
override def name = "currency"
|
||||
}
|
||||
object accountIban extends StringField(this, 255){
|
||||
//this is the legacy db field name
|
||||
override def name = "iban"
|
||||
}
|
||||
object accountLastUpdate extends DateField(this)
|
||||
object mAccountRoutingScheme extends StringField(this, 255)
|
||||
object mAccountRoutingAddress extends StringField(this, 255)
|
||||
object mBranchId extends StringField(this, 255)
|
||||
|
||||
object mAccountRuleScheme1 extends StringField(this, 10)
|
||||
object mAccountRuleValue1 extends DecimalField(this, 0)
|
||||
object mAccountRuleScheme2 extends StringField(this, 10)
|
||||
object mAccountRuleValue2 extends DecimalField(this, 0)
|
||||
|
||||
|
||||
def transactionsForAccount: QueryBuilder = {
|
||||
QueryBuilder
|
||||
.start("obp_transaction.this_account.number")
|
||||
.is(accountNumber.get)
|
||||
//FIX: change that to use the bank identifier
|
||||
.put("obp_transaction.this_account.bank.national_identifier")
|
||||
.is(this.nationalIdentifier)
|
||||
}
|
||||
|
||||
//find all the envelopes related to this account
|
||||
def allEnvelopes: List[OBPEnvelope] = OBPEnvelope.findAll(transactionsForAccount.get)
|
||||
|
||||
def envelopes(queryParams: List[OBPQueryParam]): List[OBPEnvelope] = {
|
||||
import com.mongodb.DBObject
|
||||
import net.liftweb.mongodb.FindOption
|
||||
|
||||
val limit: Seq[Limit] = queryParams.collect { case OBPLimit(value) => Limit(value) }
|
||||
val offset: Seq[Skip] = queryParams.collect { case OBPOffset(value) => Skip(value) }
|
||||
val limitAndOffset: Seq[FindOption] = limit ++ offset
|
||||
|
||||
val fromDate: Option[OBPFromDate] = queryParams.collect { case param: OBPFromDate => param }.headOption
|
||||
val toDate: Option[OBPToDate] = queryParams.collect { case param: OBPToDate => param }.headOption
|
||||
|
||||
val query: DBObject = {
|
||||
val queryWithOptionalFromDate = fromDate.map{
|
||||
date => {
|
||||
transactionsForAccount
|
||||
.put("obp_transaction.details.completed")
|
||||
.greaterThanEquals(date.value)
|
||||
}
|
||||
}.getOrElse(transactionsForAccount)
|
||||
|
||||
val queryWithOptionalFromDateAndToDate = toDate.map{
|
||||
date => {
|
||||
queryWithOptionalFromDate
|
||||
.put("obp_transaction.details.completed")
|
||||
.lessThanEquals(date.value)
|
||||
}
|
||||
}.getOrElse(queryWithOptionalFromDate)
|
||||
|
||||
queryWithOptionalFromDateAndToDate.get
|
||||
}
|
||||
|
||||
val defaultSortField = "obp_transaction.details.completed"
|
||||
val orderingParams = queryParams
|
||||
.collect { case param: OBPOrdering => param}
|
||||
.headOption
|
||||
|
||||
val ordering: Option[DBObject] =
|
||||
orderingParams.map{
|
||||
o => {
|
||||
QueryBuilder
|
||||
.start(defaultSortField)
|
||||
.is(o.order.orderValue)
|
||||
.get
|
||||
}
|
||||
}
|
||||
|
||||
ordering match {
|
||||
case Some(o) =>{
|
||||
OBPEnvelope.findAll(query, o, limitAndOffset: _*)
|
||||
}
|
||||
case _ =>{
|
||||
OBPEnvelope.findAll(query, limitAndOffset: _*)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override def bankId: BankId = {
|
||||
bankID.obj match {
|
||||
case Full(bank) => BankId(bank.permalink.get)
|
||||
case _ => BankId("")
|
||||
}
|
||||
}
|
||||
override def accountId : AccountId = AccountId(permalink.get)
|
||||
def iban: Option[String] = {
|
||||
val i = accountIban.get
|
||||
if (i.isEmpty) None else Some(i)
|
||||
}
|
||||
override def currency: String = accountCurrency.get
|
||||
override def number: String = accountNumber.get
|
||||
override def balance: BigDecimal = accountBalance.get
|
||||
override def name: String = accountName.get
|
||||
override def accountType: String = kind.get
|
||||
override def label: String = accountLabel.get
|
||||
override def accountHolder: String = holder.get
|
||||
override def lastUpdate: Date = accountLastUpdate.get
|
||||
def accountRoutingScheme: String = mAccountRoutingScheme.get
|
||||
def accountRoutingAddress: String = mAccountRoutingAddress.get
|
||||
override def branchId: String = mBranchId.get
|
||||
def createAccountRule(scheme: String, value: Long) = {
|
||||
scheme match {
|
||||
case s: String if s.equalsIgnoreCase("") == false =>
|
||||
val v = Helper.smallestCurrencyUnitToBigDecimal(value, accountCurrency.get)
|
||||
List(AccountRule(scheme, v.toString()))
|
||||
case _ =>
|
||||
Nil
|
||||
}
|
||||
}
|
||||
override def accountRoutings: List[AccountRouting] = {
|
||||
BankAccountRouting.findAll(
|
||||
By(BankAccountRouting.BankId, this.bankId.value),
|
||||
By(BankAccountRouting.AccountId, this.accountId.value)
|
||||
).map(_.accountRouting) match {
|
||||
case Nil => // This is the fallback if the BankAccountRouting failed
|
||||
List(AccountRouting(mAccountRoutingScheme.get, mAccountRoutingAddress.get))
|
||||
case everythingElseJustForward =>
|
||||
everythingElseJustForward
|
||||
}
|
||||
}
|
||||
override def accountRules: List[AccountRule] = createAccountRule(mAccountRuleScheme1.get, mAccountRuleValue1.get.toLong) :::
|
||||
createAccountRule(mAccountRuleScheme2.get, mAccountRuleValue2.get.toLong)
|
||||
}
|
||||
|
||||
object Account extends Account with MongoMetaRecord[Account] {
|
||||
def init = createIndex((permalink.name -> 1) ~ (bankID.name -> 1), true)
|
||||
}
|
||||
|
||||
class HostedBank extends Bank with MongoRecord[HostedBank] with ObjectIdPk[HostedBank]{
|
||||
def meta = HostedBank
|
||||
|
||||
object name extends StringField(this, 255)
|
||||
object alias extends StringField(this, 255)
|
||||
object logoURL extends StringField(this, 255)
|
||||
object website extends StringField(this, 255)
|
||||
object email extends StringField(this, 255)
|
||||
object permalink extends StringField(this, 255)
|
||||
object swiftBIC extends StringField(this, 255)
|
||||
object national_identifier extends StringField(this, 255)
|
||||
object mBankRoutingScheme extends StringField(this, 255)
|
||||
object mBankRoutingAddress extends StringField(this, 255)
|
||||
|
||||
def getAccount(bankAccountId: AccountId) : Box[Account] = {
|
||||
Account.find((Account.permalink.name -> bankAccountId.value) ~ (Account.bankID.name -> id.get)) ?~ {"account " + bankAccountId +" not found at bank " + permalink}
|
||||
}
|
||||
|
||||
def isAccount(bankAccountId : AccountId) : Boolean =
|
||||
Account.count((Account.permalink.name -> bankAccountId.value) ~ (Account.bankID.name -> id.get)) == 1
|
||||
|
||||
override def bankId: BankId = BankId(permalink.get)
|
||||
override def shortName: String = alias.get
|
||||
override def fullName: String = name.get
|
||||
override def logoUrl: String = logoURL.get
|
||||
override def websiteUrl: String = website.get
|
||||
override def swiftBic: String = swiftBIC.get
|
||||
override def nationalIdentifier: String = national_identifier.get
|
||||
override def bankRoutingScheme = mBankRoutingAddress.get
|
||||
override def bankRoutingAddress = mBankRoutingAddress.get
|
||||
}
|
||||
|
||||
object HostedBank extends HostedBank with MongoMetaRecord[HostedBank] {
|
||||
|
||||
def init = createIndex((permalink.name -> 1), true)
|
||||
|
||||
def find(bankId : BankId) : Box[HostedBank] = find(HostedBank.permalink.name -> bankId.value)
|
||||
|
||||
}
|
||||
@ -1,64 +0,0 @@
|
||||
/**
|
||||
Open Bank Project - API
|
||||
Copyright (C) 2011-2019, TESOBE GmbH.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Email: contact@tesobe.com
|
||||
TESOBE GmbH.
|
||||
Osloer Strasse 16/17
|
||||
Berlin 13359, Germany
|
||||
|
||||
This product includes software developed at
|
||||
TESOBE (http://www.tesobe.com/)
|
||||
|
||||
*/
|
||||
package code.model.dataAccess
|
||||
|
||||
import code.api.util.APIUtil
|
||||
import code.metadata.narrative.OBPNarrativeInit
|
||||
import code.metadata.wheretags.OBPWhereTagInit
|
||||
import com.mongodb.MongoClient
|
||||
import net.liftweb.util.ConnectionIdentifier
|
||||
|
||||
object AdminDb extends ConnectionIdentifier {
|
||||
val jndiName = "admin"
|
||||
}
|
||||
|
||||
object MongoConfig {
|
||||
def init: Unit = {
|
||||
import net.liftweb.mongodb.MongoDB
|
||||
import com.mongodb.{Mongo, ServerAddress}
|
||||
import net.liftweb.util.{Props, DefaultConnectionIdentifier}
|
||||
|
||||
|
||||
val srvr = new ServerAddress(
|
||||
APIUtil.getPropsValue("mongo.host", "localhost"),
|
||||
APIUtil.getPropsAsIntValue("mongo.port", 27017)
|
||||
)
|
||||
val defaultDatabase = Props.mode match {
|
||||
case Props.RunModes.Test => "test"
|
||||
case _ => "OBP006"
|
||||
}
|
||||
|
||||
MongoDB.defineDb(DefaultConnectionIdentifier, new MongoClient(srvr), APIUtil.getPropsValue("mongo.dbName", defaultDatabase))
|
||||
MongoDB.defineDb(AdminDb, new MongoClient(srvr), "admin")
|
||||
|
||||
|
||||
HostedBank.init
|
||||
Account.init
|
||||
OBPNarrativeInit.init
|
||||
OBPWhereTagInit.init
|
||||
}
|
||||
}
|
||||
@ -1,408 +0,0 @@
|
||||
/**
|
||||
Open Bank Project - API
|
||||
Copyright (C) 2011-2019, TESOBE GmbH.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Email: contact@tesobe.com
|
||||
TESOBE GmbH.
|
||||
Osloer Strasse 16/17
|
||||
Berlin 13359, Germany
|
||||
|
||||
This product includes software developed at
|
||||
TESOBE (http://www.tesobe.com/)
|
||||
|
||||
*/
|
||||
package code.model.dataAccess
|
||||
|
||||
import code.util.Helper
|
||||
import com.mongodb.QueryBuilder
|
||||
import net.liftweb.mongodb.record.field._
|
||||
import net.liftweb.mongodb.record.{BsonMetaRecord, BsonRecord, MongoMetaRecord, MongoRecord}
|
||||
import net.liftweb.common.{Box, Empty, Failure}
|
||||
import java.util.{Date, UUID}
|
||||
|
||||
import net.liftweb.record.field.{LongField, StringField}
|
||||
import net.liftweb.json.JsonAST._
|
||||
import code.model._
|
||||
import code.util.Helper.MdcLoggable
|
||||
import net.liftweb.record.field.{DecimalField, DoubleField}
|
||||
import net.liftweb.util.FieldError
|
||||
import org.bson.types.ObjectId
|
||||
|
||||
import scala.xml.Unparsed
|
||||
import net.liftweb.json.JsonAST.JObject
|
||||
|
||||
import scala.Some
|
||||
import net.liftweb.json.JsonAST.JString
|
||||
import net.liftweb.common.Full
|
||||
import net.liftweb.json.JsonAST.JField
|
||||
import code.metadata.counterparties.MongoCounterparties
|
||||
import com.openbankproject.commons.model.{AccountId, BankId, TransactionId}
|
||||
|
||||
/**
|
||||
* "Current Account View"
|
||||
curl -i -H "Content-Type: application/json" -X POST -d '[{
|
||||
"obp_transaction":{
|
||||
"this_account":{
|
||||
"holder":"Music Pictures Limited",
|
||||
"number":"123567",
|
||||
"kind":"current",
|
||||
"bank":{
|
||||
"IBAN":"DE1235123612",
|
||||
"national_identifier":"de.10010010",
|
||||
"name":"Postbank"
|
||||
}
|
||||
},
|
||||
"other_account":{
|
||||
"holder":"Client 1",
|
||||
"number":"123567",
|
||||
"kind":"current",
|
||||
"bank":{
|
||||
"IBAN":"UK12222879",
|
||||
"national_identifier":"uk.10010010",
|
||||
"name":"HSBC"
|
||||
}
|
||||
},
|
||||
"details":{
|
||||
"type_en":"Transfer",
|
||||
"type_de":"Überweisung",
|
||||
"posted":{
|
||||
"$dt":"2012-01-04T18:06:22.000Z"
|
||||
},
|
||||
"completed":{
|
||||
"$dt":"2012-09-04T18:52:13.000Z"
|
||||
},
|
||||
"new_balance":{
|
||||
"currency":"EUR",
|
||||
"amount":"4323.45"
|
||||
},
|
||||
"value":{
|
||||
"currency":"EUR",
|
||||
"amount":"123.45"
|
||||
},
|
||||
"other_data":"9"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"obp_transaction":{
|
||||
"this_account":{
|
||||
"holder":"Music Pictures Limited",
|
||||
"number":"123567",
|
||||
"kind":"current",
|
||||
"bank":{
|
||||
"IBAN":"DE1235123612",
|
||||
"national_identifier":"de.10010010",
|
||||
"name":"Postbank"
|
||||
}
|
||||
},
|
||||
"other_account":{
|
||||
"holder":"Client 2",
|
||||
"number":"123567",
|
||||
"kind":"current",
|
||||
"bank":{
|
||||
"IBAN":"UK22222879",
|
||||
"national_identifier":"uk.10010010",
|
||||
"name":"HSBC"
|
||||
}
|
||||
},
|
||||
"details":{
|
||||
"type_en":"Transfer",
|
||||
"type_de":"Überweisung",
|
||||
"posted":{
|
||||
"$dt":"2012-01-04T14:06:22.000Z"
|
||||
},
|
||||
"completed":{
|
||||
"$dt":"2012-09-04T14:52:13.000Z"
|
||||
},
|
||||
"new_balance":{
|
||||
"currency":"EUR",
|
||||
"amount":"2222.45"
|
||||
},
|
||||
"value":{
|
||||
"currency":"EUR",
|
||||
"amount":"223.45"
|
||||
},
|
||||
"other_data":"9"
|
||||
}
|
||||
}
|
||||
}]' http://localhost:8080/api/transactions
|
||||
*/
|
||||
|
||||
// Seems to map to a collection of the plural name
|
||||
class OBPEnvelope private() extends MongoRecord[OBPEnvelope] with ObjectIdPk[OBPEnvelope] with MdcLoggable with TransactionUUID {
|
||||
def meta = OBPEnvelope
|
||||
|
||||
def theTransactionId = TransactionId(transactionId.get)
|
||||
def theAccountId = theAccount.map(_.accountId).getOrElse(AccountId(""))
|
||||
def theBankId = theAccount.map(_.bankId).getOrElse(BankId(""))
|
||||
|
||||
object transactionId extends StringField(this, 100) {
|
||||
override def defaultValue = UUID.randomUUID.toString
|
||||
}
|
||||
|
||||
// This creates a json attribute called "obp_transaction"
|
||||
object obp_transaction extends BsonRecordField(this, OBPTransaction)
|
||||
|
||||
override def validate: List[FieldError] =
|
||||
obp_transaction.get.validate ++
|
||||
super.validate
|
||||
|
||||
object DateDescending extends Ordering[OBPEnvelope] {
|
||||
def compare(e1: OBPEnvelope, e2: OBPEnvelope) = {
|
||||
val date1 = e1.obp_transaction.get.details.get.completed.get
|
||||
val date2 = e2.obp_transaction.get.details.get.completed.get
|
||||
date1.compareTo(date2)
|
||||
}
|
||||
}
|
||||
|
||||
lazy val theAccount: Box[Account] = {
|
||||
import net.liftweb.mongodb.BsonDSL._
|
||||
val thisAcc = obp_transaction.get.this_account.get
|
||||
val num = thisAcc.number.get
|
||||
val bankNationalIdentifier = thisAcc.bank.get.national_identifier.get
|
||||
for {
|
||||
bank <- HostedBank.find((HostedBank.national_identifier.name -> bankNationalIdentifier))
|
||||
bankMongoId : ObjectId = bank.id.get
|
||||
account <- Account.find((Account.accountNumber.name -> num) ~ (Account.bankID.name -> bankMongoId))
|
||||
} yield account
|
||||
}
|
||||
|
||||
def orderByDateDescending = (e1: OBPEnvelope, e2: OBPEnvelope) => {
|
||||
val date1 = e1.obp_transaction.get.details.get.completed.get
|
||||
val date2 = e2.obp_transaction.get.details.get.completed.get
|
||||
date1.after(date2)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object OBPEnvelope extends OBPEnvelope with MongoMetaRecord[OBPEnvelope] with MdcLoggable {
|
||||
|
||||
def envelopesFromJValue(jval: JValue) : Box[OBPEnvelope] = {
|
||||
val createdBox = fromJValue(jval)
|
||||
|
||||
createdBox match {
|
||||
case Full(created) =>
|
||||
val errors = created.validate
|
||||
if(errors.isEmpty) {
|
||||
Full(created)
|
||||
} else {
|
||||
logger.warn("could not create a obp envelope.errors: ")
|
||||
logger.warn(errors)
|
||||
Empty
|
||||
}
|
||||
case Failure(msg, _, _) =>
|
||||
Failure(s"could not create Envelope from JValue: $msg")
|
||||
case _ =>
|
||||
Failure(s"could not create Envelope from JValue")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class OBPTransaction private() extends BsonRecord[OBPTransaction]{
|
||||
def meta = OBPTransaction
|
||||
|
||||
object this_account extends BsonRecordField(this, OBPAccount)
|
||||
object other_account extends BsonRecordField(this, OBPAccount)
|
||||
object details extends BsonRecordField(this, OBPDetails)
|
||||
|
||||
private def validateThisAccount: List[FieldError] = {
|
||||
val accountNumber = this_account.get.number
|
||||
val bankId = this_account.get.bank.get.national_identifier
|
||||
val accountNumberError =
|
||||
if(accountNumber.get.isEmpty)
|
||||
Some(new FieldError(accountNumber, Unparsed("this bank account number is empty")))
|
||||
else
|
||||
None
|
||||
val bankIdError =
|
||||
if(bankId.get.isEmpty)
|
||||
Some(new FieldError(bankId, Unparsed("this bank number is empty")))
|
||||
else
|
||||
None
|
||||
List(accountNumberError, bankIdError).flatten
|
||||
}
|
||||
|
||||
override def validate: List[FieldError] =
|
||||
validateThisAccount ++
|
||||
this_account.get.validate ++
|
||||
other_account.get.validate ++
|
||||
details.get.validate ++
|
||||
super.validate
|
||||
|
||||
@deprecated(Helper.deprecatedJsonGenerationMessage, null)
|
||||
def whenAddedJson(envelopeId : String) : JObject = {
|
||||
JObject(List(JField("obp_transaction_uuid", JString(envelopeId)),
|
||||
JField("this_account", this_account.get.whenAddedJson),
|
||||
JField("other_account", other_account.get.whenAddedJson),
|
||||
JField("details", details.get.whenAddedJson)))
|
||||
}
|
||||
}
|
||||
|
||||
object OBPTransaction extends OBPTransaction with BsonMetaRecord[OBPTransaction]
|
||||
|
||||
class OBPAccount private() extends BsonRecord[OBPAccount]{
|
||||
def meta = OBPAccount
|
||||
|
||||
object holder extends StringField(this, 255){
|
||||
override def required_? = false
|
||||
override def optional_? = true
|
||||
}
|
||||
|
||||
object number extends StringField(this, 255){
|
||||
override def required_? = false
|
||||
override def optional_? = true
|
||||
}
|
||||
object kind extends StringField(this, 255){
|
||||
override def required_? = false
|
||||
override def optional_? = true
|
||||
}
|
||||
object bank extends BsonRecordField(this, OBPBank)
|
||||
|
||||
override def validate: List[FieldError] =
|
||||
holder.validate ++
|
||||
number.validate ++
|
||||
kind.validate ++
|
||||
bank.validate ++
|
||||
super.validate
|
||||
|
||||
/**
|
||||
* @param moderatingAccount a temporary way to provide the obp account whose aliases should
|
||||
* be used when displaying this account
|
||||
*/
|
||||
def whenAddedJson: JObject = {
|
||||
|
||||
JObject(List(JField("holder",
|
||||
JObject(List(
|
||||
JField("holder", JString(holder.get)),
|
||||
JField("alias", JString("no"))))),
|
||||
JField("number", JString(number.get)),
|
||||
JField("kind", JString(kind.get)),
|
||||
JField("bank", bank.get.whenAddedJson)))
|
||||
}
|
||||
}
|
||||
|
||||
object OBPAccount extends OBPAccount with BsonMetaRecord[OBPAccount]{
|
||||
sealed abstract class AnAlias
|
||||
case object APublicAlias extends AnAlias
|
||||
case object APrivateAlias extends AnAlias
|
||||
}
|
||||
|
||||
class OBPBank private() extends BsonRecord[OBPBank]{
|
||||
def meta = OBPBank
|
||||
|
||||
object IBAN extends net.liftweb.record.field.StringField(this, 255)
|
||||
object national_identifier extends net.liftweb.record.field.StringField(this, 255)
|
||||
object name extends net.liftweb.record.field.StringField(this, 255)
|
||||
|
||||
override def validate: List[FieldError] =
|
||||
IBAN.validate ++
|
||||
national_identifier.validate ++
|
||||
name.validate ++
|
||||
super.validate
|
||||
|
||||
|
||||
def whenAddedJson : JObject = {
|
||||
JObject(List( JField("IBAN", JString(IBAN.get)),
|
||||
JField("national_identifier", JString(national_identifier.get)),
|
||||
JField("name", JString(name.get))))
|
||||
}
|
||||
}
|
||||
|
||||
object OBPBank extends OBPBank with BsonMetaRecord[OBPBank]
|
||||
|
||||
|
||||
|
||||
class OBPDetails private() extends BsonRecord[OBPDetails]{
|
||||
def meta = OBPDetails
|
||||
|
||||
object kind extends net.liftweb.record.field.StringField(this, 255){
|
||||
override def required_? = false
|
||||
override def optional_? = true
|
||||
}
|
||||
object posted extends DateField(this)
|
||||
object other_data extends net.liftweb.record.field.StringField(this, 5000){
|
||||
override def required_? = false
|
||||
override def optional_? = true
|
||||
}
|
||||
object new_balance extends BsonRecordField(this, OBPBalance)
|
||||
object value extends BsonRecordField(this, OBPValue)
|
||||
object completed extends DateField(this)
|
||||
object label extends net.liftweb.record.field.StringField(this, 255){
|
||||
override def required_? = false
|
||||
override def optional_? = true
|
||||
}
|
||||
|
||||
override def validate: List[FieldError] =
|
||||
kind.validate ++
|
||||
posted.validate ++
|
||||
other_data.validate ++
|
||||
new_balance.validate ++
|
||||
value.validate ++
|
||||
completed.validate ++
|
||||
label.validate ++
|
||||
super.validate
|
||||
|
||||
|
||||
def formatDate(date : Date) : String = {
|
||||
OBPDetails.formats.dateFormat.format(date)
|
||||
}
|
||||
|
||||
def whenAddedJson : JObject = {
|
||||
JObject(List( JField("type_en", JString(kind.get)),
|
||||
JField("type", JString(kind.get)),
|
||||
JField("posted", JString(formatDate(posted.get))),
|
||||
JField("completed", JString(formatDate(completed.get))),
|
||||
JField("other_data", JString(other_data.get)),
|
||||
JField("new_balance", new_balance.get.whenAddedJson),
|
||||
JField("value", value.get.whenAddedJson)))
|
||||
}
|
||||
}
|
||||
|
||||
object OBPDetails extends OBPDetails with BsonMetaRecord[OBPDetails]
|
||||
|
||||
|
||||
class OBPBalance private() extends BsonRecord[OBPBalance]{
|
||||
def meta = OBPBalance
|
||||
|
||||
object currency extends StringField(this, 5)
|
||||
object amount extends DecimalField(this, 0) // ok to use decimal?
|
||||
|
||||
override def validate: List[FieldError] =
|
||||
currency.validate ++
|
||||
amount.validate ++
|
||||
super.validate
|
||||
|
||||
def whenAddedJson : JObject = {
|
||||
JObject(List( JField("currency", JString(currency.get)),
|
||||
JField("amount", JString(amount.get.toString))))
|
||||
}
|
||||
}
|
||||
|
||||
object OBPBalance extends OBPBalance with BsonMetaRecord[OBPBalance]
|
||||
|
||||
class OBPValue private() extends BsonRecord[OBPValue]{
|
||||
def meta = OBPValue
|
||||
|
||||
object currency extends net.liftweb.record.field.StringField(this, 5)
|
||||
object amount extends net.liftweb.record.field.DecimalField(this, 0) // ok to use decimal?
|
||||
|
||||
def whenAddedJson : JObject = {
|
||||
JObject(List( JField("currency", JString(currency.get)),
|
||||
JField("amount", JString(amount.get.toString))))
|
||||
}
|
||||
}
|
||||
|
||||
object OBPValue extends OBPValue with BsonMetaRecord[OBPValue]
|
||||
@ -1,155 +0,0 @@
|
||||
package code.sandbox
|
||||
|
||||
import code.metadata.counterparties.{MongoCounterparties, Metadata}
|
||||
import code.model._
|
||||
import code.model.dataAccess._
|
||||
import net.liftweb.common._
|
||||
import java.util.UUID
|
||||
import net.liftweb.mapper.By
|
||||
import net.liftweb.mongodb.record.MongoRecord
|
||||
import net.liftweb.util.Helpers._
|
||||
import org.bson.types.ObjectId
|
||||
|
||||
//An basic implementation of Saveable for MongoRecords
|
||||
case class SaveableMongoObj[T <: MongoRecord[_]](value : T) extends Saveable[T] {
|
||||
def save() = value.save(true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports data into the format used by LocalRecordConnector (e.g. HostedBank)
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Not currently using this connector so not updating it at the moment.
|
||||
|
||||
object LocalRecordConnectorDataImport extends OBPDataImport with CreateAuthUsers {
|
||||
|
||||
type BankType = HostedBank
|
||||
type AccountType = Account
|
||||
type TransactionType = OBPEnvelope
|
||||
type MetadataType = Metadata
|
||||
|
||||
protected def createSaveableBanks(data : List[SandboxBankImport]) : Box[List[Saveable[BankType]]] = {
|
||||
val hostedBanks = data.map(b => {
|
||||
HostedBank.createRecord
|
||||
.id(ObjectId.get)
|
||||
.permalink(b.id)
|
||||
.name(b.full_name)
|
||||
.alias(b.short_name)
|
||||
.website(b.website)
|
||||
.logoURL(b.logo)
|
||||
.national_identifier(b.id) //this needs to match up with what goes in the OBPEnvelopes
|
||||
})
|
||||
|
||||
val validationErrors = hostedBanks.flatMap(_.validate)
|
||||
|
||||
if(!validationErrors.isEmpty) {
|
||||
Failure(s"Errors: ${validationErrors.map(_.msg)}")
|
||||
} else {
|
||||
Full(hostedBanks.map(SaveableMongoObj(_)))
|
||||
}
|
||||
}
|
||||
|
||||
protected def createSaveableAccount(acc : SandboxAccountImport, banks : List[HostedBank]) : Box[Saveable[Account]] = {
|
||||
def getHostedBank(acc : SandboxAccountImport) = Box(banks.find(b => b.permalink.get == acc.bank))
|
||||
|
||||
def asSaveableAccount(account : Account, hostedBank : HostedBank) = new Saveable[Account] {
|
||||
val value = account
|
||||
|
||||
def save() = {
|
||||
//this looks pointless, but what it is doing is refreshing the Account.bankID.obj reference, which
|
||||
//is used by Account.bankId. If we don't refresh it here, Account.bankId will return BankId("")
|
||||
account.bankID(account.bankID.get).save(true)
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
hBank <- getHostedBank(acc) ?~ {
|
||||
logger.warn("hosted bank not found")
|
||||
"Server error"
|
||||
}
|
||||
balance <- tryo{BigDecimal(acc.balance.amount)} ?~ s"Invalid balance: ${acc.balance.amount}"
|
||||
} yield {
|
||||
val account = Account.createRecord
|
||||
.permalink(acc.id)
|
||||
.bankID(hBank.id.get)
|
||||
.accountLabel(acc.label)
|
||||
.accountCurrency(acc.balance.currency)
|
||||
.accountBalance(balance)
|
||||
.accountNumber(acc.number)
|
||||
.kind(acc.`type`)
|
||||
.accountIban(acc.IBAN)
|
||||
|
||||
asSaveableAccount(account, hBank)
|
||||
}
|
||||
}
|
||||
|
||||
override protected def createSaveableTransaction(t : SandboxTransactionImport, createdBanks : List[BankType], createdAccounts : List[AccountType]) :
|
||||
Box[Saveable[TransactionType]] = {
|
||||
|
||||
val counterpartyHolder = t.counterparty.flatMap(_.name).getOrElse("")
|
||||
|
||||
for {
|
||||
createdBank <- Box(createdBanks.find(b => b.permalink.get == t.this_account.bank)) ?~
|
||||
s"Transaction this_account bank must be specified in import banks. Unspecified bank: ${t.this_account.bank}"
|
||||
//have to compare a.bankID to createdBank.id instead of just checking a.bankId against t.this_account.bank as createdBank hasn't been
|
||||
//saved so the a.bankId method (which involves a db lookup) will not work
|
||||
createdAcc <- Box(createdAccounts.find(a => a.bankID.toString == createdBank.id.get.toString && a.accountId == AccountId(t.this_account.id))) ?~
|
||||
s"Transaction this_account account must be specified in import accounts. Unspecified account id: ${t.this_account.id} at bank: ${t.this_account.bank}"
|
||||
newBalanceValue <- tryo{BigDecimal(t.details.new_balance)} ?~ s"Invalid new balance: ${t.details.new_balance}"
|
||||
tValue <- tryo{BigDecimal(t.details.value)} ?~ s"Invalid transaction value: ${t.details.value}"
|
||||
postedDate <- tryo{dateFormat.parse(t.details.posted)} ?~ s"Invalid date format: ${t.details.posted}. Expected pattern $datePattern"
|
||||
completedDate <-tryo{dateFormat.parse(t.details.completed)} ?~ s"Invalid date format: ${t.details.completed}. Expected pattern $datePattern"
|
||||
} yield {
|
||||
|
||||
//bankNationalIdentifier not available from createdAcc.bankNationalIdentifier as it hasn't been saved so we get it from createdBank
|
||||
val obpThisAccountBank = OBPBank.createRecord
|
||||
.national_identifier(createdBank.national_identifier.get)
|
||||
|
||||
val obpThisAccount = OBPAccount.createRecord
|
||||
.holder(createdAcc.holder.get)
|
||||
.number(createdAcc.accountNumber.get)
|
||||
.kind(createdAcc.kind.get)
|
||||
.bank(obpThisAccountBank)
|
||||
|
||||
val counterpartyAccountNumber = t.counterparty.flatMap(_.account_number)
|
||||
|
||||
val obpOtherAccount = OBPAccount.createRecord
|
||||
.holder(counterpartyHolder)
|
||||
.number(counterpartyAccountNumber.getOrElse(""))
|
||||
|
||||
val newBalance = OBPBalance.createRecord
|
||||
.amount(newBalanceValue)
|
||||
.currency(createdAcc.accountCurrency.get)
|
||||
|
||||
val transactionValue = OBPValue.createRecord
|
||||
.amount(tValue)
|
||||
.currency(createdAcc.accountCurrency.get)
|
||||
|
||||
val obpDetails = OBPDetails.createRecord
|
||||
.completed(completedDate)
|
||||
.posted(postedDate)
|
||||
.kind(t.details.`type`)
|
||||
.label(t.details.description)
|
||||
.new_balance(newBalance)
|
||||
.value(transactionValue)
|
||||
|
||||
|
||||
val obpTransaction = OBPTransaction.createRecord
|
||||
.details(obpDetails)
|
||||
.this_account(obpThisAccount)
|
||||
.other_account(obpOtherAccount)
|
||||
|
||||
val env = OBPEnvelope.createRecord
|
||||
.transactionId(t.id)
|
||||
.obp_transaction(obpTransaction)
|
||||
|
||||
SaveableMongoObj(env)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
@ -98,7 +98,6 @@ class SandboxDataLoadingTest extends FlatSpec with SendServerRequests with Match
|
||||
m == Nonce || m == code.model.Token || m == code.model.Consumer || m == AuthUser || m == ResourceUser
|
||||
}
|
||||
//drop database tables before
|
||||
//MongoDB.getDb(DefaultMongoIdentifier).foreach(_.dropDatabase())
|
||||
ToSchemify.models.filterNot(exclusion).foreach(_.bulkDelete_!!())
|
||||
ToSchemify.modelsRemotedata.filterNot(exclusion).foreach(_.bulkDelete_!!())
|
||||
//we need to delete the test uses manully here.
|
||||
|
||||
@ -1,107 +0,0 @@
|
||||
package code.setup
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.model._
|
||||
import code.model.dataAccess._
|
||||
import com.mongodb.QueryBuilder
|
||||
import net.liftweb.util.Helpers._
|
||||
import code.api.util.ErrorMessages._
|
||||
import com.openbankproject.commons.model.{AccountId, Bank, BankAccount, BankId}
|
||||
|
||||
import scala.math.BigDecimal
|
||||
import scala.math.BigDecimal.RoundingMode
|
||||
import scala.util.Random._
|
||||
|
||||
/**
|
||||
* This trait is for Liftweb record, link to MangoDB....
|
||||
*/
|
||||
trait LocalRecordConnectorTestSetup extends TestConnectorSetupWithStandardPermissions {
|
||||
|
||||
override protected def createBank(id : String) : Bank = {
|
||||
HostedBank.createRecord.
|
||||
name(randomString(5)).
|
||||
alias(randomString(5)).
|
||||
permalink(id).
|
||||
national_identifier(randomString(5)).
|
||||
save(true)
|
||||
}
|
||||
|
||||
override protected def createAccount(bankId: BankId, accountId : AccountId, currency : String) : BankAccount = {
|
||||
val q = QueryBuilder.start(HostedBank.permalink.name).is(bankId.value).get()
|
||||
val hostedBank = HostedBank.find(q).openOrThrowException(attemptedToOpenAnEmptyBox)
|
||||
|
||||
Account.createRecord.
|
||||
accountBalance(900000000).
|
||||
holder(randomString(4)).
|
||||
accountNumber(randomString(4)).
|
||||
kind(randomString(4)).
|
||||
accountName(randomString(4)).
|
||||
permalink(accountId.value).
|
||||
bankID(hostedBank.id.get).
|
||||
accountLabel(randomString(4)).
|
||||
accountCurrency(currency).
|
||||
save(true)
|
||||
}
|
||||
|
||||
override protected def createTransaction(account: BankAccount, startDate: Date, finishDate: Date) = {
|
||||
|
||||
val thisAccountBank = OBPBank.createRecord.
|
||||
IBAN(randomString(5)).
|
||||
national_identifier(account.nationalIdentifier).
|
||||
name(account.bankName)
|
||||
val thisAccount = OBPAccount.createRecord.
|
||||
holder(account.accountHolder).
|
||||
number(account.number).
|
||||
kind(account.accountType).
|
||||
bank(thisAccountBank)
|
||||
|
||||
val otherAccountBank = OBPBank.createRecord.
|
||||
IBAN(randomString(5)).
|
||||
national_identifier(randomString(5)).
|
||||
name(randomString(5))
|
||||
|
||||
val otherAccount = OBPAccount.createRecord.
|
||||
holder(randomString(5)).
|
||||
number(randomString(5)).
|
||||
kind(randomString(5)).
|
||||
bank(otherAccountBank)
|
||||
|
||||
val transactionAmount = BigDecimal(nextDouble * 1000).setScale(2,RoundingMode.HALF_UP)
|
||||
|
||||
val newBalance : OBPBalance = OBPBalance.createRecord.
|
||||
currency(account.currency).
|
||||
amount(account.balance + transactionAmount)
|
||||
|
||||
val newValue : OBPValue = OBPValue.createRecord.
|
||||
currency(account.currency).
|
||||
amount(transactionAmount)
|
||||
|
||||
val details ={
|
||||
OBPDetails
|
||||
.createRecord
|
||||
.kind(randomString(5))
|
||||
.posted(startDate)
|
||||
.other_data(randomString(5))
|
||||
.new_balance(newBalance)
|
||||
.value(newValue)
|
||||
.completed(finishDate)
|
||||
.label(randomString(5))
|
||||
}
|
||||
val transaction = OBPTransaction.createRecord.
|
||||
this_account(thisAccount).
|
||||
other_account(otherAccount).
|
||||
details(details)
|
||||
|
||||
val env = OBPEnvelope.createRecord.
|
||||
obp_transaction(transaction).save(true)
|
||||
|
||||
//slightly ugly
|
||||
account.asInstanceOf[Account].accountBalance(newBalance.amount.get).accountLastUpdate(now).save(true)
|
||||
|
||||
env.save(true)
|
||||
}
|
||||
|
||||
override protected def createTransactionRequest(account: BankAccount) = Nil
|
||||
|
||||
}
|
||||
@ -8,8 +8,6 @@ import code.model.dataAccess._
|
||||
import code.views.Views
|
||||
import com.openbankproject.commons.model._
|
||||
import net.liftweb.mapper.MetaMapper
|
||||
import net.liftweb.mongodb._
|
||||
import net.liftweb.util.DefaultConnectionIdentifier
|
||||
import net.liftweb.util.Helpers._
|
||||
|
||||
/**
|
||||
@ -40,9 +38,6 @@ trait TestConnectorSetupWithStandardPermissions extends TestConnectorSetup {
|
||||
|
||||
protected def wipeTestData(): Unit = {
|
||||
|
||||
//drop the mongo Database after each test
|
||||
MongoDB.getDb(DefaultConnectionIdentifier).foreach(_.dropDatabase())
|
||||
|
||||
//returns true if the model should not be wiped after each test
|
||||
def exclusion(m : MetaMapper[_]) = {
|
||||
m == Nonce || m == Token || m == Consumer || m == AuthUser || m == ResourceUser
|
||||
|
||||
Loading…
Reference in New Issue
Block a user