update on the appointment and lead and more

This commit is contained in:
gitea 2025-02-18 13:32:40 +00:00
parent 491d60b34f
commit 87cac68e8b
11 changed files with 157 additions and 29 deletions

View File

@ -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):

View File

@ -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

View File

@ -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,
),
]

View File

@ -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'),
),
]

View File

@ -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),
),
]

View File

@ -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),
),
]

View File

@ -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"))

View File

@ -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}."
)

View File

@ -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

View File

@ -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"""

View File

@ -201,7 +201,7 @@
<a href="{% url 'lead_update' lead.id %}" class="dropdown-item text-success-dark">{% trans "Edit" %}</a>
<a href="{% url 'send_lead_email' lead.id %}" class="dropdown-item text-success-dark">{% trans "Send Email" %}</a>
<a href="{% url 'schedule_lead' lead.id %}" class="dropdown-item text-success-dark">{% trans "Set Schedule" %}</a>
{% if not lead.is_converted %}
{% if not lead.opportunity %}
<a href="{% url 'lead_convert' lead.id %}" class="dropdown-item text-success-dark">{% trans "Convert To Opportunity" %}</a>
{% endif %}
<div class="dropdown-divider"></div>