fzaker
2/11/2013 - 10:57 AM

Using RapidGrails ReportService

Using RapidGrails ReportService

package fundmanagement

import fundmanagement.reports.PortfolioPerformance
import fundmanagement.transactions.PortfolioTransaction

class PortfolioPerformanceService {
    def symbolSynchronizationService

    def report(params) {
        def map = [:]
        def id = 1
        
        def client
        if(params.client)
            client = Client.findById(params.client.id)
        else
            client = Client.findById(params.clientId)

        def portfolioTransactions = PortfolioTransaction.findAllByClient(client)

        if(params.fromDate_year)
        {
            def fromDate = Date.parse("yyyy/MM/dd", params.fromDate_year + "/" + params.fromDate_month + "/" + params.fromDate_day)
            portfolioTransactions = portfolioTransactions.findAll {item -> item.transactionDate >= fromDate}
        }

        if(params.toDate_year)
        {
            def toDate = Date.parse("yyyy/MM/dd", params.toDate_year + "/" + params.toDate_month + "/" + params.toDate_day)
            portfolioTransactions = portfolioTransactions.findAll {item -> item.transactionDate <= toDate}
        }

        portfolioTransactions.each {
            if (it.symbol.insCode != "999") {
                if (map[it.symbol]) {
                    def perf = map[it.symbol]
                    perf.costPerShare = (it.transactionType in ["buy", "init"]) ? (((perf.costPerShare * perf.buyCount) + (it.unitCount * it.unitPrice))/(perf.buyCount + it.unitCount)) : perf.costPerShare
                    perf.sellPrice = (it.transactionType == "sell") ? (((perf.sellPrice * perf.sellCount) + (it.unitCount * it.unitPrice))/(perf.sellCount + it.unitCount)) : perf.sellPrice
                    perf.buyCount += (it.transactionType in ["buy", "init"]) ? it.unitCount : 0
                    perf.sellCount += (it.transactionType == "sell") ? it.unitCount : 0
                } else {
                    def perf = new PortfolioPerformance()
                    perf.id = id++
                    perf.symbol = it.symbol.toString()
                    perf.buyCount = (it.transactionType in ["buy", "init"]) ? it.unitCount : 0
                    perf.sellCount = (it.transactionType == "sell") ? it.unitCount : 0
                    perf.costPerShare = (it.transactionType in ["buy", "init"]) ? it.unitPrice : 0
                    perf.sellPrice = (it.transactionType == "sell") ? it.unitPrice : 0
                    if (it.symbol.insCode == "999")
                        perf.currentSharePrice = 1
                    else {
                        perf.currentSharePrice = symbolSynchronizationService.getSymbolPrice(it.symbol)
                    }

                    map[it.symbol] = perf
                }
            }
        }

        def sumMarketValue = 0.0
        def sumTotalOpenCost = 0.0
        def sumTotalClosedCost = 0.0
        def sumClosedPositionsProfitLoss = 0.0
        def sumOpenPositionsProfitLoss = 0.0
        def sumTotalProfitLoss = 0.0

        map.values().each { PortfolioPerformance perf ->
            perf.remained = perf.buyCount - perf.sellCount
            perf.totalClosedCost = perf.sellCount * perf.costPerShare
            perf.totalOpenCost = perf.remained * perf.costPerShare
            perf.marketValue = perf.remained * perf.currentSharePrice
            perf.closedPositionsProfitLoss = perf.sellCount * (perf.sellPrice - perf.costPerShare)
            perf.openPositionsProfitLoss = perf.remained * (perf.currentSharePrice - perf.costPerShare)
            perf.totalProfitLoss = perf.closedPositionsProfitLoss + perf.openPositionsProfitLoss
            perf.performance = perf.totalProfitLoss / (perf.totalOpenCost + perf.totalClosedCost)

            sumMarketValue += perf.marketValue
            sumTotalOpenCost += perf.totalOpenCost
            sumTotalClosedCost += perf.totalClosedCost
            sumClosedPositionsProfitLoss += perf.closedPositionsProfitLoss
            sumOpenPositionsProfitLoss += perf.openPositionsProfitLoss
            sumTotalProfitLoss += perf.totalProfitLoss
        }

        def userdata = [:]
        //userdata.marketValue = "<div>${String.format("%.2f", sumMarketValue)}</div><div>2</div>"
        userdata.marketValue = "${String.format("%.2f", sumMarketValue)}"
        userdata.totalOpenCost = String.format("%.2f", sumTotalOpenCost)
        userdata.totalClosedCost = String.format("%.2f", sumTotalClosedCost)
        userdata.closedPositionsProfitLoss = String.format("%.2f", sumClosedPositionsProfitLoss)
        userdata.openPositionsProfitLoss = String.format("%.2f", sumOpenPositionsProfitLoss)
        userdata.totalProfitLoss = String.format("%.2f", sumTotalProfitLoss)
        userdata.symbol='جمع'

        [list: map.values(), userdata: userdata]
    }
}
package fundmanagement.reports

