Adding customerId (UUID) to Customer, an additional guard in addCustomer

This commit is contained in:
Simon Redfern 2016-05-21 14:49:44 +02:00
parent 9329ec066c
commit f2aaa11972
10 changed files with 78 additions and 12 deletions

View File

@ -66,13 +66,15 @@ To compile and run jetty, install Maven 3 and execute:
* Run a single test. For instance right click on test/scala/code/branches/MappedBranchProviderTest and select Run Mapp...
* Run multiple tests: Right click on code and select Run. If need be:
* Run multiple tests: Right click on test/scala/code and select Run. If need be:
Goto Run / Debug configurations
Test Kind: Select All in Package
Package: Select code
Add the absolute /path-to-your-OBP-API in the "working directory" field
Add the absolute /path-to-your-OBP-API in the "working directory" field
You might need to assign more memory via VM Options: e.g. -Xmx1512M -XX:MaxPermSize=512M
Make sure your test.default.props has the minimum settings (see test.default.props.template)
Right click test/scala/code and select the Scala Tests in code to run them all.

View File

@ -83,6 +83,9 @@ object ErrorMessages {
val ViewNotFound = "OBP-30005: View not found for Account. Please specify a valid value for VIEW_ID"
val CustomerNumberAlreadyExists = "OBP-30006: Customer Number already exists. Please specify a different value for BANK_ID or CUSTOMER_NUMBER."
val CustomerAlreadyExistsForUser = "OBP-30007: The User is already linked to a Customer at BANK_ID"
// Transaction related messages:
val InvalidTransactionRequestType = "OBP-40001: Invalid value for TRANSACTION_REQUEST_TYPE"

View File

@ -570,7 +570,7 @@ trait APIMethods140 extends Loggable with APIMethods130 with APIMethods121{
|Dates need to be in the format 2013-01-21T23:08:00Z
|OAuth authentication is required.
|""",
Extraction.decompose(CustomerJson("687687678", "Joe David Bloggs",
Extraction.decompose(PostCustomerJson("687687678", "Joe David Bloggs",
"+44 07972 444 876", "person@example.com", CustomerFaceImageJson("www.example.com/person/123/image.png", exampleDate),
exampleDate, "Single", 1, List(exampleDate), "Bachelors Degree", "Employed", true, exampleDate)),
emptyObjectJson,
@ -587,8 +587,9 @@ trait APIMethods140 extends Loggable with APIMethods130 with APIMethods121{
for {
u <- user ?~! "User must be logged in to post Customer"
bank <- tryo(Bank(bankId).get) ?~! {ErrorMessages.BankNotFound}
customer <- booleanToBox(Customer.customerProvider.vend.getCustomer(bankId, u).isEmpty) ?~ "Customer already exists for this user."
postedData <- tryo{json.extract[CustomerJson]} ?~! "Incorrect json format"
customer <- booleanToBox(Customer.customerProvider.vend.getCustomer(bankId, u).isEmpty) ?~ ErrorMessages.CustomerAlreadyExistsForUser
postedData <- tryo{json.extract[PostCustomerJson]} ?~! ErrorMessages.InvalidJsonFormat
checkAvailable <- tryo(assert(Customer.customerProvider.vend.checkCustomerNumberAvailable(bankId, postedData.customer_number) == true)) ?~! ErrorMessages.CustomerNumberAlreadyExists
customer <- Customer.customerProvider.vend.addCustomer(bankId,
u,
postedData.customer_number,

View File

@ -22,7 +22,25 @@ import code.api.v1_2_1.{AmountOfMoneyJSON}
object JSONFactory1_4_0 {
case class CustomerJson(customer_number : String,
case class PostCustomerJson(
customer_number : String,
legal_name : String,
mobile_phone_number : String,
email : String,
face_image : CustomerFaceImageJson,
date_of_birth: Date,
relationship_status: String,
dependants: Int,
dob_of_dependants: List[Date],
highest_education_attained: String,
employment_status: String,
kyc_status: Boolean,
last_ok_date: Date)
case class CustomerJson(customer_id: String,
customer_number : String,
legal_name : String,
mobile_phone_number : String,
email : String,
@ -83,6 +101,7 @@ object JSONFactory1_4_0 {
def createCustomerJson(cInfo : Customer) : CustomerJson = {
CustomerJson(
customer_id = cInfo.customerId,
customer_number = cInfo.number,
legal_name = cInfo.legalName,
mobile_phone_number = cInfo.mobileNumber,

View File

@ -17,7 +17,10 @@ object Customer extends SimpleInjector {
trait CustomerProvider {
def getCustomer(bankId : BankId, user : User) : Box[Customer]
def getUser(bankId : BankId, customerId : String) : Box[User]
def getUser(bankId : BankId, customerNumber : String) : Box[User]
def checkCustomerNumberAvailable(bankId : BankId, customerNumber : String) : Boolean
def addCustomer(bankId: BankId, user: User, number: String, legalName: String, mobileNumber: String, email: String, faceImage: CustomerFaceImage,
dateOfBirth: Date,
@ -32,7 +35,8 @@ trait CustomerProvider {
}
trait Customer {
def number : String
def customerId : String // The UUID for the customer. To be used in URLs
def number : String // The Customer number i.e. the bank identifier for the customer.
def legalName : String
def mobileNumber : String
def email : String

View File

@ -4,12 +4,27 @@ import java.util.Date
import code.model.{BankId, User}
import code.model.dataAccess.APIUser
import code.util.DefaultStringField
import code.util.{MappedUUID, DefaultStringField}
import net.liftweb.common.Box
import net.liftweb.mapper._
object MappedCustomerProvider extends CustomerProvider {
override def checkCustomerNumberAvailable(bankId : BankId, customerNumber : String) : Boolean = {
val customers = MappedCustomer.findAll(
By(MappedCustomer.mBank, bankId.value),
By(MappedCustomer.mNumber, customerNumber)
)
val available: Boolean = customers.size match {
case 0 => true
case _ => false
}
available
}
override def getCustomer(bankId : BankId, user: User): Box[Customer] = {
MappedCustomer.find(
By(MappedCustomer.mUser, user.apiId.value),
@ -52,6 +67,8 @@ class MappedCustomer extends Customer with LongKeyedMapper[MappedCustomer] with
def getSingleton = MappedCustomer
object mCustomerId extends MappedUUID(this)
object mUser extends MappedLongForeignKey(this, APIUser)
object mBank extends DefaultStringField(this)
@ -69,6 +86,7 @@ class MappedCustomer extends Customer with LongKeyedMapper[MappedCustomer] with
object mKycStatus extends MappedBoolean(this)
object mLastOkDate extends MappedDateTime(this)
override def customerId: String = mCustomerId.get // id.toString
override def number: String = mNumber.get
override def mobileNumber: String = mMobileNumber.get
override def legalName: String = mLegalName.get

View File

@ -9,6 +9,7 @@ import net.liftweb.mapper._
object MappedKycDocumentsProvider extends KycDocumentProvider {
// TODO Add bankId (customerNumber is not unique)
override def getKycDocuments(customerNumber: String): List[MappedKycDocument] = {
MappedKycDocument.findAll(
By(MappedKycDocument.mCustomerNumber, customerNumber),

View File

@ -112,6 +112,16 @@ object BankId {
def unapply(id : String) = Some(BankId(id))
}
case class CustomerId(val value : String) {
override def toString = value
}
object CustomerId {
def unapply(id : String) = Some(CustomerId(id))
}
// In preparation for use in Context (api links) To replace OtherAccountId
case class CounterpartyId(val value : String) {
override def toString = value

View File

@ -16,7 +16,7 @@ class CustomerTest extends V140ServerSetup with DefaultUsers {
case class MockFaceImage(date : Date, url : String) extends CustomerFaceImage
case class MockCustomer(number: String, mobileNumber: String,
case class MockCustomer(customerId: String, number: String, mobileNumber: String,
legalName: String, email: String,
faceImage: MockFaceImage, dateOfBirth: Date,
relationshipStatus: String, dependents: Int,
@ -25,9 +25,12 @@ class CustomerTest extends V140ServerSetup with DefaultUsers {
val format = new java.text.SimpleDateFormat("dd/MM/yyyy")
val mockCustomerFaceImage = MockFaceImage(new Date(1234000), "http://example.com/image1")
val mockCustomer = MockCustomer("123", "3939", "Bob", "bob@example.com", mockCustomerFaceImage, new Date(1234000), "Single", 3, List(format.parse("30/03/2012"), format.parse("30/03/2012"), format.parse("30/03/2014")), "Bachelors Degree", "Employed", true, new Date(1234000))
val mockCustomer = MockCustomer("uuid-aisuhuiuhuikjhfd", "123", "3939", "Bob", "bob@example.com", mockCustomerFaceImage, new Date(1234000), "Single", 3, List(format.parse("30/03/2012"), format.parse("30/03/2012"), format.parse("30/03/2014")), "Bachelors Degree", "Employed", true, new Date(1234000))
object MockedCustomerProvider extends CustomerProvider {
override def checkCustomerNumberAvailable(bankId : BankId, customerNumber : String) = {true}
override def getCustomer(bankId: BankId, user: User): Box[Customer] = {
if(bankId == mockBankId) Full(mockCustomer)
else Empty
@ -105,7 +108,9 @@ class CustomerTest extends V140ServerSetup with DefaultUsers {
And("We should get the right information back")
val info = response.body.extract[CustomerJson]
val received = MockCustomer(info.customer_number,
val received = MockCustomer(
info.customer_id,
info.customer_number,
info.mobile_phone_number,
info.legal_name,
info.email,

View File

@ -17,6 +17,8 @@ class MappedCustomerMessagesTest extends V140ServerSetup with DefaultUsers {
val mockBankId = BankId("testBank1")
val mockCustomerNumber = "9393490320"
val mockCustomerId = "uuid-asdfasdfaoiu8u8u8hkjhsf"
val exampleDateString : String ="22/08/2013"
val simpleDateFormat : SimpleDateFormat = new SimpleDateFormat("dd/mm/yyyy")
@ -44,6 +46,7 @@ class MappedCustomerMessagesTest extends V140ServerSetup with DefaultUsers {
//first add a customer to send message to
var request = (v1_4Request / "banks" / mockBankId.value / "customer").POST <@ user1
var customerJson = CustomerJson(
customer_id = mockCustomerId,
customer_number = mockCustomerNumber,
legal_name = "Someone",
mobile_phone_number = "125245",