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