Merge branch 'main' of http://10.10.1.136:3000/ismail/haikal into frontend
This commit is contained in:
commit
bc1b333e3e
@ -1957,6 +1957,31 @@ class Opportunity(models.Model):
|
|||||||
)
|
)
|
||||||
loss_reason = models.CharField(max_length=255, blank=True, null=True)
|
loss_reason = models.CharField(max_length=255, blank=True, null=True)
|
||||||
|
|
||||||
|
def get_notes(self):
|
||||||
|
return self._get_filter(Notes)
|
||||||
|
def get_activities(self):
|
||||||
|
return self._get_filter(Activity)
|
||||||
|
|
||||||
|
def get_tasks(self):
|
||||||
|
return self._get_filter(Tasks)
|
||||||
|
|
||||||
|
def get_schedules(self):
|
||||||
|
return self.lead.get_all_schedules().filter(
|
||||||
|
scheduled_at__gt=timezone.now()
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_emails(self):
|
||||||
|
return self._get_filter(Email)
|
||||||
|
|
||||||
|
def _get_filter(self,Model):
|
||||||
|
objects = Model.objects.filter(
|
||||||
|
content_type__model="opportunity", object_id=self.id
|
||||||
|
)
|
||||||
|
lead_objects = Model.objects.filter(
|
||||||
|
content_type__model="lead", object_id=self.lead.id
|
||||||
|
)
|
||||||
|
objects = objects.union(lead_objects)
|
||||||
|
return objects
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if self.amount:
|
if self.amount:
|
||||||
|
|||||||
@ -125,7 +125,7 @@ urlpatterns = [
|
|||||||
name="add_note",
|
name="add_note",
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
"crm/<str:content_type>/<int:pk>/update-task/",
|
"crm/<int:pk>/update-task/",
|
||||||
views.update_task,
|
views.update_task,
|
||||||
name="update_task",
|
name="update_task",
|
||||||
),
|
),
|
||||||
|
|||||||
@ -5542,6 +5542,7 @@ class OpportunityDetailView(LoginRequiredMixin, DetailView):
|
|||||||
form.fields["stage"].widget.attrs["hx-get"] = url
|
form.fields["stage"].widget.attrs["hx-get"] = url
|
||||||
form.fields["stage"].initial = self.object.stage
|
form.fields["stage"].initial = self.object.stage
|
||||||
context["status_form"] = form
|
context["status_form"] = form
|
||||||
|
|
||||||
context["lead_notes"] = models.Notes.objects.filter(
|
context["lead_notes"] = models.Notes.objects.filter(
|
||||||
content_type__model="lead", object_id=self.object.id
|
content_type__model="lead", object_id=self.object.id
|
||||||
).order_by("-created")
|
).order_by("-created")
|
||||||
@ -8151,14 +8152,8 @@ def add_task(request, content_type, slug):
|
|||||||
return redirect(f"{content_type}_detail", slug=slug)
|
return redirect(f"{content_type}_detail", slug=slug)
|
||||||
|
|
||||||
|
|
||||||
def update_task(request,content_type, pk):
|
def update_task(request, pk):
|
||||||
try:
|
|
||||||
model = apps.get_model(f"inventory.{content_type}")
|
|
||||||
except LookupError:
|
|
||||||
raise Http404("Model not found")
|
|
||||||
|
|
||||||
task = get_object_or_404(models.Tasks, pk=pk)
|
task = get_object_or_404(models.Tasks, pk=pk)
|
||||||
obj = get_object_or_404(model, pk=task.content_object.id)
|
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
task.completed = False if task.completed else True
|
task.completed = False if task.completed else True
|
||||||
|
|||||||
@ -77,7 +77,7 @@
|
|||||||
<h4 class="mb-5 d-flex align-items-center"><span class="d-inline-block lh-sm me-1" data-feather="link" style="height:16px;width:16px;"></span> {{ _("Upcoming Events")}}</h4>
|
<h4 class="mb-5 d-flex align-items-center"><span class="d-inline-block lh-sm me-1" data-feather="link" style="height:16px;width:16px;"></span> {{ _("Upcoming Events")}}</h4>
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
{% for event in upcoming_events.schedules %}
|
{% for event in opportunity.get_schedules %}
|
||||||
<table class="table table-sm table-borderless mb-4">
|
<table class="table table-sm table-borderless mb-4">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -359,44 +359,7 @@
|
|||||||
<button class="btn btn-phoenix-primary btn-sm" type="button" data-bs-toggle="modal" data-bs-target="#activityModal"><span class="fas fa-plus me-1"></span>{{ _("Add Activity") }}</button>
|
<button class="btn btn-phoenix-primary btn-sm" type="button" data-bs-toggle="modal" data-bs-target="#activityModal"><span class="fas fa-plus me-1"></span>{{ _("Add Activity") }}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% for activity in lead_activities %}
|
{% for activity in opportunity.get_activities %}
|
||||||
<div class="border-bottom border-translucent py-4">
|
|
||||||
<div class="d-flex">
|
|
||||||
<div class="d-flex bg-primary-subtle rounded-circle flex-center me-3 bg-primary-subtle" style="width:25px; height:25px">
|
|
||||||
{% if activity.activity_type == "call" %}
|
|
||||||
<span class="fa-solid fa-phone text-warning fs-8"></span>
|
|
||||||
{% elif activity.activity_type == "email" %}
|
|
||||||
<span class="fa-solid fa-envelope text-info-light fs-8"></span>
|
|
||||||
{% elif activity.activity_type == "meeting" %}
|
|
||||||
<span class="fa-solid fa-users text-danger fs-8"></span>
|
|
||||||
{% elif activity.activity_type == "whatsapp" %}
|
|
||||||
<span class="fab fa-whatsapp text-success-dark fs-7"></span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="flex-1">
|
|
||||||
<div class="d-flex justify-content-between flex-column flex-xl-row mb-2 mb-sm-0">
|
|
||||||
<div class="flex-1 me-2">
|
|
||||||
<h5 class="text-body-highlight lh-sm"></h5>
|
|
||||||
<p class="fs-9 mb-0">{{activity.notes}}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="d-flex justify-content-between flex-column flex-xl-row mb-2 mb-sm-0">
|
|
||||||
<div class="flex-1 me-2">
|
|
||||||
<h5 class="text-body-highlight lh-sm"></h5>
|
|
||||||
{% if request.user.email == activity.created_by %}
|
|
||||||
<p class="fs-9 mb-0">by <a class="ms-1" href="#!">You</a></p>
|
|
||||||
{% else %}
|
|
||||||
<p class="fs-9 mb-0">by<a class="ms-1" href="#!">{{activity.created_by}}</a></p>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="fs-9"><span class="fa-regular fa-calendar-days text-primary me-2"></span><span class="fw-semibold">{{activity.created|naturalday|capfirst}}</span></div>
|
|
||||||
</div>
|
|
||||||
<p class="fs-9 mb-0"></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
{% for activity in activities %}
|
|
||||||
<div class="border-bottom border-translucent py-4">
|
<div class="border-bottom border-translucent py-4">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<div class="d-flex bg-primary-subtle rounded-circle flex-center me-3 bg-primary-subtle" style="width:25px; height:25px">
|
<div class="d-flex bg-primary-subtle rounded-circle flex-center me-3 bg-primary-subtle" style="width:25px; height:25px">
|
||||||
@ -443,16 +406,7 @@
|
|||||||
</form>
|
</form>
|
||||||
<div class="row gy-4 note-list">
|
<div class="row gy-4 note-list">
|
||||||
<div class="col-12 col-xl-auto flex-1">
|
<div class="col-12 col-xl-auto flex-1">
|
||||||
{% for note in lead_notes %}
|
{% for note in opportunity.get_notes %}
|
||||||
<div class="border-2 border-dashed mb-4 pb-4 border-bottom border-translucent">
|
|
||||||
<p class="mb-1 text-body-highlight">{{ note.note }}</p>
|
|
||||||
<div class="d-flex">
|
|
||||||
<div class="fs-9 text-body-tertiary text-opacity-85"><span class="fa-solid fa-clock me-2"></span><span class="fw-semibold me-1">{{note.created|naturaltime|capfirst}}</span></div>
|
|
||||||
<p class="fs-9 mb-0 text-body-tertiary text-opacity-85">by<a class="ms-1 fw-semibold" href="#!">{{note.created_by}}</a></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
{% for note in notes %}
|
|
||||||
<div class="border-2 border-dashed mb-4 pb-4 border-bottom border-translucent">
|
<div class="border-2 border-dashed mb-4 pb-4 border-bottom border-translucent">
|
||||||
<p class="mb-1 text-body-highlight">{{ note.note }}</p>
|
<p class="mb-1 text-body-highlight">{{ note.note }}</p>
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
@ -512,6 +466,7 @@
|
|||||||
<a href="{% url 'schedule_lead' opportunity.lead.slug %}" class="btn btn-primary"><span class="fa-solid fa-plus me-2"></span>Add Call</a>
|
<a href="{% url 'schedule_lead' opportunity.lead.slug %}" class="btn btn-primary"><span class="fa-solid fa-plus me-2"></span>Add Call</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<pre>{{opportunity.get_all_notes}}</pre>
|
||||||
<div class="border-top border-bottom border-translucent" id="leadDetailsTable" data-list='{"valueNames":["name","description","create_date","create_by","last_activity"],"page":5,"pagination":true}'>
|
<div class="border-top border-bottom border-translucent" id="leadDetailsTable" data-list='{"valueNames":["name","description","create_date","create_by","last_activity"],"page":5,"pagination":true}'>
|
||||||
<div class="table-responsive scrollbar mx-n1 px-1">
|
<div class="table-responsive scrollbar mx-n1 px-1">
|
||||||
<table class="table fs-9 mb-0">
|
<table class="table fs-9 mb-0">
|
||||||
@ -646,11 +601,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="list" id="all-tasks-table-body">
|
<tbody class="list" id="all-tasks-table-body">
|
||||||
{% for task in lead_tasks %}
|
{% for task in opportunity.get_tasks %}
|
||||||
{% include "partials/task.html" with task=task content_type="lead" %}
|
{% include "partials/task.html" %}
|
||||||
{% endfor %}
|
|
||||||
{% for task in tasks %}
|
|
||||||
{% include "partials/task.html" with task=task content_type="opportunity" %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<tr id="task-{{task.pk}}" class="hover-actions-trigger btn-reveal-trigger position-static {% if task.completed %}completed-task{% endif %}">
|
<tr id="task-{{task.pk}}" class="hover-actions-trigger btn-reveal-trigger position-static {% if task.completed %}completed-task{% endif %}">
|
||||||
<td class="fs-9 align-middle px-0 py-3">
|
<td class="fs-9 align-middle px-0 py-3">
|
||||||
<div class="form-check mb-0 fs-8">
|
<div class="form-check mb-0 fs-8">
|
||||||
<input class="form-check-input" type="checkbox" hx-post="{% url 'update_task' content_type=content_type pk=task.pk %}" hx-trigger="change" hx-swap="outerHTML" hx-target="#task-{{task.pk}}" />
|
<input class="form-check-input" {% if task.completed %}checked{% endif %} type="checkbox" hx-post="{% url 'update_task' task.pk %}" hx-trigger="change" hx-swap="outerHTML" hx-target="#task-{{task.pk}}" />
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="subject order align-middle white-space-nowrap py-2 ps-0"><a class="fw-semibold text-primary" href="">{{task.title}}</a>
|
<td class="subject order align-middle white-space-nowrap py-2 ps-0"><a class="fw-semibold text-primary" href="">{{task.title}}</a>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user