Files
links/invest/template_views.py
T

95 lines
3.3 KiB
Python

"""Template views for the invest app."""
import logging
from django.shortcuts import get_object_or_404, render
from django.utils import timezone
from links.models import Post, Tag
from .models import Portfolio, Transaction
from .services import (
get_all_holdings,
get_cashflow_adjusted_performance,
get_net_external_cash_flow,
get_performance_chart_data,
get_portfolio_value,
get_risk_summary,
get_weekly_overview,
)
logger = logging.getLogger(__name__)
def dashboard(request):
"""Landing page: agent-first metrics + human-readable holdings/risk dashboard."""
overview = get_weekly_overview()
now = timezone.now()
fy_start = now.year if now.month >= 7 else now.year - 1
fy_label = f"FY {str(fy_start)[2:]}-{str(fy_start + 1)[2:]}"
reference_date = overview.get('last_week_date')
all_holdings = get_all_holdings(reference_date=reference_date)
rows_by_id = {row['portfolio'].id: row for row in overview.get('portfolio_rows', [])}
for group in all_holdings:
row = rows_by_id.get(group['portfolio'].id, {})
group['this_week_value'] = row.get('this_week_value')
group['change'] = row.get('change')
group['change_pct'] = row.get('change_pct')
group['position_count'] = row.get('position_count', len(group['holdings']))
performance = get_cashflow_adjusted_performance()
risk = get_risk_summary()
recent_transactions = Transaction.objects.select_related('portfolio').order_by('-date', '-created_at')[:30]
invest_tags = list(Tag.objects.filter(slug__in=['invest', 'investment']).order_by('slug'))
invest_tag = next((tag for tag in invest_tags if tag.slug == 'invest'), None) or (invest_tags[0] if invest_tags else None)
investment_posts = Post.objects.none()
if invest_tags:
investment_posts = (
Post.objects.filter(tags__in=invest_tags)
.distinct()
.order_by('-created_at')[:12]
)
return render(request, 'invest/dashboard.html', {
'overview': overview,
'fy_label': fy_label,
'all_holdings': all_holdings,
'chart_data_json': get_performance_chart_data() or 'null',
'performance': performance,
'net_contributions': get_net_external_cash_flow(),
'risk': risk,
'recent_transactions': recent_transactions,
'invest_tag': invest_tag,
'investment_posts': investment_posts,
})
def portfolio_detail(request, pk):
"""Portfolio detail: live holdings."""
portfolio = get_object_or_404(Portfolio, pk=pk)
try:
summary = get_portfolio_value(portfolio)
except Exception as exc:
logger.error("get_portfolio_value failed for %s: %s", pk, exc)
summary = {
'portfolio_id': portfolio.id,
'portfolio_name': portfolio.name,
'holdings': [],
'total_value': 0,
}
return render(request, 'invest/portfolio_detail.html', {
'portfolio': portfolio,
'summary': summary,
})
def portfolio_transactions(request, pk):
"""Transaction history for a portfolio."""
portfolio = get_object_or_404(Portfolio, pk=pk)
transactions = portfolio.transactions.all().order_by('-date', '-created_at')
return render(request, 'invest/transactions.html', {
'portfolio': portfolio,
'transactions': transactions,
})