2022-04-09 12:45:05 -04:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
2022-04-10 12:13:03 -04:00
|
|
|
"strings"
|
2022-04-09 12:45:05 -04:00
|
|
|
|
|
|
|
"github.com/samber/lo"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
|
|
|
|
"github.com/ananthakumaran/paisa/internal/model/posting"
|
|
|
|
"github.com/ananthakumaran/paisa/internal/service"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
)
|
|
|
|
|
2022-04-10 12:13:03 -04:00
|
|
|
type Breakdown struct {
|
2022-04-22 08:37:38 -04:00
|
|
|
Group string `json:"group"`
|
|
|
|
InvestmentAmount float64 `json:"investment_amount"`
|
|
|
|
WithdrawalAmount float64 `json:"withdrawal_amount"`
|
|
|
|
MarketAmount float64 `json:"market_amount"`
|
|
|
|
XIRR float64 `json:"xirr"`
|
2022-04-10 12:13:03 -04:00
|
|
|
}
|
|
|
|
|
2022-04-09 12:45:05 -04:00
|
|
|
func GetLedger(db *gorm.DB) gin.H {
|
|
|
|
var postings []posting.Posting
|
|
|
|
result := db.Order("date DESC").Find(&postings)
|
|
|
|
if result.Error != nil {
|
|
|
|
log.Fatal(result.Error)
|
|
|
|
}
|
|
|
|
|
2022-04-23 23:47:39 -04:00
|
|
|
postings = service.PopulateMarketPrice(db, postings)
|
2022-04-19 04:02:05 -04:00
|
|
|
breakdowns := computeBreakdown(db, lo.Filter(postings, func(p posting.Posting, _ int) bool { return strings.HasPrefix(p.Account, "Asset:") }))
|
2022-04-10 12:13:03 -04:00
|
|
|
return gin.H{"postings": postings, "breakdowns": breakdowns}
|
|
|
|
}
|
|
|
|
|
2022-04-19 04:02:05 -04:00
|
|
|
func computeBreakdown(db *gorm.DB, postings []posting.Posting) map[string]Breakdown {
|
2022-04-14 03:17:42 -04:00
|
|
|
accounts := make(map[string]bool)
|
|
|
|
for _, p := range postings {
|
|
|
|
var parts []string
|
|
|
|
for _, part := range strings.Split(p.Account, ":") {
|
|
|
|
parts = append(parts, part)
|
|
|
|
accounts[strings.Join(parts, ":")] = true
|
2022-04-10 12:13:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-04-14 03:17:42 -04:00
|
|
|
result := make(map[string]Breakdown)
|
|
|
|
|
|
|
|
for group := range accounts {
|
|
|
|
ps := lo.Filter(postings, func(p posting.Posting, _ int) bool { return strings.HasPrefix(p.Account, group) })
|
2022-04-22 08:37:38 -04:00
|
|
|
investmentAmount := lo.Reduce(ps, func(acc float64, p posting.Posting, _ int) float64 {
|
|
|
|
if p.Amount < 0 || service.IsInterest(db, p) {
|
2022-04-19 04:02:05 -04:00
|
|
|
return acc
|
|
|
|
} else {
|
|
|
|
return acc + p.Amount
|
|
|
|
}
|
|
|
|
}, 0.0)
|
2022-04-22 08:37:38 -04:00
|
|
|
withdrawalAmount := lo.Reduce(ps, func(acc float64, p posting.Posting, _ int) float64 {
|
|
|
|
if p.Amount > 0 || service.IsInterest(db, p) {
|
|
|
|
return acc
|
|
|
|
} else {
|
|
|
|
return acc + -p.Amount
|
|
|
|
}
|
|
|
|
}, 0.0)
|
2022-04-10 12:13:03 -04:00
|
|
|
marketAmount := lo.Reduce(ps, func(acc float64, p posting.Posting, _ int) float64 { return acc + p.MarketAmount }, 0.0)
|
2022-04-19 04:02:05 -04:00
|
|
|
|
2022-04-23 23:47:39 -04:00
|
|
|
xirr := service.XIRR(db, ps)
|
|
|
|
breakdown := Breakdown{InvestmentAmount: investmentAmount, WithdrawalAmount: withdrawalAmount, MarketAmount: marketAmount, XIRR: xirr, Group: group}
|
2022-04-14 03:17:42 -04:00
|
|
|
result[group] = breakdown
|
2022-04-10 12:13:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return result
|
2022-04-09 12:45:05 -04:00
|
|
|
}
|