From 87cac68e8b1615adfeafe2450d5be34679df90fd Mon Sep 17 00:00:00 2001 From: gitea Date: Tue, 18 Feb 2025 13:32:40 +0000 Subject: [PATCH] update on the appointment and lead and more --- inventory/forms.py | 12 ++-- inventory/middleware.py | 19 ++++-- ...34_remove_staff_user_staff_staff_member.py | 25 ++++++++ .../0035_alter_staff_staff_member.py | 20 ++++++ .../0036_alter_schedule_scheduled_type.py | 18 ++++++ .../0037_alter_schedule_scheduled_type.py | 18 ++++++ inventory/models.py | 4 +- inventory/signals.py | 2 +- inventory/utils.py | 4 +- inventory/views.py | 62 ++++++++++++++----- templates/crm/leads/lead_list.html | 2 +- 11 files changed, 157 insertions(+), 29 deletions(-) create mode 100644 inventory/migrations/0034_remove_staff_user_staff_staff_member.py create mode 100644 inventory/migrations/0035_alter_staff_staff_member.py create mode 100644 inventory/migrations/0036_alter_schedule_scheduled_type.py create mode 100644 inventory/migrations/0037_alter_schedule_scheduled_type.py diff --git a/inventory/forms.py b/inventory/forms.py index f3a02770..8f2fd0fe 100644 --- a/inventory/forms.py +++ b/inventory/forms.py @@ -85,7 +85,12 @@ class StaffForm(forms.ModelForm): label="Email", widget=forms.EmailInput(attrs={"class": "form-control form-control-sm"}), ) - + + service_offered = forms.ModelMultipleChoiceField( + label="Services Offered", + widget=forms.CheckboxSelectMultiple(attrs={"class": "form-check-input"}), + queryset=Service.objects.all(), + required=False,) class Meta: model = Staff fields = ["name", "arabic_name", "phone_number", "staff_type"] @@ -754,11 +759,10 @@ class LeadForm(forms.ModelForm): class ScheduleForm(forms.ModelForm): scheduled_at = forms.DateTimeField( widget=DateTimeInput(attrs={"type": "datetime-local"}) - ) - + ) class Meta: model = Schedule - fields = ["purpose", "scheduled_type", "scheduled_at", "duration", "notes"] + fields = ["purpose", "scheduled_type", "scheduled_at", "duration", "notes",] class NoteForm(forms.ModelForm): diff --git a/inventory/middleware.py b/inventory/middleware.py index b321c5a6..665d9d00 100644 --- a/inventory/middleware.py +++ b/inventory/middleware.py @@ -23,7 +23,6 @@ class LogUserActivityMiddleware: action=action, timestamp=timezone.now() ) - return response def get_client_ip(self, request): @@ -42,13 +41,25 @@ class InjectParamsMiddleware: # request.entity = request.user.dealer.entity request.dealer = get_user_type(request) except Exception as e: - pass - + pass response = self.get_response(request) - return response +class InjectDealerMiddleware: + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): + try: + dealer = get_user_type(request) + request.user.dealer = dealer + + except Exception as e: + pass + response = self.get_response(request) + return response + # class OTPVerificationMiddleware: # def __init__(self, get_response): # self.get_response = get_response diff --git a/inventory/migrations/0034_remove_staff_user_staff_staff_member.py b/inventory/migrations/0034_remove_staff_user_staff_staff_member.py new file mode 100644 index 00000000..e1271f46 --- /dev/null +++ b/inventory/migrations/0034_remove_staff_user_staff_staff_member.py @@ -0,0 +1,25 @@ +# Generated by Django 4.2.17 on 2025-02-18 09:13 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('appointment', '0001_initial'), + ('inventory', '0033_alter_schedule_scheduled_by'), + ] + + operations = [ + migrations.RemoveField( + model_name='staff', + name='user', + ), + migrations.AddField( + model_name='staff', + name='staff_member', + field=models.OneToOneField(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='staff_member', to='appointment.staffmember'), + preserve_default=False, + ), + ] diff --git a/inventory/migrations/0035_alter_staff_staff_member.py b/inventory/migrations/0035_alter_staff_staff_member.py new file mode 100644 index 00000000..517857ce --- /dev/null +++ b/inventory/migrations/0035_alter_staff_staff_member.py @@ -0,0 +1,20 @@ +# Generated by Django 4.2.17 on 2025-02-18 09:31 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('appointment', '0001_initial'), + ('inventory', '0034_remove_staff_user_staff_staff_member'), + ] + + operations = [ + migrations.AlterField( + model_name='staff', + name='staff_member', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='staff', to='appointment.staffmember'), + ), + ] diff --git a/inventory/migrations/0036_alter_schedule_scheduled_type.py b/inventory/migrations/0036_alter_schedule_scheduled_type.py new file mode 100644 index 00000000..0ad89164 --- /dev/null +++ b/inventory/migrations/0036_alter_schedule_scheduled_type.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.17 on 2025-02-18 13:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('inventory', '0035_alter_staff_staff_member'), + ] + + operations = [ + migrations.AlterField( + model_name='schedule', + name='scheduled_type', + field=models.CharField(choices=[('Call', 'Call'), ('Meeting Service', 'Meeting Service'), ('Email', 'Email')], default='Call', max_length=200), + ), + ] diff --git a/inventory/migrations/0037_alter_schedule_scheduled_type.py b/inventory/migrations/0037_alter_schedule_scheduled_type.py new file mode 100644 index 00000000..7098d1ae --- /dev/null +++ b/inventory/migrations/0037_alter_schedule_scheduled_type.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.17 on 2025-02-18 13:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('inventory', '0036_alter_schedule_scheduled_type'), + ] + + operations = [ + migrations.AlterField( + model_name='schedule', + name='scheduled_type', + field=models.CharField(choices=[('Call', 'Call'), ('Meeting', 'Meeting'), ('Email', 'Email')], default='Call', max_length=200), + ), + ] diff --git a/inventory/models.py b/inventory/models.py index a5bb120d..9e4d5eec 100644 --- a/inventory/models.py +++ b/inventory/models.py @@ -18,7 +18,7 @@ from .mixins import LocalizedNameMixin from django_ledger.models import EntityModel, ItemModel,EstimateModel,InvoiceModel from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType - +from appointment.models import StaffMember class DealerUserManager(UserManager): def create_user_with_dealer( self, @@ -925,7 +925,7 @@ class StaffTypes(models.TextChoices): class Staff(models.Model, LocalizedNameMixin): - user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="staff") + staff_member = models.OneToOneField(StaffMember, on_delete=models.CASCADE, related_name="staff") dealer = models.ForeignKey(Dealer, on_delete=models.CASCADE, related_name="staff") name = models.CharField(max_length=255, verbose_name=_("Name")) arabic_name = models.CharField(max_length=255, verbose_name=_("Arabic Name")) diff --git a/inventory/signals.py b/inventory/signals.py index 4e2617cc..67e646f0 100644 --- a/inventory/signals.py +++ b/inventory/signals.py @@ -810,7 +810,7 @@ def track_lead_status_change(sender, instance, **kwargs): def notify_assigned_staff(sender, instance, created, **kwargs): if instance.staff: # Check if the lead is assigned models.Notification.objects.create( - user=instance.staff.user, + user=instance.staff.staff_member.user, message=f"You have been assigned a new lead: {instance.full_name}." ) diff --git a/inventory/utils.py b/inventory/utils.py index b95de92b..7f7cbe54 100644 --- a/inventory/utils.py +++ b/inventory/utils.py @@ -99,8 +99,8 @@ def get_user_type(request): dealer = "" if hasattr(request.user, "dealer"): dealer = request.user.dealer - elif hasattr(request.user, "staff"): - dealer = request.user.staff.dealer + elif hasattr(request.user, "staffmember"): + dealer = request.user.staffmember.staff.dealer return dealer diff --git a/inventory/views.py b/inventory/views.py index 2bf225bf..c3e4eee5 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -1879,17 +1879,23 @@ class UserCreateView( def form_valid(self, form): dealer = get_user_type(self.request) - form.instance.dealer = dealer + email = form.cleaned_data["email"] password = "Tenhal@123" - user = User.objects.create_user(username=email, email=email, password=password) - + user = User.objects.create_user(username=form.cleaned_data["name"], email=email, password=password) + user.is_staff = True + user.save() + staff_member = StaffMember.objects.create(user=user) + services = form.cleaned_data["service_offered"] + if services: + for service in services: + staff_member.services_offered.add(service) staff = form.save(commit=False) - staff.user = user + staff.staff_member = staff_member + staff.dealer = dealer staff.save() - return super().form_valid(form) - + class UserUpdateView( LoginRequiredMixin, @@ -1907,7 +1913,31 @@ class UserUpdateView( kwargs["instance"] = self.get_object() # Pass the Staff instance to the form return kwargs - + def get_form(self, form_class = None): + form = super().get_form(form_class) + form.fields['email'].disabled = True + return form + def get_initial(self): + initial = super().get_initial() + initial['service_offered'] = self.object.staff_member.services_offered.all() + initial['email'] = self.object.staff_member.user.email + return initial + def form_valid(self, form): + services = form.cleaned_data["service_offered"] + if not services: + self.object.staff_member.services_offered.clear() + else: + for service in services: + self.object.staff_member.services_offered.add(service) + + staff = form.save(commit=False) + staff.name = form.cleaned_data["name"] + staff.arabic_name = form.cleaned_data["arabic_name"] + staff.phone_number = form.cleaned_data["phone_number"] + staff.staff_type = form.cleaned_data["staff_type"] + staff.save() + return super().form_valid(form) + def UserDeleteview(request, pk): user = get_object_or_404(models.Staff, pk=pk) user.delete() @@ -3205,8 +3235,8 @@ def lead_create(request): dealer = get_user_type(request) instance.dealer = dealer staff = None - if hasattr(request.user, "staff"): - staff = request.user.staff + if hasattr(request.user, "staffmember"): + staff = request.user.staffmember.staff instance.staff = staff # creating customer in ledger @@ -3313,7 +3343,7 @@ def delete_note(request, pk): def lead_convert(request, pk): lead = get_object_or_404(models.Lead, pk=pk) dealer = get_user_type(request) - if lead.is_converted: + if hasattr(lead, "opportunity"): messages.error(request, "Lead is already converted to customer.") else: customer = lead.convert_to_customer(dealer.entity) @@ -3323,7 +3353,7 @@ def lead_convert(request, pk): @login_required def schedule_lead(request, pk): - if not request.user.is_staff: + if not hasattr(request.user,"staffmember"): messages.error(request, "You do not have permission to schedule lead.") return redirect("lead_list") dealer = get_user_type(request) @@ -3342,7 +3372,8 @@ def schedule_lead(request, pk): if not service: messages.error(request, "Service not found!") return redirect("lead_list") - staff_member = StaffMember.objects.filter(user=request.user).first() + # staff_member = StaffMember.objects.filter(user=request.user).first() + staff_member = request.user.staffmember appointment_request = AppointmentRequest.objects.create( date=instance.scheduled_at.date(), @@ -3351,7 +3382,7 @@ def schedule_lead(request, pk): service=service, staff_member=staff_member, ) - client = get_object_or_404(User, email=lead.email) + client = get_object_or_404(User, email=lead.email) # Create Appointment Appointment.objects.create( client=client, @@ -3389,7 +3420,7 @@ def send_lead_email(request, pk,email_pk=None): if request.method == "POST": email_pk = request.POST.get('email_pk') - if email_pk != "None" or email_pk != "": + if email_pk not in [None,"None",""]: email = get_object_or_404(models.Email, pk=int(email_pk)) email.status = models.EmailStatus.SENT email.save() @@ -3401,7 +3432,8 @@ def send_lead_email(request, pk,email_pk=None): request.POST.get("subject"), request.POST.get("message"), ) - models.Activity.objects.create(content_object=lead, notes="Email sent",created_by=request.user,activity_type=models.ActionChoices.EMAIL) + dealer = get_user_type(request) + models.Activity.objects.create(dealer=dealer,content_object=lead, notes="Email sent",created_by=request.user,activity_type=models.ActionChoices.EMAIL) messages.success(request, _("Email sent successfully!")) return redirect("lead_list") msg = f""" diff --git a/templates/crm/leads/lead_list.html b/templates/crm/leads/lead_list.html index e41e074d..b26d0b01 100644 --- a/templates/crm/leads/lead_list.html +++ b/templates/crm/leads/lead_list.html @@ -201,7 +201,7 @@ {% trans "Edit" %} {% trans "Send Email" %} {% trans "Set Schedule" %} - {% if not lead.is_converted %} + {% if not lead.opportunity %} {% trans "Convert To Opportunity" %} {% endif %}