mirror of
https://github.com/wahyd4/links.git
synced 2026-08-09 05:06:16 +10:00
95 lines
3.3 KiB
Python
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,
|
|
})
|