<commit_before>/*
 * Copyright 2015 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package scintuit.data

import com.github.nscala_money.money.Imports._
import com.github.nscala_time.time.Imports._
import enumeratum.EnumEntry._
import enumeratum.{Enum, EnumEntry}

import scalaz.Scalaz._

sealed abstract class CorrectionAction extends EnumEntry with Uppercase
object CorrectionAction extends Enum[CorrectionAction] {
  val values = findValues
  case object Replace extends CorrectionAction
  case object Delete extends CorrectionAction
}

// ================================== Investment Banking Transaction Types ==================================
sealed abstract class InvestmentSubAccountType extends EnumEntry with Uppercase
object InvestmentSubAccountType extends Enum[InvestmentSubAccountType] {
  val values = findValues
  case object Cash extends InvestmentSubAccountType
  case object Margin extends InvestmentSubAccountType
  case object Short extends InvestmentSubAccountType
  case object Other extends InvestmentSubAccountType
}

sealed abstract class Banking401KSourceType extends EnumEntry with Uppercase
object Banking401KSourceType extends Enum[Banking401KSourceType] {
  val values = findValues
  case object PreTax extends Banking401KSourceType
  case object AfterTax extends Banking401KSourceType
  case object Match extends Banking401KSourceType
  case object ProfitSharing extends Banking401KSourceType
  case object Rollover extends Banking401KSourceType
  case object OtherVest extends Banking401KSourceType
  case object OtherNonVest extends Banking401KSourceType
}

// ================================== Investment Transaction Types ==================================
sealed abstract class BuyType extends EnumEntry with Uppercase
object BuyType extends Enum[BuyType] {
  val values = findValues
  case object Buy extends BuyType
  case object BuyToCover extends BuyType
}

sealed abstract class IncomeType extends EnumEntry with Uppercase
object IncomeType extends Enum[IncomeType] {
  val values = findValues
  case object CapitalGainsLong extends IncomeType {override def entryName: String = "CGLONG"}
  case object CapitalGainsShort extends IncomeType {override def entryName: String = "CGSHORT"}
  case object Dividend extends IncomeType {override def entryName: String = "DIV"}
  case object Interest extends IncomeType
  case object Misc extends IncomeType
}

sealed abstract class OptionsAction extends EnumEntry with Uppercase
object OptionsAction extends Enum[OptionsAction] {
  val values = findValues
  case object Exercise extends OptionsAction
  case object Assign extends OptionsAction
  case object Expire extends OptionsAction
}

sealed abstract class OptionsBuyType extends EnumEntry with Uppercase
object OptionsBuyType extends Enum[OptionsBuyType] {
  val values = findValues
  case object BuyToOpen extends OptionsBuyType
  case object BuyToClose extends OptionsBuyType
}

sealed abstract class OptionsSellType extends EnumEntry with Uppercase
object OptionsSellType extends Enum[OptionsSellType] {
  val values = findValues
  case object SellToOpen extends OptionsSellType
  case object SellToClose extends OptionsSellType
}

sealed abstract class PositionType extends EnumEntry with Uppercase
object PositionType extends Enum[PositionType] {
  val values = findValues
  case object Long extends PositionType
  case object Short extends PositionType
}

sealed abstract class TransferAction extends EnumEntry with Uppercase
object TransferAction extends Enum[TransferAction] {
  val values = findValues
  case object In extends TransferAction
  case object Out extends TransferAction
}

sealed abstract class RelatedOptionTransactionType extends EnumEntry with Uppercase
object RelatedOptionTransactionType extends Enum[RelatedOptionTransactionType] {
  val values = findValues
  case object Spread extends RelatedOptionTransactionType
  case object Straddle extends RelatedOptionTransactionType
  case object None extends RelatedOptionTransactionType
  case object Other extends RelatedOptionTransactionType
}

sealed abstract class SecuredType extends EnumEntry with Uppercase
object SecuredType extends Enum[SecuredType] {
  val values = findValues
  case object Naked extends SecuredType
  case object Covered extends SecuredType
}

sealed abstract class SellReason extends EnumEntry with Uppercase
object SellReason extends Enum[SellReason] {
  val values = findValues
  case object Call extends SellReason
  case object Sell extends SellReason
  case object Maturity extends SellReason
}

sealed abstract class SellType extends EnumEntry with Uppercase
object SellType extends Enum[SellType] {
  val values = findValues
  case object Sell extends SellType
  case object SellShort extends SellType
}

// ================================== Categorization ==================================
sealed abstract class CategorizationSource extends EnumEntry with Uppercase
object CategorizationSource extends Enum[CategorizationSource] {
  val values = findValues
  case object Aggr extends CategorizationSource
  case object OFX extends CategorizationSource
  case object Cat extends CategorizationSource
}

case class RawCategorization(
  common: RawCategorizationCommon,
  context: Vector[RawCategorizationContext]
)

case class RawCategorizationCommon(
  normalizedPayeeName: Option[String],
  merchant: Option[String],
  sic: Option[Int]
)

case class RawCategorizationContext(
  source: Option[CategorizationSource],
  categoryName: Option[String],
  contextType: Option[String],
  scheduleC: Option[String]
)

case class CategorizationContext(raw: RawCategorizationContext) {
  def category: Option[String] = raw.categoryName
  def scheduleC: Option[String] = raw.scheduleC

  def source: Option[CategorizationSource] = raw.source
  def contextType: Option[String] = raw.contextType
}

case class Categorization(raw: RawCategorization) {
  def payee: Option[String] = raw.common.normalizedPayeeName
  def merchant: Option[String] = raw.common.merchant
  def sic: Option[String] = raw.common.sic map (_.toString)

  def contexts: Vector[CategorizationContext] = raw.context map CategorizationContext
}

// ================================== Transactions ==================================
sealed trait RawTransaction {
  val id: TransactionId
  val currencyType: Option[CurrencyUnit]
  val institutionTransactionId: Option[String]
  val correctInstitutionTransactionId: Option[String]
  val correctAction: Option[CorrectionAction]
  val serverTransactionId: Option[String]
  val checkNumber: Option[String]
  val refNumber: Option[String]
  val confirmationNumber: Option[String]
  val payeeId: Option[String]
  val payeeName: Option[String]
  val extendedPayeeName: Option[String]
  val memo: Option[String]
  val `type`: Option[String]
  val valueType: Option[String]
  val currencyRate: Option[BigDecimal]
  val currencyOriginal: Option[Boolean]
  val postedDate: Option[DateTime]
  val userDate: Option[DateTime]
  val availableDate: Option[DateTime]
  val amount: Option[BigDecimal]
  val runningBalanceAmount: Option[BigDecimal]
  val pending: Option[Boolean]
  val categorization: RawCategorization
}

sealed trait Transaction {
  val raw: RawTransaction

  private[data] def toMoney(amount: Option[BigDecimal]): Option[BigMoney] =
    (raw.currencyType |@| amount)(BigMoney.of)

  def id: TransactionId = raw.id
  def idInstitution: Option[String] = raw.institutionTransactionId
  def idServer: Option[String] = raw.serverTransactionId

  def currency: Option[CurrencyUnit] = raw.currencyType
  def currencyRate: Option[BigDecimal] = raw.currencyRate
  def currencyConverted: Option[Boolean] = raw.currencyOriginal

  def amount: Option[BigMoney] = toMoney(raw.amount)
  def pending: Option[Boolean] = raw.pending
  def `type`: Option[String] = raw.`type`

  def memo: Option[String] = raw.memo
  def categorization: Categorization = Categorization(raw.categorization)
  def payeeId: Option[String] = raw.payeeId
  def payeeName: Option[String] = raw.payeeName
  def payeeNameExtended: Option[String] = raw.extendedPayeeName<commit_msg>add absolute amount field to transactions<commit_after>/*
 * Copyright 2015 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package scintuit.data

import com.github.nscala_money.money.Imports._
import com.github.nscala_time.time.Imports._
import enumeratum.EnumEntry._
import enumeratum.{Enum, EnumEntry}

import scalaz.Scalaz._

sealed abstract class CorrectionAction extends EnumEntry with Uppercase
object CorrectionAction extends Enum[CorrectionAction] {
  val values = findValues
  case object Replace extends CorrectionAction
  case object Delete extends CorrectionAction
}

// ================================== Investment Banking Transaction Types ==================================
sealed abstract class InvestmentSubAccountType extends EnumEntry with Uppercase
object InvestmentSubAccountType extends Enum[InvestmentSubAccountType] {
  val values = findValues
  case object Cash extends InvestmentSubAccountType
  case object Margin extends InvestmentSubAccountType
  case object Short extends InvestmentSubAccountType
  case object Other extends InvestmentSubAccountType
}

sealed abstract class Banking401KSourceType extends EnumEntry with Uppercase
object Banking401KSourceType extends Enum[Banking401KSourceType] {
  val values = findValues
  case object PreTax extends Banking401KSourceType
  case object AfterTax extends Banking401KSourceType
  case object Match extends Banking401KSourceType
  case object ProfitSharing extends Banking401KSourceType
  case object Rollover extends Banking401KSourceType
  case object OtherVest extends Banking401KSourceType
  case object OtherNonVest extends Banking401KSourceType
}

// ================================== Investment Transaction Types ==================================
sealed abstract class BuyType extends EnumEntry with Uppercase
object BuyType extends Enum[BuyType] {
  val values = findValues
  case object Buy extends BuyType
  case object BuyToCover extends BuyType
}

sealed abstract class IncomeType extends EnumEntry with Uppercase
object IncomeType extends Enum[IncomeType] {
  val values = findValues
  case object CapitalGainsLong extends IncomeType {override def entryName: String = "CGLONG"}
  case object CapitalGainsShort extends IncomeType {override def entryName: String = "CGSHORT"}
  case object Dividend extends IncomeType {override def entryName: String = "DIV"}
  case object Interest extends IncomeType
  case object Misc extends IncomeType
}

sealed abstract class OptionsAction extends EnumEntry with Uppercase
object OptionsAction extends Enum[OptionsAction] {
  val values = findValues
  case object Exercise extends OptionsAction
  case object Assign extends OptionsAction
  case object Expire extends OptionsAction
}

sealed abstract class OptionsBuyType extends EnumEntry with Uppercase
object OptionsBuyType extends Enum[OptionsBuyType] {
  val values = findValues
  case object BuyToOpen extends OptionsBuyType
  case object BuyToClose extends OptionsBuyType
}

sealed abstract class OptionsSellType extends EnumEntry with Uppercase
object OptionsSellType extends Enum[OptionsSellType] {
  val values = findValues
  case object SellToOpen extends OptionsSellType
  case object SellToClose extends OptionsSellType
}

sealed abstract class PositionType extends EnumEntry with Uppercase
object PositionType extends Enum[PositionType] {
  val values = findValues
  case object Long extends PositionType
  case object Short extends PositionType
}

sealed abstract class TransferAction extends EnumEntry with Uppercase
object TransferAction extends Enum[TransferAction] {
  val values = findValues
  case object In extends TransferAction
  case object Out extends TransferAction
}

sealed abstract class RelatedOptionTransactionType extends EnumEntry with Uppercase
object RelatedOptionTransactionType extends Enum[RelatedOptionTransactionType] {
  val values = findValues
  case object Spread extends RelatedOptionTransactionType
  case object Straddle extends RelatedOptionTransactionType
  case object None extends RelatedOptionTransactionType
  case object Other extends RelatedOptionTransactionType
}

sealed abstract class SecuredType extends EnumEntry with Uppercase
object SecuredType extends Enum[SecuredType] {
  val values = findValues
  case object Naked extends SecuredType
  case object Covered extends SecuredType
}

sealed abstract class SellReason extends EnumEntry with Uppercase
object SellReason extends Enum[SellReason] {
  val values = findValues
  case object Call extends SellReason
  case object Sell extends SellReason
  case object Maturity extends SellReason
}

sealed abstract class SellType extends EnumEntry with Uppercase
object SellType extends Enum[SellType] {
  val values = findValues
  case object Sell extends SellType
  case object SellShort extends SellType
}

// ================================== Categorization ==================================
sealed abstract class CategorizationSource extends EnumEntry with Uppercase
object CategorizationSource extends Enum[CategorizationSource] {
  val values = findValues
  case object Aggr extends CategorizationSource
  case object OFX extends CategorizationSource
  case object Cat extends CategorizationSource
}

case class RawCategorization(
  common: RawCategorizationCommon,
  context: Vector[RawCategorizationContext]
)

case class RawCategorizationCommon(
  normalizedPayeeName: Option[String],
  merchant: Option[String],
  sic: Option[Int]
)

case class RawCategorizationContext(
  source: Option[CategorizationSource],
  categoryName: Option[String],
  contextType: Option[String],
  scheduleC: Option[String]
)

case class CategorizationContext(raw: RawCategorizationContext) {
  def category: Option[String] = raw.categoryName
  def scheduleC: Option[String] = raw.scheduleC

  def source: Option[CategorizationSource] = raw.source
  def contextType: Option[String] = raw.contextType
}

case class Categorization(raw: RawCategorization) {
  def payee: Option[String] = raw.common.normalizedPayeeName
  def merchant: Option[String] = raw.common.merchant
  def sic: Option[String] = raw.common.sic map (_.toString)

  def contexts: Vector[CategorizationContext] = raw.context map CategorizationContext
}

// ================================== Transactions ==================================
sealed trait RawTransaction {
  val id: TransactionId
  val currencyType: Option[CurrencyUnit]
  val institutionTransactionId: Option[String]
  val correctInstitutionTransactionId: Option[String]
  val correctAction: Option[CorrectionAction]
  val serverTransactionId: Option[String]
  val checkNumber: Option[String]
  val refNumber: Option[String]
  val confirmationNumber: Option[String]
  val payeeId: Option[String]
  val payeeName: Option[String]
  val extendedPayeeName: Option[String]
  val memo: Option[String]
  val `type`: Option[String]
  val valueType: Option[String]
  val currencyRate: Option[BigDecimal]
  val currencyOriginal: Option[Boolean]
  val postedDate: Option[DateTime]
  val userDate: Option[DateTime]
  val availableDate: Option[DateTime]
  val amount: Option[BigDecimal]
  val runningBalanceAmount: Option[BigDecimal]
  val pending: Option[Boolean]
  val categorization: RawCategorization
}

sealed trait Transaction {
  val raw: RawTransaction

  private[data] def toMoney(amount: Option[BigDecimal]): Option[BigMoney] =
    (raw.currencyType |@| amount)(BigMoney.of)

  def id: TransactionId = raw.id
  def idInstitution: Option[String] = raw.institutionTransactionId
  def idServer: Option[String] = raw.serverTransactionId

  def currency: Option[CurrencyUnit] = raw.currencyType
  def currencyRate: Option[BigDecimal] = raw.currencyRate
  def currencyConverted: Option[Boolean] = raw.currencyOriginal

  def amount: Option[BigMoney] = toMoney(raw.amount)
  def amountAbsolute: Option[BigMoney] = toMoney(raw.amount map (_.abs))
  def pending: Option[Boolean] = raw.pending
  def `type`: Option[String] = raw.`type`

  def memo: Option[String] = raw.memo
  def categorization: Categorization = Categorization(raw.categorization)
  def payeeId: Option[String] = raw.payeeId
  def payeeName: Option[String] = raw.payeeName
  def payeeNameExtended: Option[String] = raw.extendedPayeeName
{'fraction_non_alphanumeric': 0.08121358943300455, 'fraction_numerical': 0.0043836880659860415, 'mean_word_length': 5.915835660151576, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7144806', 'n_tokens_mistral': 4551, 'n_tokens_neox': 4432, 'n_words': 1578}