diff --git a/app/Models/DailyChange.php b/app/Models/DailyChange.php index 04f774e..8136612 100644 --- a/app/Models/DailyChange.php +++ b/app/Models/DailyChange.php @@ -62,83 +62,72 @@ class DailyChange extends Model { $currency = auth()->user()?->getCurrency() ?? config('investbrain.base_currency'); - $dividendSub = DB::table('holdings') - ->join('dividends', 'dividends.symbol', '=', 'holdings.symbol') - ->leftJoin('currency_rates as cr', function ($join) use ($currency) { - $join->on(DB::raw('DATE(cr.date)'), '=', DB::raw('DATE(dividends.date)')) - ->where('cr.currency', '=', $currency); - }) - ->join('transactions as tx', function ($join) { - $join->on('tx.symbol', '=', 'holdings.symbol') - ->on('tx.portfolio_id', '=', 'holdings.portfolio_id') - ->whereColumn('tx.date', '<=', 'dividends.date'); - }) - ->select(['holdings.portfolio_id', 'dividends.date']) - ->selectRaw(" - ((CASE WHEN tx.transaction_type = 'BUY' - THEN tx.quantity ELSE 0 END) - - (CASE WHEN tx.transaction_type = 'SELL' - THEN tx.quantity ELSE 0 END)) - * SUM( - dividends.dividend_amount_base - * COALESCE(cr.rate, 1) - ) - AS total_dividends_earned") - ->groupBy(['holdings.portfolio_id', 'dividends.date', 'tx.transaction_type', 'tx.quantity']); - - $costBasisSub = DB::table('transactions') - ->leftJoin('currency_rates as cr', function ($join) use ($currency) { - $join->on(DB::raw('DATE(cr.date)'), '=', DB::raw('DATE(transactions.date)')) - ->where('cr.currency', $currency); - }) - ->select(['transactions.portfolio_id', 'transactions.date']); - return $query - ->select(['daily_change.date', 'daily_change.portfolio_id']) - ->selectRaw('daily_change.total_market_value * COALESCE(cr.rate, 1) AS total_market_value') + // Join currency rates to get the rate for each date ->leftJoin('currency_rates as cr', function ($join) use ($currency) { $join->on(DB::raw('DATE(cr.date)'), '=', DB::raw('DATE(daily_change.date)')) ->where('cr.currency', '=', $currency); }) - ->selectSub(function ($query) use ($costBasisSub) { - $query->fromSub( - $costBasisSub->selectRaw(" - (CASE - WHEN transactions.transaction_type = 'BUY' - THEN 1 ELSE -1 END - ) * transactions.cost_basis_base * transactions.quantity * COALESCE(cr.rate, 1) AS total_cost_basis"), - 'cb') - ->selectRaw('SUM(cb.total_cost_basis)') - ->whereColumn('cb.date', '<=', 'daily_change.date') - ->whereColumn('cb.portfolio_id', '=', 'daily_change.portfolio_id'); - }, 'total_cost_basis') - ->selectSub(function ($query) use ($costBasisSub) { - $query->fromSub( - $costBasisSub->selectRaw(" - (CASE - WHEN transactions.transaction_type = 'SELL' - THEN transactions.sale_price_base - transactions.cost_basis_base - END - ) * transactions.quantity * COALESCE(cr.rate, 1) AS realized_gain_dollars"), - 'cb') - ->selectRaw('SUM(cb.realized_gain_dollars)') - ->whereColumn('cb.date', '<=', 'daily_change.date') - ->whereColumn('cb.portfolio_id', '=', 'daily_change.portfolio_id'); - }, 'realized_gain_dollars') - ->selectSub(function ($query) use ($dividendSub) { // todo: maybe costbasis uses this model? - $query->fromSub($dividendSub, 'd') - ->selectRaw('SUM(d.total_dividends_earned)') - ->whereColumn('d.date', '<=', 'daily_change.date') - ->whereColumn('d.portfolio_id', '=', 'daily_change.portfolio_id'); - }, 'total_dividends_earned') - ->addSelect('annotation') + ->select([ + 'daily_change.date', + 'daily_change.portfolio_id', + DB::raw('daily_change.total_market_value * COALESCE(cr.rate, 1) as total_market_value'), + 'total_cost_basis' => function ($query) use ($currency) { + $query->from('transactions') + ->leftJoin('currency_rates as cr', function ($join) use ($currency) { + $join->on(DB::raw('DATE(cr.date)'), '=', DB::raw('DATE(transactions.date)')) + ->where('cr.currency', '=', $currency); + }) + ->selectRaw('SUM( + (CASE WHEN transactions.transaction_type = \'BUY\' THEN 1 ELSE -1 END) + * transactions.cost_basis_base * transactions.quantity * COALESCE(cr.rate, 1) + )') + ->whereColumn('transactions.portfolio_id', 'daily_change.portfolio_id') + ->whereColumn('transactions.date', '<=', 'daily_change.date'); + }, + 'realized_gain_dollars' => function ($query) use ($currency) { + $query->from('transactions') + ->leftJoin('currency_rates as cr', function ($join) use ($currency) { + $join->on(DB::raw('DATE(cr.date)'), '=', DB::raw('DATE(transactions.date)')) + ->where('cr.currency', '=', $currency); + }) + ->selectRaw('SUM( + (CASE WHEN transactions.transaction_type = \'SELL\' + THEN (transactions.sale_price_base - transactions.cost_basis_base) + ELSE 0 END) + * transactions.quantity * COALESCE(cr.rate, 1) + )') + ->whereColumn('transactions.portfolio_id', 'daily_change.portfolio_id') + ->whereColumn('transactions.date', '<=', 'daily_change.date'); + }, + 'total_dividends_earned' => function ($query) use ($currency) { + $query->from('holdings') + ->join('dividends', 'dividends.symbol', '=', 'holdings.symbol') + ->leftJoin('currency_rates as cr', function ($join) use ($currency) { + $join->on(DB::raw('DATE(cr.date)'), '=', DB::raw('DATE(dividends.date)')) + ->where('cr.currency', '=', $currency); + }) + ->join('transactions as tx', function ($join) { + $join->on('tx.symbol', '=', 'holdings.symbol') + ->on('tx.portfolio_id', '=', 'holdings.portfolio_id') + ->whereColumn('tx.date', '<=', 'dividends.date'); + }) + ->selectRaw('SUM( + ((CASE WHEN tx.transaction_type = \'BUY\' THEN tx.quantity ELSE 0 END) + - (CASE WHEN tx.transaction_type = \'SELL\' THEN tx.quantity ELSE 0 END)) + * dividends.dividend_amount_base + * COALESCE(cr.rate, 1) + )') + ->whereColumn('holdings.portfolio_id', 'daily_change.portfolio_id') + ->whereColumn('dividends.date', '<=', 'daily_change.date'); + }, + ]) ->orderBy('daily_change.date'); } public function scopeGetDailyPerformance($query) { return $query->get() - ->sortBy('date') ->groupBy('date') ->map(function ($group) { diff --git a/app/Models/Holding.php b/app/Models/Holding.php index dee3c3e..d1343b7 100644 --- a/app/Models/Holding.php +++ b/app/Models/Holding.php @@ -402,7 +402,7 @@ class Holding extends Model ) ->leftJoinSub($dividends_sub, 'dividends_display', function ($join) { - $join->on('holdings.symbol', '=', 'dividends_display.symbol'); + $join->on('holdings.symbol', '=', 'dividends_display.symbol'); // todo: this isnt limiting to port ids } );