Skip to content
This repository has been archived by the owner on Oct 26, 2021. It is now read-only.

Commit

Permalink
Add native currency to account cells #36
Browse files Browse the repository at this point in the history
  • Loading branch information
einsteinx2 committed Jun 16, 2017
1 parent f350932 commit 53e35b3
Show file tree
Hide file tree
Showing 11 changed files with 207 additions and 9 deletions.
6 changes: 6 additions & 0 deletions BalanceOpen.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
2D8D54481EEB12360060FCCF /* BalanceOpenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D8D54471EEB12360060FCCF /* BalanceOpenTests.swift */; };
2DA7FAB91EF2637700CD8CED /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DA7FAB81EF2637700CD8CED /* Sparkle.framework */; };
2DC8663A1EF2654A00502A98 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2DA7FAB81EF2637700CD8CED /* Sparkle.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
530DD1891EF458A400C0DDD3 /* FMDatabasePoolAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 530DD1881EF458A400C0DDD3 /* FMDatabasePoolAdditions.m */; };
532121B61EEAC2BF00F4812A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532121B51EEAC2BF00F4812A /* AppDelegate.swift */; };
532121C61EEAC47300F4812A /* Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532121C51EEAC47300F4812A /* Database.swift */; };
532121DB1EEAC4DC00F4812A /* FMDatabase.m in Sources */ = {isa = PBXBuildFile; fileRef = 532121CE1EEAC4DC00F4812A /* FMDatabase.m */; };
Expand Down Expand Up @@ -203,6 +204,8 @@
2D8D54471EEB12360060FCCF /* BalanceOpenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BalanceOpenTests.swift; sourceTree = "<group>"; };
2D8D54491EEB12360060FCCF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
2DA7FAB81EF2637700CD8CED /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = "<group>"; };
530DD1871EF458A400C0DDD3 /* FMDatabasePoolAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FMDatabasePoolAdditions.h; sourceTree = "<group>"; };
530DD1881EF458A400C0DDD3 /* FMDatabasePoolAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FMDatabasePoolAdditions.m; sourceTree = "<group>"; };
532121B21EEAC2BF00F4812A /* BalanceOpen.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BalanceOpen.app; sourceTree = BUILT_PRODUCTS_DIR; };
532121B51EEAC2BF00F4812A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
532121BE1EEAC2BF00F4812A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -505,6 +508,8 @@
532121D01EEAC4DC00F4812A /* FMDatabaseAdditions.m */,
532121D11EEAC4DC00F4812A /* FMDatabasePool.h */,
532121D21EEAC4DC00F4812A /* FMDatabasePool.m */,
530DD1871EF458A400C0DDD3 /* FMDatabasePoolAdditions.h */,
530DD1881EF458A400C0DDD3 /* FMDatabasePoolAdditions.m */,
532121D31EEAC4DC00F4812A /* FMDatabaseQueue.h */,
532121D41EEAC4DC00F4812A /* FMDatabaseQueue.m */,
532121D61EEAC4DC00F4812A /* FMResultSet.h */,
Expand Down Expand Up @@ -869,6 +874,7 @@
53FA53041EF3FAFE002990B0 /* InstitutionDefaultBar.swift in Sources */,
532122091EEAC89B00F4812A /* CCNStatusItem.m in Sources */,
532121DE1EEAC4DC00F4812A /* FMDatabaseQueue.m in Sources */,
530DD1891EF458A400C0DDD3 /* FMDatabasePoolAdditions.m in Sources */,
532122B11EEAE85500F4812A /* AccountConnectionErrors.swift in Sources */,
532122481EEAD32B00F4812A /* Theme.swift in Sources */,
532122441EEAD2B700F4812A /* AccountsTabViewController.swift in Sources */,
Expand Down
11 changes: 10 additions & 1 deletion BalanceOpen/Data Model/API Models/CoinbaseApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -215,13 +215,22 @@ struct CoinbaseApi {
decimals = currency.decimals
}

