· 10 months ago · Feb 26, 2025, 04:35 PM
1from django.contrib import messages
2from django.views.decorators.http import require_http_methods
3from django.contrib.auth import authenticate, login, logout
4from django.contrib.auth.decorators import login_required, user_passes_test
5from django.http import HttpResponse, JsonResponse, HttpResponseNotAllowed
6from django.shortcuts import get_object_or_404, render, redirect
7from django.views.decorators.csrf import csrf_exempt
8from reportlab.lib.pagesizes import letter
9from reportlab.pdfgen import canvas
10import random, json
11import traceback # Importa traceback una sola vez
12from .models import Cliente, Contrato, Servicio, Usuario, Rol, Empleado, Zona, Avenida, Direccion # Importa todos los modelos en una línea
13from .forms import ClienteForm, ContratoForm # Importa los formularios
14from django.core.paginator import Paginator
15from django.db.models import Q # Importa Q para consultas OR
16from .forms import ContratoForm
17
18
19
20@csrf_exempt
21def registrar_cliente(request):
22 if request.method == "POST":
23 try:
24 form = ClienteForm(request.POST)
25 if form.is_valid():
26 form.save()
27 return JsonResponse({"mensaje": "Cliente agregado correctamente"}, status=200)
28 else:
29 return JsonResponse({"error": "Error en el formulario", "detalles": form.errors}, status=400)
30 except Exception as e:
31 # Capturamos el traceback para ver detalles del error.
32 traceback_str = traceback.format_exc()
33 return JsonResponse({"error": "Error interno", "detalles": traceback_str}, status=500)
34 return JsonResponse({"error": "Método no permitido"}, status=405)
35
36
37
38
39
40
41def login_view(request):
42 if request.method == "POST":
43 username = request.POST['username']
44 password = request.POST['password']
45 user = authenticate(request, username=username, password=password)
46 if user is not None:
47 login(request, user)
48 return redirect('dashboard') # Redirigir al dashboard si el login es exitoso
49 else:
50 messages.error(request, "Usuario o contraseña incorrectos")
51 return render(request, 'usuarios/login.html')
52
53def logout_view(request):
54 logout(request)
55 return redirect('login') # Redirigir al login después de cerrar sesión
56
57@login_required
58def dashboard(request):
59 return render(request, 'usuarios/dashboard.html')
60
61### CRUD USUARIOS ###
62
63@login_required
64def lista_usuarios(request):
65 usuarios = Usuario.objects.all()
66 roles = Rol.objects.all() # ✅ Asegurar que los roles estén disponibles en la plantilla
67 return render(request, 'usuarios/lista_usuarios.html', {'usuarios': usuarios, 'roles': roles})
68
69@login_required
70def editar_usuario(request, user_id):
71 usuario = get_object_or_404(Usuario, id=user_id)
72
73 if request.method == 'POST':
74 usuario.username = request.POST['username']
75 usuario.first_name = request.POST['first_name']
76 usuario.last_name = request.POST['last_name']
77 usuario.email = request.POST['email']
78 usuario.rol_id = request.POST.get('rol')
79 usuario.estatus = 'estatus' in request.POST # Checkbox activo/inactivo
80 usuario.save()
81 messages.success(request, "Usuario actualizado correctamente.")
82 return redirect('lista_usuarios')
83
84 roles = Rol.objects.all()
85 return render(request, 'usuarios/editar_usuario.html', {'usuario': usuario, 'roles': roles})
86
87@login_required
88def eliminar_usuario(request, user_id):
89 usuario = get_object_or_404(Usuario, id=user_id)
90 usuario.delete()
91 messages.success(request, "Usuario eliminado correctamente.")
92 return redirect('lista_usuarios')
93
94@login_required
95def crear_usuario(request):
96 if request.method == "POST":
97 username = request.POST.get('username').strip()
98 first_name = request.POST.get('first_name').strip()
99 last_name = request.POST.get('last_name').strip()
100 email = request.POST.get('email').strip()
101 password = request.POST.get('password')
102 rol_id = request.POST.get('rol')
103
104 # Validar que no haya campos vacíos
105 if not username or not first_name or not last_name or not email or not password or not rol_id:
106 messages.error(request, "Todos los campos son obligatorios.")
107 return redirect('lista_usuarios')
108
109 # Validar si el usuario ya existe
110 if Usuario.objects.filter(username=username).exists():
111 messages.error(request, "El nombre de usuario ya está en uso.")
112 return redirect('lista_usuarios')
113
114 # Verificar si el rol existe en la base de datos
115 try:
116 rol = Rol.objects.get(id=rol_id)
117 except Rol.DoesNotExist:
118 messages.error(request, "El rol seleccionado no es válido.")
119 return redirect('lista_usuarios')
120
121 # Crear usuario y cifrar la contraseña
122 nuevo_usuario = Usuario(
123 username=username,
124 first_name=first_name,
125 last_name=last_name,
126 email=email,
127 rol=rol
128 )
129 nuevo_usuario.set_password(password) # 🔐 Cifra la contraseña
130 nuevo_usuario.save()
131
132 messages.success(request, f"Usuario '{username}' creado correctamente.")
133 return redirect('lista_usuarios')
134
135 # Si el método no es POST, regresar la lista de usuarios
136 usuarios = Usuario.objects.all()
137 roles = Rol.objects.all()
138 return render(request, 'usuarios/lista_usuarios.html', {'usuarios': usuarios, 'roles': roles})
139
140
141### CRUD EMPLEADOS ###
142
143@login_required
144def lista_empleados(request):
145 empleados = Empleado.objects.all()
146 return render(request, 'usuarios/lista_empleados.html', {'empleados': empleados})
147
148@login_required
149def crear_empleado(request):
150 if request.method == "POST":
151 nombre = request.POST['nombre']
152 apellido = request.POST['apellido']
153 dni = request.POST['dni']
154 rol_id = request.POST.get('rol')
155 rol = Rol.objects.get(id=rol_id)
156
157 Empleado.objects.create(nombre=nombre, apellido=apellido, dni=dni, rol=rol)
158 messages.success(request, "Empleado agregado correctamente.")
159 return redirect('lista_empleados')
160
161 roles = Rol.objects.all()
162 return render(request, 'usuarios/crear_empleado.html', {'roles': roles})
163
164@login_required
165def editar_empleado(request, emp_id):
166 empleado = get_object_or_404(Empleado, id=emp_id)
167
168 if request.method == "POST":
169 empleado.nombre = request.POST['nombre']
170 empleado.apellido = request.POST['apellido']
171 empleado.dni = request.POST['dni']
172 empleado.rol_id = request.POST.get('rol')
173 empleado.save()
174 messages.success(request, "Empleado actualizado correctamente.")
175 return redirect('lista_empleados')
176
177 roles = Rol.objects.all()
178 return render(request, 'usuarios/editar_empleado.html', {'empleado': empleado, 'roles': roles})
179
180@login_required
181def eliminar_empleado(request, emp_id):
182 empleado = get_object_or_404(Empleado, id=emp_id)
183 empleado.delete()
184 messages.success(request, "Empleado eliminado correctamente.")
185 return redirect('lista_empleados')
186
187### CRUD ROLES ###
188
189@login_required
190def lista_roles(request):
191 roles = Rol.objects.all()
192 return render(request, 'usuarios/lista_roles.html', {'roles': roles})
193
194@login_required
195def crear_rol(request):
196 if request.method == "POST":
197 nombre = request.POST['nombre']
198 Rol.objects.create(nombre=nombre)
199 messages.success(request, "Rol creado correctamente.")
200 return redirect('lista_roles')
201
202 return render(request, 'usuarios/crear_rol.html')
203
204@login_required
205def editar_rol(request, rol_id):
206 rol = get_object_or_404(Rol, id=rol_id)
207
208 if request.method == "POST":
209 rol.nombre = request.POST['nombre']
210 rol.save()
211 messages.success(request, "Rol actualizado correctamente.")
212 return redirect('lista_roles')
213
214 return render(request, 'usuarios/editar_rol.html', {'rol': rol})
215
216@login_required
217def eliminar_rol(request, rol_id):
218 rol = get_object_or_404(Rol, id=rol_id)
219 rol.delete()
220 messages.success(request, "Rol eliminado correctamente.")
221 return redirect('lista_roles')
222
223
224
225@login_required
226def editar_usuario(request, user_id):
227 usuario = get_object_or_404(Usuario, id=user_id)
228
229 if request.method == "POST":
230 usuario.username = request.POST.get('username').strip()
231 usuario.first_name = request.POST.get('first_name').strip()
232 usuario.last_name = request.POST.get('last_name').strip()
233 usuario.email = request.POST.get('email').strip()
234 rol_id = request.POST.get('rol')
235 usuario.estatus = 'estatus' in request.POST # Checkbox para activar/desactivar usuario
236
237 # Validar si el usuario ya existe con otro ID
238 if Usuario.objects.exclude(id=user_id).filter(username=usuario.username).exists():
239 messages.error(request, "El nombre de usuario ya está en uso por otro usuario.")
240 return redirect('lista_usuarios')
241
242 # Verificar si el rol existe
243 try:
244 usuario.rol = Rol.objects.get(id=rol_id)
245 except Rol.DoesNotExist:
246 messages.error(request, "El rol seleccionado no es válido.")
247 return redirect('lista_usuarios')
248
249 usuario.save()
250 messages.success(request, f"Usuario '{usuario.username}' actualizado correctamente.")
251 return redirect('lista_usuarios')
252
253 roles = Rol.objects.all()
254 return render(request, 'usuarios/editar_usuario.html', {'usuario': usuario, 'roles': roles})
255
256
257@login_required
258def eliminar_usuario(request, user_id):
259 usuario = get_object_or_404(Usuario, id=user_id)
260 usuario.delete()
261 messages.success(request, f"Usuario '{usuario.username}' eliminado correctamente.")
262 return redirect('lista_usuarios')
263
264
265
266# Función para verificar si el usuario es administrador
267def es_admin(user):
268 return user.is_authenticated and user.is_superuser
269
270### RESTRINGIR VISTAS A ADMINISTRADORES ###
271
272@login_required
273@user_passes_test(es_admin, login_url='/dashboard/') # Redirigir si no es admin
274def lista_usuarios(request):
275 usuarios = Usuario.objects.all()
276 roles = Rol.objects.all()
277 return render(request, 'usuarios/lista_usuarios.html', {'usuarios': usuarios, 'roles': roles})
278
279@login_required
280@user_passes_test(es_admin, login_url='/dashboard/')
281def crear_usuario(request):
282 if request.method == "POST":
283 username = request.POST.get('username').strip()
284 first_name = request.POST.get('first_name').strip()
285 last_name = request.POST.get('last_name').strip()
286 email = request.POST.get('email').strip()
287 password = request.POST.get('password')
288 rol_id = request.POST.get('rol')
289
290 if Usuario.objects.filter(username=username).exists():
291 messages.error(request, "El nombre de usuario ya está en uso.")
292 return redirect('lista_usuarios')
293
294 try:
295 rol = Rol.objects.get(id=rol_id)
296 except Rol.DoesNotExist:
297 messages.error(request, "El rol seleccionado no es válido.")
298 return redirect('lista_usuarios')
299
300 nuevo_usuario = Usuario(
301 username=username,
302 first_name=first_name,
303 last_name=last_name,
304 email=email,
305 rol=rol
306 )
307 nuevo_usuario.set_password(password)
308 nuevo_usuario.save()
309
310 messages.success(request, f"Usuario '{username}' creado correctamente.")
311 return redirect('lista_usuarios')
312
313 return redirect('lista_usuarios')
314
315@login_required
316@user_passes_test(es_admin, login_url='/dashboard/')
317def eliminar_usuario(request, user_id):
318 usuario = get_object_or_404(Usuario, id=user_id)
319 usuario.delete()
320 messages.success(request, f"Usuario '{usuario.username}' eliminado correctamente.")
321 return redirect('lista_usuarios')
322
323@login_required
324@user_passes_test(es_admin, login_url='/dashboard/')
325def lista_roles(request):
326 roles = Rol.objects.all()
327 return render(request, 'usuarios/lista_roles.html', {'roles': roles})
328
329@login_required
330@user_passes_test(es_admin, login_url='/dashboard/')
331def crear_rol(request):
332 if request.method == "POST":
333 nombre = request.POST['nombre']
334 Rol.objects.create(nombre=nombre)
335 messages.success(request, "Rol creado correctamente.")
336 return redirect('lista_roles')
337
338 return render(request, 'usuarios/crear_rol.html')
339
340@login_required
341@user_passes_test(es_admin, login_url='/dashboard/')
342def eliminar_rol(request, rol_id):
343 rol = get_object_or_404(Rol, id=rol_id)
344 rol.delete()
345 messages.success(request, "Rol eliminado correctamente.")
346 return redirect('lista_roles')
347
348
349def lista_zonas(request):
350 zonas = Zona.objects.all()
351 return render(request, "usuarios/lista_zonas.html", {"zonas": zonas})
352
353def crear_zona(request):
354 if request.method == "POST":
355 nombre = request.POST["nombre"]
356 Zona.objects.create(nombre=nombre)
357 messages.success(request, "Zona creada correctamente.")
358 return redirect("lista_zonas")
359 return redirect("lista_zonas")
360
361def editar_zona(request, zona_id):
362 zona = get_object_or_404(Zona, id=zona_id)
363 if request.method == "POST":
364 zona.nombre = request.POST["nombre"]
365 zona.save()
366 messages.success(request, "Zona actualizada correctamente.")
367 return redirect("lista_zonas")
368 return redirect("lista_zonas")
369
370def eliminar_zona(request, zona_id):
371 zona = get_object_or_404(Zona, id=zona_id)
372 zona.delete()
373 messages.success(request, "Zona eliminada correctamente.")
374 return redirect("lista_zonas")
375
376
377def lista_avenidas(request):
378 avenidas = Avenida.objects.select_related("zona").order_by("zona_id")
379 zonas = Zona.objects.all() # Enviar zonas al template para el formulario
380
381 return render(request, "usuarios/lista_avenidas.html", {"avenidas": avenidas, "zonas": zonas})
382
383
384def crear_avenida(request):
385 if request.method == "POST":
386 nombre = request.POST["nombre"]
387 zona_id = request.POST["zona"]
388 zona = get_object_or_404(Zona, id=zona_id)
389 Avenida.objects.create(nombre=nombre, zona=zona)
390 messages.success(request, "Avenida creada correctamente.")
391 return redirect("lista_avenidas")
392 return redirect("lista_avenidas")
393
394def editar_avenida(request, avenida_id):
395 avenida = get_object_or_404(Avenida, id=avenida_id)
396 if request.method == "POST":
397 avenida.nombre = request.POST["nombre"]
398 zona_id = request.POST["zona"]
399 avenida.zona = get_object_or_404(Zona, id=zona_id)
400 avenida.save()
401 messages.success(request, "Avenida actualizada correctamente.")
402 return redirect("lista_avenidas")
403 return redirect("lista_avenidas")
404
405def eliminar_avenida(request, avenida_id):
406 avenida = get_object_or_404(Avenida, id=avenida_id)
407 avenida.delete()
408 messages.success(request, "Avenida eliminada correctamente.")
409 return redirect("lista_avenidas")
410
411def lista_clientes(request):
412 clientes_list = Cliente.objects.all().order_by('id')
413
414 query = request.GET.get('q') # Obtiene el término de búsqueda del formulario
415
416 if query:
417 # Filtra clientes por nombre, documento o cualquier otro campo que desees
418 clientes_list = clientes_list.filter(
419 Q(nombre__icontains=query) | Q(documento__icontains=query)
420 )
421
422 paginator = Paginator(clientes_list, 6)
423 page_number = request.GET.get('page')
424 clientes = paginator.get_page(page_number)
425
426 zonas = Zona.objects.all()
427 return render(request, 'usuarios/lista_clientes.html', {'clientes': clientes, 'zonas': zonas})
428
429
430
431def obtener_cliente(request, id):
432 """Devuelve datos del cliente en JSON para edición"""
433 cliente = get_object_or_404(Cliente, id=id)
434 data = {
435 "id": cliente.id,
436 "documento": cliente.documento,
437 "nombre": cliente.nombre,
438 "apellido_paterno": cliente.apellido_paterno,
439 "apellido_materno": cliente.apellido_materno,
440 "fecha_nacimiento": cliente.fecha_nacimiento.strftime("%Y-%m-%d"),
441 "sexo": cliente.sexo,
442 "telefono": cliente.telefono,
443 "email": cliente.email,
444 "direccion": cliente.direccion,
445 "estatus": cliente.estatus,
446 "zona_id": cliente.zona.id,
447 "avenida_id": cliente.avenida.id,
448 }
449 return JsonResponse(data)
450
451def get_avenidas(request, zona_id):
452 avenidas = Avenida.objects.filter(zona_id=zona_id).values('id', 'nombre')
453 return JsonResponse({'avenidas': list(avenidas)})
454
455def get_zonas(request):
456 zonas = list(Zona.objects.values('id', 'nombre'))
457 return JsonResponse({'zonas': zonas})
458
459
460
461@require_http_methods(["GET", "POST"])
462def editar_cliente(request, cliente_id):
463 cliente = get_object_or_404(Cliente, id=cliente_id)
464
465 if request.method == "GET":
466 data = {
467 "id": cliente.id,
468 "documento": cliente.documento,
469 "nombre": cliente.nombre,
470 "apellido_paterno": cliente.apellido_paterno,
471 "apellido_materno": cliente.apellido_materno,
472 "fecha_nacimiento": cliente.fecha_nacimiento.strftime("%Y-%m-%d") if cliente.fecha_nacimiento else None,
473 "sexo": cliente.sexo,
474 "telefono": cliente.telefono,
475 "email": cliente.email,
476 "direccion": cliente.direccion,
477 "estatus": cliente.estatus,
478 "zona_id": cliente.zona.id if cliente.zona else None,
479 "avenida_id": cliente.avenida.id if cliente.avenida else None,
480 }
481 return JsonResponse(data, safe=False)
482
483 elif request.method == "POST":
484 # Lógica para actualizar el cliente
485 return JsonResponse({"message": "Cliente actualizado correctamente"})
486
487 return JsonResponse({"error": "Método no permitido"}, status=405)
488
489
490
491
492@csrf_exempt
493def eliminar_cliente(request, cliente_id):
494 if request.method == "DELETE": # Verifica que el método sea DELETE
495 cliente = get_object_or_404(Cliente, id=cliente_id)
496 cliente.delete()
497 return JsonResponse({"mensaje": "Cliente eliminado correctamente"}, status=200)
498
499 return JsonResponse({"error": "Método no permitido"}, status=405)
500
501
502
503
504
505@csrf_exempt
506def agregar_cliente(request):
507 """ Agrega un cliente y su dirección si se proporciona. """
508 if request.method == "POST":
509 try:
510 form = ClienteForm(request.POST)
511 if form.is_valid():
512 cliente = form.save()
513 direccion_texto = request.POST.get("direccion")
514 if direccion_texto:
515 Direccion.objects.create(cliente=cliente, direccion=direccion_texto)
516 return JsonResponse({"mensaje": "Cliente agregado correctamente", "id": cliente.id}, status=201)
517 return JsonResponse({"error": "Formulario inválido", "detalles": form.errors}, status=400)
518 except Exception as e:
519 return JsonResponse({"error": f"Error interno del servidor: {str(e)}"}, status=500)
520 return JsonResponse({"error": "Método no permitido"}, status=405)
521
522
523
524def cliente_detail(request, cliente_id):
525 cliente = get_object_or_404(Cliente, pk=cliente_id)
526 if request.method == "GET":
527 data = {
528 'id': cliente.id,
529 'documento': cliente.documento,
530 'nombre': cliente.nombre,
531 'apellido_paterno': cliente.apellido_paterno,
532 'apellido_materno': cliente.apellido_materno,
533 'fecha_nacimiento': cliente.fecha_nacimiento.strftime('%Y-%m-%d'),
534 'sexo': cliente.sexo,
535 'telefono': cliente.telefono,
536 'email': cliente.email,
537 'estatus': cliente.estatus,
538 'numero_cliente': cliente.numero_cliente,
539 # Se devuelven todas las direcciones asociadas al cliente, incluyendo los IDs para zona y avenida
540 'direcciones': [
541 {
542 'id': d.id,
543 'zona': d.zona.nombre if d.zona else None,
544 'zona_id': d.zona.id if d.zona else None,
545 'avenida': d.avenida.nombre if d.avenida else None,
546 'avenida_id': d.avenida.id if d.avenida else None,
547 'direccion': d.direccion,
548 } for d in cliente.direcciones.all()
549 ]
550 }
551 return JsonResponse(data)
552 elif request.method == "POST":
553 # Aquí procesa la actualización de los datos del cliente
554 return JsonResponse({'mensaje': 'Cliente actualizado correctamente.'})
555 else:
556 return HttpResponseNotAllowed(['GET', 'POST'])
557
558
559def detalle_cliente(request, cliente_id):
560 cliente = get_object_or_404(Cliente, pk=cliente_id)
561 return render(request, 'cliente_detail.html', {'cliente': cliente})
562
563
564
565def detalle_cliente_html(request, cliente_id):
566 # Obtener el cliente (y sus direcciones) como ya lo haces en cliente_detail
567 cliente = get_object_or_404(Cliente, pk=cliente_id)
568 return render(request, 'usuarios/detalle_cliente.html', {'cliente': cliente})
569
570
571
572# --- Agregado de Reportes y Generación de PDF ---
573def generar_pdf_clientes(request):
574 response = HttpResponse(content_type='application/pdf')
575 response['Content-Disposition'] = 'attachment; filename="reporte_clientes.pdf"'
576 pdf = canvas.Canvas(response, pagesize=letter)
577 pdf.setTitle("Reporte de Clientes")
578 pdf.setFont("Helvetica-Bold", 14)
579 pdf.drawString(200, 750, "Reporte de Clientes")
580 pdf.setFont("Helvetica", 10)
581 clientes = Cliente.objects.all()
582 y = 720
583 for cliente in clientes:
584 pdf.drawString(50, y, f"{cliente.documento} - {cliente.nombre} - {cliente.telefono} - {cliente.email}")
585 y -= 20
586 pdf.showPage()
587 pdf.save()
588 return response
589
590
591# Vista para listar servicios
592def lista_servicios(request):
593 servicios = Servicio.objects.all()
594 return render(request, 'usuarios/lista_servicios.html', {'servicios': servicios})
595
596# Vista para agregar un servicio
597def agregar_servicio(request):
598 if request.method == "POST":
599 nombre = request.POST.get("nombre")
600 costo = request.POST.get("costo")
601
602 if nombre and costo:
603 Servicio.objects.create(nombre=nombre, costo=int(costo))
604 messages.success(request, "Servicio agregado correctamente")
605 return redirect("servicios") # Redirige a la lista de servicios
606
607 return render(request, "usuarios/lista_servicios.html")
608
609# Vista para editar un servicio
610def editar_servicio(request, servicio_id):
611 servicio = get_object_or_404(Servicio, id=servicio_id)
612
613 if request.method == "GET":
614 # Retornar datos del servicio en formato JSON
615 return JsonResponse({
616 "id": servicio.id,
617 "nombre": servicio.nombre,
618 "costo": servicio.costo
619 })
620
621 elif request.method == "POST":
622 try:
623 servicio.nombre = request.POST.get("nombre")
624 servicio.costo = int(request.POST.get("costo"))
625 servicio.save()
626 messages.success(request, "Servicio actualizado correctamente")
627 return JsonResponse({"mensaje": "Servicio actualizado correctamente"})
628 except Exception as e:
629 return JsonResponse({"error": f"Error al actualizar el servicio: {str(e)}"}, status=400)
630
631 return JsonResponse({"error": "Método no permitido"}, status=405)
632
633
634# Vista para eliminar un servicio
635def eliminar_servicio(request, servicio_id):
636 servicio = get_object_or_404(Servicio, id=servicio_id)
637 servicio.delete()
638 messages.success(request, "Servicio eliminado correctamente")
639 return JsonResponse({"mensaje": "Servicio eliminado correctamente"})
640
641
642
643# Vista para listar contratos
644def lista_contratos(request):
645 contratos = Contrato.objects.all()
646 form = ContratoForm()
647 return render(request, "usuarios/lista_contratos.html", {"contratos": contratos, "form": form})
648
649
650# Vista para generar número de abonado único
651def generar_numero_abonado():
652 return "C" + str(random.randint(100000, 999999))
653
654def obtener_servicio(request, servicio_id):
655 """ Obtiene información de un servicio específico """
656 try:
657 servicio = get_object_or_404(Servicio, pk=servicio_id)
658 return JsonResponse({"id": servicio.id, "nombre": servicio.nombre, "costo": servicio.costo})
659 except Exception as e:
660 return JsonResponse({'error': f'Ocurrió un error al obtener el servicio: {e}'}, status=500)
661
662
663
664
665
666
667
668# Vista para obtener los datos de un contrato
669def obtener_contrato(request, id):
670 try:
671 contrato = get_object_or_404(Contrato, id=id)
672
673 # Construir el nombre completo correctamente
674 cliente = contrato.cliente
675 cliente_nombre = f"{cliente.nombre} {cliente.apellido_paterno} {cliente.apellido_materno or ''}".strip()
676
677 return JsonResponse({
678 "success": True,
679 "contrato": {
680 "id": contrato.id,
681 "cliente": cliente.id,
682 "cliente_nombre": cliente_nombre, # ✅ Usa apellido_paterno y apellido_materno
683 "numero_abonado": contrato.numero_abonado,
684 "descripcion": contrato.descripcion,
685 "total": contrato.total
686 }
687 })
688 except Exception as e:
689 return JsonResponse({"success": False, "message": f"Error en el servidor: {str(e)}"}, status=500)
690
691
692# Vista para editar un registrar_contrato
693@csrf_exempt
694def obtener_cliente(request, cliente_id):
695 """ Devuelve los datos de un cliente en formato JSON. """
696 cliente = get_object_or_404(Cliente, id=cliente_id)
697 data = {
698 "id": cliente.id,
699 "documento": cliente.documento,
700 "nombre": cliente.nombre,
701 "apellido_paterno": cliente.apellido_paterno,
702 "apellido_materno": cliente.apellido_materno,
703 "telefono": cliente.telefono,
704 "email": cliente.email,
705 "direccion": cliente.direccion,
706 "estatus": cliente.estatus,
707 }
708 return JsonResponse(data)
709
710@csrf_exempt
711def editar_cliente(request, cliente_id):
712 """ Actualiza un cliente existente. """
713 if request.method == "POST":
714 try:
715 cliente = get_object_or_404(Cliente, id=cliente_id)
716 for key, value in request.POST.items():
717 setattr(cliente, key, value)
718 cliente.save()
719 return JsonResponse({"mensaje": "Cliente actualizado correctamente"}, status=200)
720 except Exception as e:
721 return JsonResponse({"error": f"Error interno: {str(e)}"}, status=500)
722 return JsonResponse({"error": "Método no permitido"}, status=405)
723
724
725
726
727
728
729
730# Vista para eliminar contrato
731def eliminar_contrato(request, id):
732 if request.method == "DELETE":
733 contrato = get_object_or_404(Contrato, id=id)
734 contrato.delete()
735 return JsonResponse({"success": True})
736 return JsonResponse({"success": False, "error": "Método no permitido"}, status=405)
737
738
739# Buscar clientes por nombre o documento
740def buscar_clientes(request):
741 query = request.GET.get("query", "").strip()
742 if query:
743 clientes = Cliente.objects.filter(nombre__icontains=query) | Cliente.objects.filter(documento__icontains=query)
744 data = list(clientes.values("id", "nombre", "documento"))
745 return JsonResponse(data, safe=False)
746 return JsonResponse([], safe=False)
747
748
749
750
751
752
753@csrf_exempt
754def agregar_contrato(request):
755 """ Agrega un nuevo contrato con sus servicios asociados. """
756 if request.method == "POST":
757 form = ContratoForm(request.POST)
758 if form.is_valid():
759 contrato = form.save(commit=False)
760 contrato.total = contrato.calcular_total()
761 contrato.save()
762 form.save_m2m()
763 return JsonResponse({"mensaje": "Contrato agregado correctamente"}, status=201)
764 return JsonResponse({"error": "Formulario inválido", "detalles": form.errors}, status=400)
765 return JsonResponse({"error": "Método no permitido"}, status=405)
766
767@csrf_exempt
768def editar_contrato(request, id):
769 """ Edita los detalles de un contrato existente. """
770 contrato = get_object_or_404(Contrato, id=id)
771 if request.method == "POST":
772 try:
773 data = json.loads(request.body.decode("utf-8"))
774 for key, value in data.items():
775 setattr(contrato, key, value)
776 contrato.save()
777 return JsonResponse({"mensaje": "Contrato actualizado correctamente"}, status=200)
778 except Exception as e:
779 return JsonResponse({"error": f"Error interno: {str(e)}"}, status=500)
780 return JsonResponse({"error": "Método no permitido"}, status=405)
781
782
783
784def generar_numero_abonado(request):
785 """
786 Genera un número de abonado único basado en el último contrato registrado.editar_cliente
787 """
788 ultimo_contrato = Contrato.objects.order_by('-numero_abonado').first()
789 nuevo_numero = (ultimo_contrato.numero_abonado + 1) if ultimo_contrato and ultimo_contrato.numero_abonado else 1000
790 return JsonResponse({"numero_abonado": nuevo_numero})
791
792
793def get_zonas(request):
794 zonas = list(Zona.objects.values('id', 'nombre'))
795 return JsonResponse({'zonas': zonas})
796
797def obtener_avenidas(request):
798 """ Devuelve la lista de avenidas filtradas por zona. """
799 zona_id = request.GET.get("zona_id")
800 avenidas = list(Avenida.objects.filter(zona_id=zona_id).values("id", "nombre")) if zona_id else []
801 return JsonResponse({"avenidas": avenidas})
802
803
804
805
806
807def obtener_direcciones_cliente(request, cliente_id):
808 try:
809 direcciones = Direccion.objects.filter(cliente_id=cliente_id).values("id", "direccion")
810 return JsonResponse({"direcciones": list(direcciones)})
811 except Exception as e:
812 print(f"Error al obtener direcciones: {e}") # Depuración
813 return JsonResponse({"error": "Ocurrió un error al obtener las direcciones."}, status=500)
814
815
816def obtener_estado_cliente(request, cliente_id):
817 try:
818 cliente = Cliente.objects.get(id=cliente_id)
819 return JsonResponse({'estatus': cliente.estatus}) # Ajusta según el nombre del campo en el modelo
820 except Cliente.DoesNotExist:
821 return JsonResponse({'error': 'Cliente no encontrado'}, status=404)