Açıklama Yok

views.py 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. from __future__ import annotations
  2. from django.shortcuts import render, redirect, get_object_or_404
  3. from django.contrib import messages
  4. from django.urls import reverse
  5. from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
  6. from orgs.models import Organization, UserProfile
  7. from recycle_core.models import ProvidedService
  8. from recycle_core.models import Material, ScrapListing, PickupOrder
  9. from cms.models import Post, PostCategory
  10. from .forms import PickupRequestForm, ContactForm, RegistrationForm, PublicUserForm, PublicUserPhotoForm
  11. from .models import Lead
  12. from recycle_core.controllers.pickup_request import (
  13. PickupRequestController,
  14. PickupRequestData,
  15. )
  16. from django.contrib.auth.views import LoginView
  17. from django.urls import reverse
  18. def home(request):
  19. org = getattr(request, "org", None)
  20. posts_qs = Post.objects.all()
  21. if org is not None:
  22. posts_qs = posts_qs.filter(organization=org)
  23. posts = posts_qs.order_by("-published_at")[:3]
  24. listings_qs = ScrapListing.objects.filter(is_public=True)
  25. if org is not None:
  26. listings_qs = listings_qs.filter(organization=org)
  27. listings = listings_qs.order_by("-created_at")[:6]
  28. materials_qs = Material.objects.all().order_by("name")
  29. if org is not None:
  30. materials_qs = materials_qs.filter(organization=org)
  31. materials = materials_qs[:12]
  32. services_qs = ProvidedService.objects.none()
  33. if org is not None:
  34. services_qs = ProvidedService.objects.filter(organization=org, is_enabled=True).order_by("display_order", "id")
  35. services = list(services_qs)
  36. pickup_form = PickupRequestForm()
  37. contact_form = ContactForm()
  38. register_form = RegistrationForm()
  39. return render(
  40. request,
  41. "public_frontend/home.html",
  42. {
  43. "posts": posts,
  44. "listings": listings,
  45. "materials": materials,
  46. "services": services,
  47. "pickup_form": pickup_form,
  48. "contact_form": contact_form,
  49. "org": org,
  50. "register_form": register_form,
  51. },
  52. )
  53. def materials_list(request):
  54. org = getattr(request, "org", None)
  55. qs = Material.objects.all().order_by("name")
  56. if org is not None:
  57. qs = qs.filter(organization=org)
  58. return render(request, "public_frontend/materials_list.html", {"materials": qs, "org": org})
  59. def listings_list(request):
  60. org = getattr(request, "org", None)
  61. qs = ScrapListing.objects.filter(is_public=True, status=ScrapListing.STATUS_OPEN).order_by("-created_at")
  62. if org is not None:
  63. qs = qs.filter(organization=org)
  64. paginator = Paginator(qs, 12)
  65. page = request.GET.get("page")
  66. try:
  67. page_obj = paginator.page(page)
  68. except PageNotAnInteger:
  69. page_obj = paginator.page(1)
  70. except EmptyPage:
  71. page_obj = paginator.page(paginator.num_pages)
  72. return render(request, "public_frontend/listings_list.html", {"page_obj": page_obj, "listings": page_obj.object_list, "org": org})
  73. def listing_detail(request, pk: int):
  74. org = getattr(request, "org", None)
  75. base_qs = ScrapListing.objects.filter(is_public=True)
  76. if org is not None:
  77. base_qs = base_qs.filter(organization=org)
  78. listing = get_object_or_404(base_qs, pk=pk)
  79. return render(request, "public_frontend/listing_detail.html", {"listing": listing, "org": org})
  80. def service_detail(request, pk: int):
  81. org = getattr(request, "org", None)
  82. base_qs = ProvidedService.objects.filter(is_enabled=True)
  83. if org is not None:
  84. base_qs = base_qs.filter(organization=org)
  85. service = get_object_or_404(base_qs, pk=pk)
  86. return render(request, "public_frontend/service_detail.html", {"service": service, "org": org})
  87. def pickup_request(request):
  88. org = getattr(request, "org", None)
  89. form = PickupRequestForm(request.POST or None, request.FILES or None)
  90. if request.method == "POST":
  91. if not org:
  92. messages.error(request, "Organization context missing.")
  93. return redirect("public_frontend:pickup_request")
  94. if form.is_valid():
  95. ctrl = PickupRequestController()
  96. data = PickupRequestData(
  97. organization=org,
  98. name=form.cleaned_data.get("name"),
  99. email=form.cleaned_data.get("email", ""),
  100. phone=form.cleaned_data.get("phone", ""),
  101. address=form.cleaned_data.get("address", ""),
  102. materials=form.cleaned_data.get("materials", ""),
  103. preferred_at=form.cleaned_data.get("preferred_at"),
  104. files=request.FILES.getlist("photos") if hasattr(request, "FILES") and "photos" in request.FILES else [],
  105. )
  106. result = ctrl.submit(data)
  107. if result.ok:
  108. messages.success(request, "Thanks! Your pickup request was submitted.")
  109. return redirect("public_frontend:home")
  110. else:
  111. messages.error(request, result.error or "Unable to submit your request.")
  112. else:
  113. messages.error(request, "Please correct the errors below.")
  114. return render(request, "public_frontend/pickup_request.html", {"form": form, "org": org})
  115. def contact(request):
  116. org = getattr(request, "org", None)
  117. form = ContactForm(request.POST or None)
  118. if request.method == "POST":
  119. if not org:
  120. messages.error(request, "Organization context missing.")
  121. return redirect("public_frontend:contact")
  122. if form.is_valid():
  123. Lead.objects.create(
  124. organization=org,
  125. name=form.cleaned_data["name"],
  126. email=form.cleaned_data["email"],
  127. phone=form.cleaned_data.get("phone", ""),
  128. subject=form.cleaned_data.get("subject", ""),
  129. message=form.cleaned_data.get("message", ""),
  130. source="contact",
  131. )
  132. messages.success(request, "Thanks! We will get back to you shortly.")
  133. return redirect("public_frontend:home")
  134. messages.error(request, "Please correct the errors below.")
  135. return render(request, "public_frontend/contact.html", {"form": form, "org": org})
  136. def register(request):
  137. from django.contrib.auth import get_user_model
  138. from django.contrib.auth.models import Group
  139. from orgs.models import UserProfile
  140. org = getattr(request, "org", None)
  141. if not org:
  142. messages.error(request, "Organization context missing.")
  143. return redirect("public_frontend:home")
  144. form = RegistrationForm(request.POST or None)
  145. if request.method == "POST":
  146. if form.is_valid():
  147. User = get_user_model()
  148. user = User(username=form.cleaned_data["username"], email=form.cleaned_data["email"], is_active=False)
  149. user.set_password(form.cleaned_data["password1"])
  150. user.save()
  151. role = form.cleaned_data["role"]
  152. # Create org profile
  153. UserProfile.objects.create(user=user, organization=org, role=role)
  154. # Add to group matching the role if exists
  155. try:
  156. g = Group.objects.filter(name=role).first()
  157. if g:
  158. user.groups.add(g)
  159. except Exception:
  160. pass
  161. messages.success(request, "Account created. Please wait for admin approval.")
  162. return redirect("public_frontend:home")
  163. else:
  164. messages.error(request, "Please correct the errors below.")
  165. return render(request, "public_frontend/register.html", {"form": form, "org": org})
  166. def blog_list(request):
  167. org = getattr(request, "org", None)
  168. qs = Post.objects.all().order_by("-published_at", "-created_at")
  169. if org is not None:
  170. qs = qs.filter(organization=org)
  171. paginator = Paginator(qs, 10)
  172. page = request.GET.get("page")
  173. try:
  174. page_obj = paginator.page(page)
  175. except PageNotAnInteger:
  176. page_obj = paginator.page(1)
  177. except EmptyPage:
  178. page_obj = paginator.page(paginator.num_pages)
  179. return render(request, "public_frontend/blog_list.html", {"page_obj": page_obj, "posts": page_obj.object_list, "org": org})
  180. def blog_detail(request, slug: str):
  181. org = getattr(request, "org", None)
  182. base_qs = Post.objects.all()
  183. if org is not None:
  184. base_qs = base_qs.filter(organization=org)
  185. post = get_object_or_404(base_qs, slug=slug)
  186. # Ensure markdown is rendered; fallback to raw content if needed
  187. html = getattr(post, "content_html", None) or getattr(post, "content", "")
  188. return render(request, "public_frontend/blog_detail.html", {"post": post, "html": html, "org": org})
  189. class PublicLoginView(LoginView):
  190. template_name = "public_frontend/login.html"
  191. redirect_authenticated_user = True
  192. def get_success_url(self):
  193. return reverse("public_frontend:home")
  194. from django.contrib.auth.decorators import login_required
  195. from django.contrib.auth import get_user_model
  196. @login_required
  197. def my_profile(request):
  198. user = request.user
  199. profile = getattr(user, "recycle_profile", None)
  200. role_code = getattr(profile, "role", None)
  201. role_label = dict(UserProfile.ROLE_CHOICES).get(role_code, "-") if role_code else "-"
  202. if request.method == "POST":
  203. form_user = PublicUserForm(request.POST, instance=user)
  204. form_photo = PublicUserPhotoForm(request.POST, request.FILES, instance=profile) if profile else None
  205. ok_user = form_user.is_valid()
  206. ok_photo = True if form_photo is None else form_photo.is_valid()
  207. if ok_user and ok_photo:
  208. form_user.save()
  209. if form_photo is not None:
  210. form_photo.save()
  211. messages.success(request, "Profile updated.")
  212. return redirect(reverse("public_frontend:my_profile"))
  213. messages.error(request, "Please correct the errors below.")
  214. else:
  215. form_user = PublicUserForm(instance=user)
  216. form_photo = PublicUserPhotoForm(instance=profile) if profile else None
  217. return render(
  218. request,
  219. "public_frontend/my_profile.html",
  220. {"form_user": form_user, "form_photo": form_photo, "has_profile": bool(profile), "username_value": user.username, "role_label": role_label},
  221. )