var altDecimals = 2
if let altCurrency = Currency(rawValue: ca.nativeCurrency) {
altDecimals = altCurrency.decimals
}

// Calculate the integer value of the balance based on the decimals
var balance = ca.balance
balance.multiply(by: Decimal(pow(10.0, Double(decimals))))
let currentBalance = (balance as NSDecimalNumber).intValue

var altBalance = ca.nativeBalance
altBalance.multiply(by: Decimal(pow(10.0, Double(altDecimals))))
let altCurrentBalance = (altBalance as NSDecimalNumber).intValue

// Initialize an Account object to insert the record
_ = Account(institutionId: institution.institutionId, sourceId: institution.sourceId, sourceAccountId: ca.id, sourceInstitutionId: "", accountTypeId: AccountType.depository, accountSubTypeId: nil, name: ca.name, currency: ca.currency, decimals: decimals, currentBalance: currentBalance, availableBalance: nil, number: nil)
_ = Account(institutionId: institution.institutionId, sourceId: institution.sourceId, sourceAccountId: ca.id, sourceInstitutionId: "", accountTypeId: AccountType.depository, accountSubTypeId: nil, name: ca.name, currency: ca.currency, decimals: decimals, currentBalance: currentBalance, availableBalance: nil, number: nil, altCurrency: ca.nativeCurrency, altDecimals: altDecimals, altCurrentBalance: altCurrentBalance, altAvailableBalance: nil)
}

// Remove accounts that no longer exist
Expand Down
36 changes: 30 additions & 6 deletions BalanceOpen/Data Model/Local Models/Account.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@ private func arrayFromResult(_ result: FMResultSet) -> [AnyObject] {
array.append(result.string(forColumnIndex: 7) as AnyObject) // name

array.append(result.string(forColumnIndex: 8) as AnyObject) // currency
array.append(result.long(forColumnIndex: 9) as AnyObject) // decimals
array.append(result.long(forColumnIndex: 9) as AnyObject) // decimals
array.append(result.long(forColumnIndex: 10) as AnyObject) // currentBalance
array.append(n2N(result.object(forColumnIndex: 11) as? Int)) // availableBalance

array.append(n2N(result.object(forColumnIndex: 12) as? String)) // number

array.append(n2N(result.object(forColumnIndex: 13) as? String)) // altCurrency
array.append(n2N(result.object(forColumnIndex: 14) as? Int)) // altDecimals
array.append(n2N(result.object(forColumnIndex: 15) as? Int)) // altCurrentBalance
array.append(n2N(result.object(forColumnIndex: 16) as? Int)) // altAvailableBalance

return array
}