import ar.com.fdvs.dj.domain.DJCalculation
import rapidgrails.Field

class PortfolioPerformanceController {
    def reportService
    def portfolioPerformanceService
    def messageSource

    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

    def index() {
        redirect(action: "list", params: params)
    }

    def list() {}

    def grid() {}

    def chart() {
        def locale = new Locale("en")

        def list = portfolioPerformanceService.report(params).list
        def series = [
                [name: messageSource.getMessage("portfolioPerformance.closedPositionsProfitLoss", null, "Closed Positions Profit/Loss", locale), data: list.collect { it.closedPositionsProfitLoss }],
                [name: messageSource.getMessage("portfolioPerformance.openPositionsProfitLoss", null, "Open Positions Profit/Loss", locale), data: list.collect { it.openPositionsProfitLoss }],
                [name: messageSource.getMessage("portfolioPerformance.totalProfitLoss", null, "Total Profit/Loss", locale), data: list.collect { it.totalProfitLoss }]
        ]

        def xAxis = list.collect { it.symbol }
        def title = messageSource.getMessage("portfolioPerformance.profitLoss.chart", null, "Portfolio Performance", locale)
        [title: title, subtitle: "", xAxis: xAxis]
    }

    def pdf() {
        export("pdf")
    }

    def xls() {
        export("xls")
    }

    private def export(format) {
        def reportTitle = "Portfolio Performance"
        def subTitle = "smaller title goes here!"

        def fields = []
        fields << Field.String(name: "symbol")
        fields << Field.Integer(name: "buyCount")
        fields << Field.Integer(name: "sellCount")
        fields << Field.Integer(name: "remained")
        fields << Field.Double(name: "costPerShare")
        fields << Field.Double(name: "totalClosedCost", footerCalculation: DJCalculation.SUM)
        fields << Field.Double(name: "totalOpenCost", footerCalculation: DJCalculation.SUM)
        fields << Field.Double(name: "sellPrice")
        fields << Field.Double(name: "currentSharePrice")
        fields << Field.Double(name: "marketValue", footerCalculation: DJCalculation.SUM)
        fields << Field.Double(name: "closedPositionsProfitLoss", footerCalculation: DJCalculation.SUM)
        fields << Field.Double(name: "openPositionsProfitLoss", footerCalculation: DJCalculation.SUM)
        fields << Field.Double(name: "totalProfitLoss", footerCalculation: DJCalculation.SUM)
        fields << Field.Double(name: "performance")

        def columns = fields.collect {it.title}.toArray(new String[0])

        reportService.CreateReportFile(reportTitle, subTitle, fields, portfolioPerformanceService.report(params).list, columns, format, response, request, true)
    }
}
package fundmanagement.reports

class PortfolioPerformance {
    String symbol
    Integer buyCount
    Integer sellCount
    Integer remained
    Double costPerShare
    Double totalClosedCost
    Double totalOpenCost
    Double sellPrice
    Double currentSharePrice
    Double marketValue
    Double closedPositionsProfitLoss
    Double openPositionsProfitLoss
    Double totalProfitLoss
    Double performance

    static charts = {
        chart(title: "profitLoss", subtitle: "", variable: "symbol") {
            column("closedPositionsProfitLoss")
            column("openPositionsProfitLoss")
            column("totalProfitLoss")
        }
        chart(title: "performance", subtitle: "", variable: "symbol") {
            column("performance")
        }
    }

    static constraints = {
        symbol()
        buyCount()
        sellCount()
        remained()
        costPerShare()
        totalClosedCost()
        totalOpenCost()
        sellPrice()
        currentSharePrice()
        marketValue()
        closedPositionsProfitLoss()
        openPositionsProfitLoss()
        totalProfitLoss()
        performance()
    }
}