mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-01-15 21:53:28 +01:00
298 lines
8.1 KiB
Python
298 lines
8.1 KiB
Python
from django.contrib import messages
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.db.models import Sum, Avg
|
|
from django.db.models.functions import TruncMonth
|
|
from django.http import HttpResponse
|
|
from django.shortcuts import render, get_object_or_404
|
|
from django.utils.translation import gettext_lazy as _
|
|
from django.views.decorators.http import require_http_methods
|
|
|
|
from apps.common.decorators.htmx import only_htmx
|
|
from apps.dca.forms import DCAEntryForm, DCAStrategyForm
|
|
from apps.dca.models import DCAStrategy, DCAEntry
|
|
from apps.common.models import SharedObject
|
|
from apps.common.forms import SharedObjectForm
|
|
|
|
|
|
@login_required
|
|
def strategy_index(request):
|
|
return render(request, "dca/pages/strategy_index.html")
|
|
|
|
|
|
@only_htmx
|
|
@login_required
|
|
def strategy_list(request):
|
|
strategies = DCAStrategy.objects.all().order_by("name")
|
|
return render(
|
|
request, "dca/fragments/strategy/list.html", {"strategies": strategies}
|
|
)
|
|
|
|
|
|
@only_htmx
|
|
@login_required
|
|
def strategy_add(request):
|
|
if request.method == "POST":
|
|
form = DCAStrategyForm(request.POST)
|
|
if form.is_valid():
|
|
form.save()
|
|
messages.success(request, _("DCA Strategy added successfully"))
|
|
|
|
return HttpResponse(
|
|
status=204,
|
|
headers={
|
|
"HX-Trigger": "updated, hide_offcanvas",
|
|
},
|
|
)
|
|
else:
|
|
form = DCAStrategyForm()
|
|
|
|
return render(
|
|
request,
|
|
"dca/fragments/strategy/add.html",
|
|
{"form": form},
|
|
)
|
|
|
|
|
|
@only_htmx
|
|
@login_required
|
|
def strategy_edit(request, strategy_id):
|
|
dca_strategy = get_object_or_404(DCAStrategy, id=strategy_id)
|
|
|
|
if dca_strategy.owner and dca_strategy.owner != request.user:
|
|
messages.error(request, _("Only the owner can edit this"))
|
|
|
|
return HttpResponse(
|
|
status=204,
|
|
headers={
|
|
"HX-Trigger": "updated, hide_offcanvas",
|
|
},
|
|
)
|
|
|
|
if request.method == "POST":
|
|
form = DCAStrategyForm(request.POST, instance=dca_strategy)
|
|
if form.is_valid():
|
|
form.save()
|
|
messages.success(request, _("DCA Strategy updated successfully"))
|
|
|
|
return HttpResponse(
|
|
status=204,
|
|
headers={
|
|
"HX-Trigger": "updated, hide_offcanvas",
|
|
},
|
|
)
|
|
else:
|
|
form = DCAStrategyForm(instance=dca_strategy)
|
|
|
|
return render(
|
|
request,
|
|
"dca/fragments/strategy/edit.html",
|
|
{"form": form, "strategy": dca_strategy},
|
|
)
|
|
|
|
|
|
@only_htmx
|
|
@login_required
|
|
@require_http_methods(["DELETE"])
|
|
def strategy_delete(request, strategy_id):
|
|
dca_strategy = get_object_or_404(DCAStrategy, id=strategy_id)
|
|
|
|
if (
|
|
dca_strategy.owner != request.user
|
|
and request.user in dca_strategy.shared_with.all()
|
|
):
|
|
dca_strategy.shared_with.remove(request.user)
|
|
messages.success(request, _("Item no longer shared with you"))
|
|
else:
|
|
dca_strategy.delete()
|
|
messages.success(request, _("DCA strategy deleted successfully"))
|
|
|
|
return HttpResponse(
|
|
status=204,
|
|
headers={
|
|
"HX-Trigger": "updated, hide_offcanvas",
|
|
},
|
|
)
|
|
|
|
|
|
@only_htmx
|
|
@login_required
|
|
@require_http_methods(["GET"])
|
|
def strategy_take_ownership(request, strategy_id):
|
|
dca_strategy = get_object_or_404(DCAStrategy, id=strategy_id)
|
|
|
|
if not dca_strategy.owner:
|
|
dca_strategy.owner = request.user
|
|
dca_strategy.visibility = SharedObject.Visibility.private
|
|
dca_strategy.save()
|
|
|
|
messages.success(request, _("Ownership taken successfully"))
|
|
|
|
return HttpResponse(
|
|
status=204,
|
|
headers={
|
|
"HX-Trigger": "updated, hide_offcanvas",
|
|
},
|
|
)
|
|
|
|
|
|
@only_htmx
|
|
@login_required
|
|
@require_http_methods(["GET", "POST"])
|
|
def strategy_share(request, pk):
|
|
obj = get_object_or_404(DCAStrategy, id=pk)
|
|
|
|
if obj.owner and obj.owner != request.user:
|
|
messages.error(request, _("Only the owner can edit this"))
|
|
|
|
return HttpResponse(
|
|
status=204,
|
|
headers={
|
|
"HX-Trigger": "updated, hide_offcanvas",
|
|
},
|
|
)
|
|
|
|
if request.method == "POST":
|
|
form = SharedObjectForm(request.POST, instance=obj, user=request.user)
|
|
if form.is_valid():
|
|
form.save()
|
|
messages.success(request, _("Configuration saved successfully"))
|
|
|
|
return HttpResponse(
|
|
status=204,
|
|
headers={
|
|
"HX-Trigger": "updated, hide_offcanvas",
|
|
},
|
|
)
|
|
else:
|
|
form = SharedObjectForm(instance=obj, user=request.user)
|
|
|
|
return render(
|
|
request,
|
|
"dca/fragments/strategy/share.html",
|
|
{"form": form, "object": obj},
|
|
)
|
|
|
|
|
|
@login_required
|
|
def strategy_detail_index(request, strategy_id):
|
|
strategy = get_object_or_404(DCAStrategy, id=strategy_id)
|
|
|
|
return render(
|
|
request,
|
|
"dca/pages/strategy_detail_index.html",
|
|
context={"strategy": strategy},
|
|
)
|
|
|
|
|
|
@only_htmx
|
|
@login_required
|
|
def strategy_detail(request, strategy_id):
|
|
strategy = get_object_or_404(DCAStrategy, id=strategy_id)
|
|
entries = strategy.entries.all()
|
|
|
|
# Calculate monthly aggregates
|
|
monthly_data = (
|
|
entries.annotate(month=TruncMonth("date"))
|
|
.values("month")
|
|
.annotate(
|
|
total_paid=Sum("amount_paid"),
|
|
total_received=Sum("amount_received"),
|
|
avg_entry_price=Avg("amount_paid") / Avg("amount_received"),
|
|
)
|
|
.order_by("month")
|
|
)
|
|
|
|
# Prepare entries data with current values
|
|
entries_data = [
|
|
{
|
|
"entry": entry,
|
|
"current_value": entry.current_value(),
|
|
"profit_loss": entry.profit_loss(),
|
|
"profit_loss_percentage": entry.profit_loss_percentage(),
|
|
}
|
|
for entry in entries
|
|
]
|
|
entries_data.reverse()
|
|
|
|
context = {
|
|
"strategy": strategy,
|
|
"entries": entries,
|
|
"entries_data": entries_data,
|
|
"monthly_data": monthly_data,
|
|
"investment_frequency": strategy.investment_frequency_data(),
|
|
"price_comparison_data": strategy.price_comparison_data(),
|
|
}
|
|
|
|
return render(request, "dca/fragments/strategy/details.html", context)
|
|
|
|
|
|
@only_htmx
|
|
@login_required
|
|
def strategy_entry_add(request, strategy_id):
|
|
strategy = get_object_or_404(DCAStrategy, id=strategy_id)
|
|
if request.method == "POST":
|
|
form = DCAEntryForm(request.POST, strategy=strategy)
|
|
if form.is_valid():
|
|
form.save()
|
|
messages.success(request, _("Entry added successfully"))
|
|
|
|
return HttpResponse(
|
|
status=204,
|
|
headers={
|
|
"HX-Trigger": "updated, hide_offcanvas",
|
|
},
|
|
)
|
|
else:
|
|
form = DCAEntryForm(strategy=strategy)
|
|
|
|
return render(
|
|
request,
|
|
"dca/fragments/entry/add.html",
|
|
{"form": form, "strategy": strategy},
|
|
)
|
|
|
|
|
|
@only_htmx
|
|
@login_required
|
|
def strategy_entry_edit(request, strategy_id, entry_id):
|
|
dca_entry = get_object_or_404(DCAEntry, id=entry_id, strategy__id=strategy_id)
|
|
|
|
if request.method == "POST":
|
|
form = DCAEntryForm(request.POST, instance=dca_entry)
|
|
if form.is_valid():
|
|
form.save()
|
|
messages.success(request, _("Entry updated successfully"))
|
|
|
|
return HttpResponse(
|
|
status=204,
|
|
headers={
|
|
"HX-Trigger": "updated, hide_offcanvas",
|
|
},
|
|
)
|
|
else:
|
|
form = DCAEntryForm(instance=dca_entry)
|
|
|
|
return render(
|
|
request,
|
|
"dca/fragments/entry/edit.html",
|
|
{"form": form, "dca_entry": dca_entry},
|
|
)
|
|
|
|
|
|
@only_htmx
|
|
@login_required
|
|
@require_http_methods(["DELETE"])
|
|
def strategy_entry_delete(request, entry_id, strategy_id):
|
|
dca_entry = get_object_or_404(DCAEntry, id=entry_id, strategy__id=strategy_id)
|
|
|
|
dca_entry.delete()
|
|
|
|
messages.success(request, _("Entry deleted successfully"))
|
|
|
|
return HttpResponse(
|
|
status=204,
|
|
headers={
|
|
"HX-Trigger": "updated, hide_offcanvas",
|
|
},
|
|
)
|