Expand All @@ -55,6 +60,11 @@ class Account: Equatable {
// Last 4 digits of credit card number, if applicable, using String as Plaid uses that format in JSON
var number: String?

var altCurrency: String?
var altDecimals: Int?
var altCurrentBalance: Int?
var altAvailableBalance: Int?

var isCreditAccount: Bool {
// Assume a balance is positive.
// If there is a bug, it is better for them not to suffer the heart attack of positive balances displaying as negative.
Expand Down Expand Up @@ -177,9 +187,14 @@ class Account: Equatable {
self.availableBalance = resultArray[11] as? Int

self.number = resultArray[12] as? String

self.altCurrency = resultArray[13] as? String
self.altDecimals = resultArray[14] as? Int
self.altCurrentBalance = resultArray[15] as? Int
self.altAvailableBalance = resultArray[16] as? Int
}

init?(institutionId: Int, sourceId: Source, sourceAccountId: String, sourceInstitutionId: String, accountTypeId: AccountType, accountSubTypeId: AccountType?, name: String, currency: String, decimals: Int, currentBalance: Int, availableBalance: Int?, number: String?) {
init?(institutionId: Int, sourceId: Source, sourceAccountId: String, sourceInstitutionId: String, accountTypeId: AccountType, accountSubTypeId: AccountType?, name: String, currency: String, decimals: Int, currentBalance: Int, availableBalance: Int?, number: String?, altCurrency: String? = nil, altDecimals: Int? = nil, altCurrentBalance: Int? = nil, altAvailableBalance: Int? = nil) {

self.institutionId = institutionId
self.sourceId = sourceId
Expand All @@ -197,6 +212,11 @@ class Account: Equatable {

self.number = number

self.altCurrency = altCurrency
self.altDecimals = altDecimals
self.altCurrentBalance = altCurrentBalance
self.altAvailableBalance = altAvailableBalance

// First check if a record for this account already exists
var accountIdFromDb: Int?
database.readDbPool.inDatabase { db in
Expand All @@ -215,8 +235,8 @@ class Account: Equatable {
var generatedId: Int?
database.writeDbQueue.inDatabase { db in
do {
let insert = "INSERT INTO accounts VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
try db.executeUpdate(insert, NSNull(), institutionId, sourceId.rawValue, sourceAccountId, sourceInstitutionId, accountTypeId.rawValue, n2N(accountSubTypeId?.rawValue), name, currency, decimals, currentBalance, n2N(availableBalance), n2N(number))
let insert = "INSERT INTO accounts VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
try db.executeUpdate(insert, NSNull(), institutionId, sourceId.rawValue, sourceAccountId, sourceInstitutionId, accountTypeId.rawValue, n2N(accountSubTypeId?.rawValue), name, currency, decimals, currentBalance, n2N(availableBalance), n2N(number), n2N(altCurrency), n2N(altDecimals), n2N(altCurrentBalance), n2N(altAvailableBalance))

generatedId = Int(db.lastInsertRowId())
} catch {
Expand All @@ -239,7 +259,7 @@ class Account: Equatable {
func updateModel() {
database.writeDbQueue.inDatabase { db in
do {
let insert = "INSERT OR REPLACE INTO accounts VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
let insert = "INSERT OR REPLACE INTO accounts VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"

// Hack for compile time speed
let accountId: Any = self.accountId
Expand All @@ -255,8 +275,12 @@ class Account: Equatable {
let currentBalance: Any = self.currentBalance
let availableBalance: Any = n2N(self.availableBalance)
let number: Any = n2N(self.number)
let altCurrency: Any = n2N(self.altCurrency)
let altDecimals: Any = n2N(self.altDecimals)
let altCurrentBalance: Any = n2N(self.altCurrentBalance)
let altAvailableBalance: Any = n2N(self.altAvailableBalance)

try db.executeUpdate(insert, accountId, institutionId, sourceId, sourceAccountId, sourceInstitutionId, accountType, accountSubType, name, currency, decimals, currentBalance, availableBalance, number)
try db.executeUpdate(insert, accountId, institutionId, sourceId, sourceAccountId, sourceInstitutionId, accountType, accountSubType, name, currency, decimals, currentBalance, availableBalance, number, altCurrency, altDecimals, altCurrentBalance, altAvailableBalance)
} catch {
log.severe("DB Error: " + db.lastErrorMessage())
}
Expand Down
6 changes: 6 additions & 0 deletions BalanceOpen/Data Model/Static & Singletons/Database.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ class Database {
"(accountId INTEGER PRIMARY KEY AUTOINCREMENT, institutionId INTEGER, sourceId INTEGER, " +
"sourceAccountId TEXT, sourceInstitutionId TEXT, accountTypeId INTEGER, accountSubTypeId INTEGER, " +
"name TEXT, currency TEXT, decimals INTEGER, currentBalance INTEGER, availableBalance INTEGER, number TEXT)")
if !db.columnExists("altCurrency", inTableWithName: "accounts") {
statements.append("ALTER TABLE accounts ADD COLUMN altCurrency TEXT")
statements.append("ALTER TABLE accounts ADD COLUMN altDecimals INTEGER")
statements.append("ALTER TABLE accounts ADD COLUMN altCurrentBalance INTEGER")
statements.append("ALTER TABLE accounts ADD COLUMN altAvailableBalance INTEGER")
}

for statement in statements {
if !db.executeUpdate(statement, withArgumentsIn: nil) {
Expand Down
24 changes: 24 additions & 0 deletions BalanceOpen/Frameworks/fmdb/FMDatabasePoolAdditions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// FMDatabasePoolAdditions.h
// iSub
//
// Created by Benjamin Baron on 3/9/16.
// Copyright (c) 2016 Ben Baron. All rights reserved.
//

#import "FMDB.h"

@interface FMDatabasePool (Additions)

- (int)intForQuery:(NSString*)query, ...;
- (long)longForQuery:(NSString*)query, ...;
- (BOOL)boolForQuery:(NSString*)query, ...;
- (double)doubleForQuery:(NSString*)query, ...;
- (NSString*)stringForQuery:(NSString*)query, ...;
- (NSData*)dataForQuery:(NSString*)query, ...;
- (NSDate*)dateForQuery:(NSString*)query, ...;

- (BOOL)tableExists:(NSString*)tableName;
- (BOOL)columnExists:(NSString*)columnName inTableWithName:(NSString*)tableName;

@end
87 changes: 87 additions & 0 deletions BalanceOpen/Frameworks/fmdb/FMDatabasePoolAdditions.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//
// FMDatabasePoolAdditions.m
// iSub
//
// Created by Benjamin Baron on 3/9/16.
// Copyright (c) 2016 Ben Baron. All rights reserved.
//

#import "FMDatabasePoolAdditions.h"
#import "FMDatabase.h"
#import "FMDatabaseAdditions.h"

@interface FMDatabase (PrivateStuff)
- (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arrayArgs orDictionary:(NSDictionary *)dictionaryArgs orVAList:(va_list)args;
@end

@implementation FMDatabasePool (Additions)

#define RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(type, sel) \
va_list args; \
va_start(args, query); \
__block va_list *args_ptr = &args; \
__block type ret; \
[self inDatabase:^(FMDatabase *db) { \
FMResultSet *resultSet = [db executeQuery:query withArgumentsInArray:nil orDictionary:nil orVAList:*args_ptr]; \
ret = [resultSet next] ? [resultSet sel:0] : (type)0; \
[resultSet close]; \
[resultSet setParentDB:nil]; \
}]; \
va_end(args); \
return ret;

- (NSString*)stringForQuery:(NSString*)query, ...
{
RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSString *, stringForColumnIndex);
}

- (int)intForQuery:(NSString*)query, ...
{
RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(int, intForColumnIndex);
}

- (long)longForQuery:(NSString*)query, ...
{
RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(long, longForColumnIndex);
}

- (BOOL)boolForQuery:(NSString*)query, ...
{
RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(BOOL, boolForColumnIndex);
}

- (double)doubleForQuery:(NSString*)query, ...
{
RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(double, doubleForColumnIndex);
}

- (NSData*)dataForQuery:(NSString*)query, ...
{
RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSData *, dataForColumnIndex);
}

- (NSDate*)dateForQuery:(NSString*)query, ...
{
RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSDate *, dateForColumnIndex);
}

- (BOOL)tableExists:(NSString*)tableName
{
__block BOOL exists;
[self inDatabase:^(FMDatabase *db) {
exists = [db tableExists:tableName];
}];
return exists;
}

- (BOOL)columnExists:(NSString*)columnName inTableWithName:(NSString*)tableName
{
__block BOOL exists;
[self inDatabase:^(FMDatabase *db) {
exists = [db columnExists:columnName inTableWithName:tableName];
}];
return exists;
}

@end

2 changes: 1 addition & 1 deletion BalanceOpen/Supporting Files/Bridging-Header.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//

#import <Sparkle/Sparkle.h>
#import "FMDB.h"
#import "FMDatabasePoolAdditions.h"
#import "CCNStatusItem.h"
#import "CertValidator.h"
#import "ObjC.h"
35 changes: 34 additions & 1 deletion BalanceOpen/UI/AccountsTabTableCells.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class AccountsTabAccountCell: View {
let nameField = LabelField()
let inclusionIndicator = ImageView()
let amountField = LabelField()
let altAmountField = LabelField()

static var dateFormatter = DateFormatter()

Expand All @@ -59,7 +60,18 @@ class AccountsTabAccountCell: View {
amountField.snp.makeConstraints { make in
make.width.equalTo(100)
make.trailing.equalToSuperview().inset(12)
make.centerY.equalToSuperview()
make.top.equalToSuperview().offset(8)
}

altAmountField.backgroundColor = CurrentTheme.defaults.cell.backgroundColor
altAmountField.font = CurrentTheme.accounts.cell.altAmountFont
altAmountField.textColor = CurrentTheme.accounts.cell.altAmountColor
altAmountField.usesSingleLineMode = true
self.addSubview(altAmountField)
altAmountField.snp.makeConstraints { make in
make.width.equalTo(100)
make.trailing.equalToSuperview().inset(8)
make.bottom.equalToSuperview().offset(-8)
}

nameField.backgroundColor = CurrentTheme.defaults.cell.backgroundColor
Expand Down Expand Up @@ -92,6 +104,27 @@ class AccountsTabAccountCell: View {
}
}

if updatedModel.altCurrency != nil && updatedModel.currency != updatedModel.altCurrency {
if let altCurrency = Currency(rawValue: updatedModel.altCurrency!), let altCurrentBalance = updatedModel.altCurrentBalance {
altAmountField.stringValue = amountToString(amount: altCurrentBalance, currency: altCurrency, showNegative: true)
altAmountField.setAccessibilityLabel("Account Total")
altAmountField.snp.updateConstraints { make in
let width = altAmountField.stringValue.size(font: CurrentTheme.accounts.cell.amountFont)
make.width.equalTo(width)
}
}

altAmountField.isHidden = false
amountField.snp.updateConstraints { make in
make.top.equalToSuperview().offset(8)
}
} else {
altAmountField.isHidden = true
amountField.snp.updateConstraints { make in
make.top.equalToSuperview().offset(20)
}
}

nameField.stringValue = updatedModel.displayName
nameField.setAccessibilityLabel("Account Name")

Expand Down
3 changes: 3 additions & 0 deletions BalanceOpen/UI/DarkTheme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ struct DarkTheme: Theme {
amountColorCents: NSColor(deviceRedInt: 153, green: 165, blue: 174),
amountColorPositive: NSColor(deviceRedInt: 88, green: 184, blue: 33),

altAmountFont: NSFont.monospacedDigitSystemFont(ofSize: 12),
altAmountColor: NSColor(deviceRedInt: 153, green: 165, blue: 174),

availableFont: NSFont.systemFont(ofSize: 10.5),
availableColor: NSColor(deviceRedInt: 148, green: 158, blue: 168)
)
Expand Down
3 changes: 3 additions & 0 deletions BalanceOpen/UI/LightTheme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ struct LightTheme: Theme {
amountColorCents: NSColor(deviceRedInt: 19, green: 22, blue: 25, alpha: 0.64),
amountColorPositive: NSColor(deviceRedInt: 33, green: 143, blue: 0),

altAmountFont: NSFont.monospacedDigitSystemFont(ofSize: 12),
altAmountColor: NSColor(deviceRedInt: 19, green: 22, blue: 25, alpha: 0.64),

availableFont: NSFont.systemFont(ofSize: 10.5),
availableColor: NSColor(deviceRedInt: 114, green: 117, blue: 121)
)
Expand Down
3 changes: 3 additions & 0 deletions BalanceOpen/UI/Theme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ struct AccountsTheme {
let amountColorCents: NSColor
let amountColorPositive: NSColor

let altAmountFont: NSFont
let altAmountColor: NSColor

let availableFont: NSFont
let availableColor: NSColor
}
Expand Down

0 comments on commit 53e35b3

Please sign in to comment.