forked from snowplow/snowplow
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Scala Common Enrich: converting transactions from given currency to "…
…home currency" (closes snowplow#370) Scala Common Enrich: converting transactions from given currency to home currency Scala Common Enrich: converting transactions from given currency to home currency Scala Common Enrich: converting transactions from given currency to home currency Scala Common Enrich: converting transactions from given currency to home currency (closes snowplow#370) Scala Common Enrich: converting transactions from given currency to home currency (closes snowplow#370)
- Loading branch information
Showing
7 changed files
with
301 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
157 changes: 157 additions & 0 deletions
157
...wanalytics.snowplow.enrich/common/enrichments/registry/CurrencyConversionEnrichment.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
/* | ||
* Copyright (c) 2012-2015 Snowplow Analytics Ltd. All rights reserved. | ||
* | ||
* This program is licensed to you under the Apache License Version 2.0, | ||
* and you may not use this file except in compliance with the Apache License Version 2.0. | ||
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the Apache License Version 2.0 is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. | ||
*/ | ||
package com.snowplowanalytics | ||
package snowplow | ||
package enrich | ||
package common | ||
package enrichments | ||
package registry | ||
|
||
// Java | ||
import java.net.URI | ||
|
||
// Maven Artifact | ||
import org.apache.maven.artifact.versioning.DefaultArtifactVersion | ||
|
||
// Scalaz | ||
import scalaz._ | ||
import Scalaz._ | ||
|
||
// json4s | ||
import org.json4s.JValue | ||
|
||
// Iglu | ||
import iglu.client.SchemaKey | ||
import iglu.client.validation.ProcessingMessageMethods._ | ||
|
||
// Scala Forex | ||
import org.joda.money.{Money} | ||
import org.joda.time.{DateTime, DateTimeZone} | ||
import com.snowplowanalytics.forex._ | ||
import com.snowplowanalytics.forex.oerclient.{OerClientConfig, DeveloperAccount, AccountType, OerResponseError} | ||
import com.snowplowanalytics.forex.oerclient.OerResponseError._ | ||
import com.snowplowanalytics.forex.{Forex, ForexConfig} | ||
import com.snowplowanalytics.forex.ForexLookupWhen._ | ||
//import org.joda.money.BigMoney.convertedTo | ||
// This project | ||
import common.utils.ConversionUtils | ||
import utils.ScalazJson4sUtils | ||
|
||
/** | ||
* Companion object. Lets us create an CurrencyConversionEnrichment | ||
* instance from a JValue. | ||
*/ | ||
object CurrencyConversionEnrichmentConfig extends ParseableEnrichment { | ||
|
||
val supportedSchemaKey = SchemaKey("com.snowplowanalytics.snowplow", "currency_conversion_config", "jsonschema", "1-0-0") | ||
|
||
//Creates an CurrencyConversionEnrichment instance from a JValue | ||
def parse(config: JValue, schemaKey: SchemaKey): ValidatedNelMessage[CurrencyConversionEnrichment] = { | ||
isParseable(config, schemaKey).flatMap( conf => { | ||
(for { | ||
apiKey <- ScalazJson4sUtils.extract[String](config, "parameters", "apiKey") | ||
baseCurrency <- ScalazJson4sUtils.extract[String](config, "parameters", "baseCurrency") | ||
rateAt <- ScalazJson4sUtils.extract[String](config, "parameters", "rateAt") | ||
enrich = CurrencyConversionEnrichment(apiKey, baseCurrency, rateAt) | ||
} yield enrich).toValidationNel | ||
}) | ||
} | ||
} | ||
|
||
/** | ||
* Case class to wrap everything we | ||
* can extract as converted Transaction | ||
* Amounts. | ||
*/ | ||
case class TransactionAmounts( | ||
total: String, | ||
tax: String, | ||
shipping: String) | ||
|
||
// Object and a case object with the same name | ||
|
||
case class CurrencyConversionEnrichment( | ||
apiKey: String, | ||
baseCurrency: String, | ||
rateAt: String) extends Enrichment { | ||
|
||
val version = new DefaultArtifactVersion("0.1.0") | ||
|
||
// To convert string value to double | ||
|
||
def toDouble(s: String) = try { | ||
Some(s.toDouble) | ||
} catch { | ||
case _ => None | ||
} | ||
|
||
// To provide Validation for org.joda.money.Money variable | ||
def eitherToValidation(input:Either[OerResponseError, Money]): Validation[String, Double]= { | ||
input match { | ||
case Right(l) => (l.getAmount().doubleValue()).success[String] | ||
case Left(l) => (s"Open Exchange Rates error, message: ${l.errorMessage}").failure | ||
} | ||
} | ||
|
||
// To retrieve value from Success/Failure and parse them as string | ||
def tryParse(s: Either[OerResponseError, Money]):String = { | ||
eitherToValidation(s) match { | ||
case Success(pass) => { | ||
pass.toString() | ||
} | ||
case Failure(fail) => { | ||
fail | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Convert's currency for a given | ||
* set of currency, using | ||
* Scala-Forex. | ||
* | ||
* @param trCurrency The desired | ||
* currency for a given | ||
* amount | ||
* @param trAmounts Contains | ||
* total amount, tax, shipping | ||
* amount's | ||
* @param tiCurrency Trasaction Item | ||
* Currency | ||
* @param tiPrice Trasaction Item | ||
* Price | ||
* @return the converted currency | ||
* in TransacrionAmounts | ||
* format and Ttansaction | ||
* Item Price | ||
*/ | ||
def convertCurrencies(trCurrency: String, trAmounts: TransactionAmounts, tiCurrency: String, tiPrice: String): ValidationNel[String, (TransactionAmounts, String)] = { | ||
|
||
try{ | ||
val fx = Forex(ForexConfig( nowishCacheSize = 0, nowishSecs = 0, eodCacheSize= 0, baseCurrency = baseCurrency), OerClientConfig(apiKey, DeveloperAccount)) | ||
val newCurrencyTr = fx.convert((toDouble(trAmounts.total)).get).to(trCurrency).nowish | ||
val newCurrencyTi = fx.convert((toDouble(tiPrice)).get).to(tiCurrency).nowish | ||
val newTrAmountsTax = fx.convert((toDouble(trAmounts.tax)).get).to(trCurrency).nowish | ||
val newTrAmountsShipping = fx.convert((toDouble(trAmounts.shipping)).get).to(trCurrency).nowish | ||
val newCurrencyList = List(newCurrencyTr, newCurrencyTi, newTrAmountsTax, newTrAmountsShipping) | ||
val tupleArray = newCurrencyList.map(element=>tryParse(element)) | ||
val returnTuple = (TransactionAmounts(tupleArray(0), tupleArray(2), tupleArray(3)), tupleArray(1)) | ||
returnTuple.success | ||
|
||
} catch { | ||
case e => "Exception Converting Currency :[%s]".format( e.getMessage).failureNel | ||
} | ||
|
||
} | ||
} | ||
|
61 changes: 61 additions & 0 deletions
61
...lytics.snowplow.enrich.common/enrichments/registry/CurrencyConversionEnrichmentSpec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* Copyright (c) 2012-2014 Snowplow Analytics Ltd. All rights reserved. | ||
* | ||
* This program is licensed to you under the Apache License Version 2.0, | ||
* and you may not use this file except in compliance with the Apache License Version 2.0. | ||
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0. | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the Apache License Version 2.0 is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. | ||
*/ | ||
package com.snowplowanalytics.snowplow.enrich.common | ||
package enrichments | ||
package registry | ||
|
||
// Specs2 | ||
import org.specs2.Specification | ||
import org.specs2.matcher.DataTables | ||
import org.specs2.scalaz._ | ||
|
||
// Scalaz | ||
import scalaz._ | ||
import Scalaz._ | ||
|
||
|
||
// Scala Forex | ||
import org.joda.time.{DateTime, DateTimeZone} | ||
import com.snowplowanalytics.forex._ | ||
import com.snowplowanalytics.forex.oerclient.{OerClientConfig, DeveloperAccount, AccountType} | ||
import com.snowplowanalytics.forex.{Forex, ForexConfig} | ||
|
||
import com.snowplowanalytics.snowplow.enrich.common.enrichments.registry._ | ||
// This project | ||
//import object com.snowplowanalytics.snowplow.enrich.common.enrichments.registry.CurrencyConversionEnrichment | ||
/** | ||
* Tests the convertCurrencies function | ||
*/ | ||
|
||
class CurrencyConversionEnrichmentSpec extends Specification with DataTables { def is = | ||
|
||
"This is a specification to test convertCurrencies" ^ | ||
p^ | ||
"Currency Conversion should work" ! e1^ | ||
end | ||
|
||
val appIdInvalid = (TransactionAmounts("Open Exchange Rates error, message: Invalid App ID provided - please sign up at https://openexchangerates.org/signup, or contact support@openexchangerates.org. Thanks!","Open Exchange Rates error, message: Invalid App ID provided - please sign up at https://openexchangerates.org/signup, or contact support@openexchangerates.org. Thanks!","Open Exchange Rates error, message: Invalid App ID provided - please sign up at https://openexchangerates.org/signup, or contact support@openexchangerates.org. Thanks!"),"Open Exchange Rates error, message: Invalid App ID provided - please sign up at https://openexchangerates.org/signup, or contact support@openexchangerates.org. Thanks!") | ||
def e1 = | ||
"SPEC NAME" || "TRANSACTION PRICE" | "API Key" | "TRANSACTION AMOUNT" | "TRANSACTION ITEM CURRENCY" | "TRANSACTION ITEM PRICE" |"CONVERTED TUPLE" | | ||
"First Success Test" !! "GBP" ! "" ! TransactionAmounts("12.99", "2.67", "0") ! "GBP" ! "12.99" !(TransactionAmounts("8.65","1.78","0.0"),"8.65").success | | ||
"First Failure Test" !! "RUP" ! "" ! TransactionAmounts("14.99", "1.17", "0") ! "GBP" ! "17.99" ! "Exception Converting Currency :[Either.left.value on Right]".failureNel | | ||
"Second Failure Test" !! "HUL" ! "" ! TransactionAmounts("10.99", "0.7", "0") ! "GBP" ! "1.99" ! "Exception Converting Currency :[Either.left.value on Right]".failureNel | | ||
"Third Failure Test" !! "GBP" ! "89ab8d8dabdj9usd9d8siasjndsajA8Ada8" ! TransactionAmounts("2.99", "3.67", "0") ! "GBP" ! "2.99" ! appIdInvalid.success | | ||
"Second Success Test" !! "USD" ! "" ! TransactionAmounts("11.09", "4.67", "2") ! "GBP" ! "10.99" !(TransactionAmounts("11.09","4.67","2.0"),"7.32").success | | ||
"Third Success Test" !! "GBP" ! "" ! TransactionAmounts("10.00", "2.67", "0") ! "GBP" ! "10.00" !(TransactionAmounts("6.66","1.78","0.0"),"6.66").success |> { | ||
(_, trPrice, apiKey, trAmount, tiCurrency, tiPrice, expected) => | ||
CurrencyConversionEnrichment(apiKey, "EUR", "EOD_PRIOR").convertCurrencies(trPrice, trAmount, tiCurrency, tiPrice) must_== expected | ||
} | ||
|
||
} | ||
|
Oops, something went wrong.