feat: multi tenancy support

This commit is contained in:
Herculino Trotta
2025-03-08 12:03:17 -03:00
parent c7d70a1748
commit 020dd74f80
79 changed files with 2401 additions and 399 deletions
+77 -3
View File
@@ -8,6 +8,8 @@ from django.views.decorators.http import require_http_methods
from apps.common.decorators.htmx import only_htmx
from apps.transactions.forms import TransactionCategoryForm
from apps.transactions.models import TransactionCategory
from apps.common.models import SharedObject
from apps.common.forms import SharedObjectForm
@login_required
@@ -85,6 +87,16 @@ def category_add(request, **kwargs):
def category_edit(request, category_id):
category = get_object_or_404(TransactionCategory, id=category_id)
if category.owner and category.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 = TransactionCategoryForm(request.POST, instance=category)
if form.is_valid():
@@ -107,15 +119,77 @@ def category_edit(request, category_id):
)
@only_htmx
@login_required
@require_http_methods(["GET", "POST"])
def category_share(request, pk):
obj = get_object_or_404(TransactionCategory, 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,
"categories/fragments/share.html",
{"form": form, "object": obj},
)
@only_htmx
@login_required
@require_http_methods(["DELETE"])
def category_delete(request, category_id):
category = get_object_or_404(TransactionCategory, id=category_id)
category.delete()
messages.success(request, _("Category deleted successfully"))
if category.owner != request.user and request.user in category.shared_with.all():
category.shared_with.remove(request.user)
messages.success(request, _("Item no longer shared with you"))
else:
category.delete()
messages.success(request, _("Category deleted successfully"))
return HttpResponse(
status=204,
headers={
"HX-Trigger": "updated, hide_offcanvas",
},
)
@only_htmx
@login_required
@require_http_methods(["GET"])
def category_take_ownership(request, category_id):
category = get_object_or_404(TransactionCategory, id=category_id)
if not category.owner:
category.owner = request.user
category.visibility = SharedObject.Visibility.private
category.save()
messages.success(request, _("Ownership taken successfully"))
return HttpResponse(
status=204,
+77 -3
View File
@@ -8,6 +8,8 @@ from django.views.decorators.http import require_http_methods
from apps.common.decorators.htmx import only_htmx
from apps.transactions.forms import TransactionEntityForm
from apps.transactions.models import TransactionEntity
from apps.common.models import SharedObject
from apps.common.forms import SharedObjectForm
@login_required
@@ -85,6 +87,16 @@ def entity_add(request, **kwargs):
def entity_edit(request, entity_id):
entity = get_object_or_404(TransactionEntity, id=entity_id)
if entity.owner and entity.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 = TransactionEntityForm(request.POST, instance=entity)
if form.is_valid():
@@ -113,9 +125,12 @@ def entity_edit(request, entity_id):
def entity_delete(request, entity_id):
entity = get_object_or_404(TransactionEntity, id=entity_id)
entity.delete()
messages.success(request, _("Entity deleted successfully"))
if entity.owner != request.user and request.user in entity.shared_with.all():
entity.shared_with.remove(request.user)
messages.success(request, _("Item no longer shared with you"))
else:
entity.delete()
messages.success(request, _("Entity deleted successfully"))
return HttpResponse(
status=204,
@@ -123,3 +138,62 @@ def entity_delete(request, entity_id):
"HX-Trigger": "updated, hide_offcanvas",
},
)
@only_htmx
@login_required
@require_http_methods(["GET"])
def entity_take_ownership(request, entity_id):
entity = get_object_or_404(TransactionEntity, id=entity_id)
if not entity.owner:
entity.owner = request.user
entity.visibility = SharedObject.Visibility.private
entity.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 entity_share(request, pk):
obj = get_object_or_404(TransactionEntity, 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,
"entities/fragments/share.html",
{"form": form, "object": obj},
)
+77 -3
View File
@@ -8,6 +8,8 @@ from django.views.decorators.http import require_http_methods
from apps.common.decorators.htmx import only_htmx
from apps.transactions.forms import TransactionTagForm
from apps.transactions.models import TransactionTag
from apps.common.models import SharedObject
from apps.common.forms import SharedObjectForm
@login_required
@@ -85,6 +87,16 @@ def tag_add(request, **kwargs):
def tag_edit(request, tag_id):
tag = get_object_or_404(TransactionTag, id=tag_id)
if tag.owner and tag.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 = TransactionTagForm(request.POST, instance=tag)
if form.is_valid():
@@ -113,9 +125,12 @@ def tag_edit(request, tag_id):
def tag_delete(request, tag_id):
tag = get_object_or_404(TransactionTag, id=tag_id)
tag.delete()
messages.success(request, _("Tag deleted successfully"))
if tag.owner != request.user and request.user in tag.shared_with.all():
tag.shared_with.remove(request.user)
messages.success(request, _("Item no longer shared with you"))
else:
tag.delete()
messages.success(request, _("Tag deleted successfully"))
return HttpResponse(
status=204,
@@ -123,3 +138,62 @@ def tag_delete(request, tag_id):
"HX-Trigger": "updated, hide_offcanvas",
},
)
@only_htmx
@login_required
@require_http_methods(["GET"])
def tag_take_ownership(request, tag_id):
tag = get_object_or_404(TransactionTag, id=tag_id)
if not tag.owner:
tag.owner = request.user
tag.visibility = SharedObject.Visibility.private
tag.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 tag_share(request, pk):
obj = get_object_or_404(TransactionTag, 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,
"tags/fragments/share.html",
{"form": form, "object": obj},
)