support exporting timezone and account currency
This commit is contained in:
@@ -14,8 +14,8 @@ type EzBookKeepingCSVFileExporter struct {
|
|||||||
DataConverter
|
DataConverter
|
||||||
}
|
}
|
||||||
|
|
||||||
const csvHeaderLine = "Time,Type,Category,Sub Category,Account,Amount,Account2,Account2 Amount,Tags,Comment\n"
|
const csvHeaderLine = "Time,Timezone,Type,Category,Sub Category,Account,Account Currency,Amount,Account2,Account2 Currency,Account2 Amount,Tags,Comment\n"
|
||||||
const csvDataLineFormat = "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n"
|
const csvDataLineFormat = "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n"
|
||||||
|
|
||||||
// ToExportedContent returns the exported csv data
|
// ToExportedContent returns the exported csv data
|
||||||
func (e *EzBookKeepingCSVFileExporter) ToExportedContent(uid int64, timezone *time.Location, transactions []*models.Transaction, accountMap map[int64]*models.Account, categoryMap map[int64]*models.TransactionCategory, tagMap map[int64]*models.TransactionTag, allTagIndexs map[int64][]int64) ([]byte, error) {
|
func (e *EzBookKeepingCSVFileExporter) ToExportedContent(uid int64, timezone *time.Location, transactions []*models.Transaction, accountMap map[int64]*models.Account, categoryMap map[int64]*models.TransactionCategory, tagMap map[int64]*models.TransactionTag, allTagIndexs map[int64][]int64) ([]byte, error) {
|
||||||
@@ -33,23 +33,27 @@ func (e *EzBookKeepingCSVFileExporter) ToExportedContent(uid int64, timezone *ti
|
|||||||
|
|
||||||
transactionTimeZone := time.FixedZone("Transaction Timezone", int(transaction.TimezoneUtcOffset)*60)
|
transactionTimeZone := time.FixedZone("Transaction Timezone", int(transaction.TimezoneUtcOffset)*60)
|
||||||
transactionTime := utils.FormatUnixTimeToLongDateTimeWithoutSecond(utils.GetUnixTimeFromTransactionTime(transaction.TransactionTime), transactionTimeZone)
|
transactionTime := utils.FormatUnixTimeToLongDateTimeWithoutSecond(utils.GetUnixTimeFromTransactionTime(transaction.TransactionTime), transactionTimeZone)
|
||||||
|
transactionTimezone := utils.FormatTimezoneOffset(transactionTimeZone)
|
||||||
transactionType := e.getTransactionTypeName(transaction.Type)
|
transactionType := e.getTransactionTypeName(transaction.Type)
|
||||||
category := e.getTransactionCategoryName(transaction.CategoryId, categoryMap)
|
category := e.getTransactionCategoryName(transaction.CategoryId, categoryMap)
|
||||||
subCategory := e.getTransactionSubCategoryName(transaction.CategoryId, categoryMap)
|
subCategory := e.getTransactionSubCategoryName(transaction.CategoryId, categoryMap)
|
||||||
account := e.getAccountName(transaction.AccountId, accountMap)
|
account := e.getAccountName(transaction.AccountId, accountMap)
|
||||||
|
accountCurrency := e.getAccountCurrency(transaction.AccountId, accountMap)
|
||||||
amount := e.getDisplayAmount(transaction.Amount)
|
amount := e.getDisplayAmount(transaction.Amount)
|
||||||
account2 := ""
|
account2 := ""
|
||||||
|
account2Currency := ""
|
||||||
account2Amount := ""
|
account2Amount := ""
|
||||||
|
|
||||||
if transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT {
|
if transaction.Type == models.TRANSACTION_DB_TYPE_TRANSFER_OUT {
|
||||||
account2 = e.getAccountName(transaction.RelatedAccountId, accountMap)
|
account2 = e.getAccountName(transaction.RelatedAccountId, accountMap)
|
||||||
|
account2Currency = e.getAccountCurrency(transaction.RelatedAccountId, accountMap)
|
||||||
account2Amount = e.getDisplayAmount(transaction.RelatedAccountAmount)
|
account2Amount = e.getDisplayAmount(transaction.RelatedAccountAmount)
|
||||||
}
|
}
|
||||||
|
|
||||||
tags := e.getTags(transaction.TransactionId, allTagIndexs, tagMap)
|
tags := e.getTags(transaction.TransactionId, allTagIndexs, tagMap)
|
||||||
comment := e.getComment(transaction.Comment)
|
comment := e.getComment(transaction.Comment)
|
||||||
|
|
||||||
ret.WriteString(fmt.Sprintf(csvDataLineFormat, transactionTime, transactionType, category, subCategory, account, amount, account2, account2Amount, tags, comment))
|
ret.WriteString(fmt.Sprintf(csvDataLineFormat, transactionTime, transactionTimezone, transactionType, category, subCategory, account, accountCurrency, amount, account2, account2Currency, account2Amount, tags, comment))
|
||||||
}
|
}
|
||||||
|
|
||||||
return []byte(ret.String()), nil
|
return []byte(ret.String()), nil
|
||||||
@@ -109,6 +113,16 @@ func (e *EzBookKeepingCSVFileExporter) getAccountName(accountId int64, accountMa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *EzBookKeepingCSVFileExporter) getAccountCurrency(accountId int64, accountMap map[int64]*models.Account) string {
|
||||||
|
account, exists := accountMap[accountId]
|
||||||
|
|
||||||
|
if exists {
|
||||||
|
return account.Currency
|
||||||
|
} else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (e *EzBookKeepingCSVFileExporter) getDisplayAmount(amount int64) string {
|
func (e *EzBookKeepingCSVFileExporter) getDisplayAmount(amount int64) string {
|
||||||
displayAmount := utils.Int64ToString(amount)
|
displayAmount := utils.Int64ToString(amount)
|
||||||
integer := utils.SubString(displayAmount, 0, len(displayAmount)-2)
|
integer := utils.SubString(displayAmount, 0, len(displayAmount)-2)
|
||||||
|
|||||||
+22
-1
@@ -1,6 +1,9 @@
|
|||||||
package utils
|
package utils
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
longDateTimeFormat = "2006-01-02 15:04:05"
|
longDateTimeFormat = "2006-01-02 15:04:05"
|
||||||
@@ -53,6 +56,24 @@ func ParseFromShortDateTime(t string, utcOffset int16) (time.Time, error) {
|
|||||||
return time.ParseInLocation(shortDateTimeFormat, t, timezone)
|
return time.ParseInLocation(shortDateTimeFormat, t, timezone)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FormatTimezoneOffset returns "+/-HH:MM" format of timezone
|
||||||
|
func FormatTimezoneOffset(timezone *time.Location) string {
|
||||||
|
_, tzOffset := time.Now().In(timezone).Zone()
|
||||||
|
tzMinutesOffset := tzOffset / 60
|
||||||
|
|
||||||
|
sign := "+"
|
||||||
|
hourAbsOffset := tzMinutesOffset / 60
|
||||||
|
minuteAbsOffset := tzMinutesOffset % 60
|
||||||
|
|
||||||
|
if hourAbsOffset < 0 {
|
||||||
|
sign = "-"
|
||||||
|
hourAbsOffset = -hourAbsOffset
|
||||||
|
minuteAbsOffset = -minuteAbsOffset
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s%02d:%02d", sign, hourAbsOffset, minuteAbsOffset)
|
||||||
|
}
|
||||||
|
|
||||||
// GetMinTransactionTimeFromUnixTime returns the minimum transaction time from unix time
|
// GetMinTransactionTimeFromUnixTime returns the minimum transaction time from unix time
|
||||||
func GetMinTransactionTimeFromUnixTime(unixTime int64) int64 {
|
func GetMinTransactionTimeFromUnixTime(unixTime int64) int64 {
|
||||||
return unixTime * 1000
|
return unixTime * 1000
|
||||||
|
|||||||
@@ -60,6 +60,28 @@ func TestParseFromShortDateTime(t *testing.T) {
|
|||||||
assert.Equal(t, expectedValue, actualValue)
|
assert.Equal(t, expectedValue, actualValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFormatTimezoneOffset(t *testing.T) {
|
||||||
|
timezone := time.FixedZone("Test Timezone", 120*60)
|
||||||
|
expectedValue := "+02:00"
|
||||||
|
actualValue := FormatTimezoneOffset(timezone)
|
||||||
|
assert.Equal(t, expectedValue, actualValue)
|
||||||
|
|
||||||
|
timezone = time.FixedZone("Test Timezone", 345*60)
|
||||||
|
expectedValue = "+05:45"
|
||||||
|
actualValue = FormatTimezoneOffset(timezone)
|
||||||
|
assert.Equal(t, expectedValue, actualValue)
|
||||||
|
|
||||||
|
timezone = time.FixedZone("Test Timezone", -720*60)
|
||||||
|
expectedValue = "-12:00"
|
||||||
|
actualValue = FormatTimezoneOffset(timezone)
|
||||||
|
assert.Equal(t, expectedValue, actualValue)
|
||||||
|
|
||||||
|
timezone = time.FixedZone("Test Timezone", 0)
|
||||||
|
expectedValue = "+00:00"
|
||||||
|
actualValue = FormatTimezoneOffset(timezone)
|
||||||
|
assert.Equal(t, expectedValue, actualValue)
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetMinTransactionTimeFromUnixTime(t *testing.T) {
|
func TestGetMinTransactionTimeFromUnixTime(t *testing.T) {
|
||||||
expectedValue := int64(1617228083000)
|
expectedValue := int64(1617228083000)
|
||||||
actualValue := GetMinTransactionTimeFromUnixTime(1617228083)
|
actualValue := GetMinTransactionTimeFromUnixTime(1617228083)
|
||||||
|
|||||||
Reference in New Issue
Block a user