update invoice
This commit is contained in:
parent
4af455510f
commit
b47231ed2a
@ -2002,7 +2002,13 @@ class Opportunity(models.Model):
|
|||||||
return self.lead.get_calls()
|
return self.lead.get_calls()
|
||||||
|
|
||||||
def get_schedules(self):
|
def get_schedules(self):
|
||||||
|
# qs = Schedule.objects.filter(
|
||||||
|
# dealer=self.dealer,
|
||||||
|
# content_type__model__in=["lead"], object_id=self.object.id,
|
||||||
|
# scheduled_by=self.request.user
|
||||||
|
# )
|
||||||
return (
|
return (
|
||||||
|
|
||||||
self.lead.get_all_schedules()
|
self.lead.get_all_schedules()
|
||||||
.filter(scheduled_at__gt=timezone.now())
|
.filter(scheduled_at__gt=timezone.now())
|
||||||
.order_by("scheduled_at")
|
.order_by("scheduled_at")
|
||||||
@ -2323,6 +2329,14 @@ class Payment(models.Model):
|
|||||||
max_length=100, null=True, blank=True, verbose_name=_("reference number")
|
max_length=100, null=True, blank=True, verbose_name=_("reference number")
|
||||||
)
|
)
|
||||||
payment_date = models.DateField(auto_now_add=True, verbose_name=_("date"))
|
payment_date = models.DateField(auto_now_add=True, verbose_name=_("date"))
|
||||||
|
invoice = models.ForeignKey(
|
||||||
|
InvoiceModel,
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name="payments",
|
||||||
|
verbose_name=_("invoice"),
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("payment")
|
verbose_name = _("payment")
|
||||||
@ -2983,3 +2997,49 @@ class ExtraInfo(models.Model):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"ExtraInfo for {self.content_object} ({self.content_type})"
|
return f"ExtraInfo for {self.content_object} ({self.content_type})"
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_sale_orders(cls, staff=None, is_dealer=False):
|
||||||
|
if not staff and not is_dealer:
|
||||||
|
return []
|
||||||
|
|
||||||
|
content_type = ContentType.objects.get_for_model(EstimateModel)
|
||||||
|
related_content_type = ContentType.objects.get_for_model(Staff)
|
||||||
|
|
||||||
|
if is_dealer:
|
||||||
|
qs = cls.objects.filter(
|
||||||
|
content_type=content_type,
|
||||||
|
related_content_type=related_content_type,
|
||||||
|
related_object_id__isnull=False
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
qs = cls.objects.filter(
|
||||||
|
content_type=content_type,
|
||||||
|
related_content_type=related_content_type,
|
||||||
|
related_object_id=staff.pk
|
||||||
|
)
|
||||||
|
|
||||||
|
return [x.content_object.sale_orders.first() for x in qs if x.content_object.sale_orders.first()]
|
||||||
|
@classmethod
|
||||||
|
def get_invoices(cls, staff=None, is_dealer=False):
|
||||||
|
if not staff and not is_dealer:
|
||||||
|
return []
|
||||||
|
|
||||||
|
content_type = ContentType.objects.get_for_model(EstimateModel)
|
||||||
|
related_content_type = ContentType.objects.get_for_model(Staff)
|
||||||
|
|
||||||
|
if is_dealer:
|
||||||
|
qs = cls.objects.filter(
|
||||||
|
content_type=content_type,
|
||||||
|
related_content_type=related_content_type,
|
||||||
|
related_object_id__isnull=False
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
qs = cls.objects.filter(
|
||||||
|
content_type=content_type,
|
||||||
|
related_content_type=related_content_type,
|
||||||
|
related_object_id=staff.pk
|
||||||
|
)
|
||||||
|
print(qs[0].content_object.invoicemodel_set.first())
|
||||||
|
return [x.content_object.invoicemodel_set.first() for x in qs if x.content_object.invoicemodel_set.first()]
|
||||||
|
|||||||
@ -642,3 +642,6 @@ class BaseBillActionView(LoginRequiredMixin,PermissionRequiredMixin, RedirectVie
|
|||||||
level=messages.ERROR,
|
level=messages.ERROR,
|
||||||
extra_tags='is-danger')
|
extra_tags='is-danger')
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -226,8 +226,8 @@ def reserve_car(car, request):
|
|||||||
car.save()
|
car.save()
|
||||||
# --- Logging for Success ---
|
# --- Logging for Success ---
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Car {car.id} ('{car.make} {car.model}') reserved successfully "
|
f"Car {car.pk} ('{car.id_car_make} {car.id_car_model}') reserved successfully "
|
||||||
f"by user {request.user.id} ('{request.user.username}'). "
|
f"by user {request.user}. "
|
||||||
f"Reserved until: {reserved_until}."
|
f"Reserved until: {reserved_until}."
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -235,8 +235,8 @@ def reserve_car(car, request):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
# --- Logging for Error ---
|
# --- Logging for Error ---
|
||||||
logger.error(
|
logger.error(
|
||||||
f"Error reserving car {car.id} ('{car.make} {car.model}') "
|
f"Error reserving car {car.pk} ('{car.id_car_make} {car.id_car_model}') "
|
||||||
f"for user {request.user.id} ('{request.user.username}'). "
|
f"for user {request.user} . "
|
||||||
f"Error: {e}",
|
f"Error: {e}",
|
||||||
exc_info=True
|
exc_info=True
|
||||||
)
|
)
|
||||||
@ -473,7 +473,7 @@ def set_invoice_payment(dealer, entity, invoice, amount, payment_method):
|
|||||||
calculator = CarFinanceCalculator(invoice)
|
calculator = CarFinanceCalculator(invoice)
|
||||||
finance_data = calculator.get_finance_data()
|
finance_data = calculator.get_finance_data()
|
||||||
|
|
||||||
handle_account_process(invoice, amount, finance_data)
|
# handle_account_process(invoice, amount, finance_data)
|
||||||
invoice.make_payment(amount)
|
invoice.make_payment(amount)
|
||||||
invoice.save()
|
invoice.save()
|
||||||
|
|
||||||
|
|||||||
@ -4210,13 +4210,12 @@ def sales_list_view(request, dealer_slug):
|
|||||||
staff = getattr(request.user.staffmember, "staff", None)
|
staff = getattr(request.user.staffmember, "staff", None)
|
||||||
qs = []
|
qs = []
|
||||||
try:
|
try:
|
||||||
if dealer:
|
if request.is_dealer:
|
||||||
qs = models.ExtraInfo.get_sale_orders(staff=staff,is_dealer=True)
|
qs = models.ExtraInfo.get_sale_orders(staff=staff,is_dealer=True)
|
||||||
else:
|
elif request.is_staff:
|
||||||
qs = models.ExtraInfo.get_sale_orders(staff=staff)
|
qs = models.ExtraInfo.get_sale_orders(staff=staff)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
print(qs)
|
|
||||||
# sale_orders = models.SaleOrder.objects.filter(
|
# sale_orders = models.SaleOrder.objects.filter(
|
||||||
# dealer=dealer,
|
# dealer=dealer,
|
||||||
# )
|
# )
|
||||||
@ -4289,19 +4288,19 @@ class EstimateListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
|||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
|
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
|
||||||
staff = getattr(self.request.user.staffmember, "staff", None)
|
staff = getattr(self.request.user.staffmember, "staff", None)
|
||||||
dealer = getattr(self.request.user, "dealer", None)
|
|
||||||
|
|
||||||
if dealer:
|
if self.request.is_dealer:
|
||||||
qs = models.ExtraInfo.objects.filter(
|
qs = models.ExtraInfo.objects.filter(
|
||||||
content_type=ContentType.objects.get_for_model(EstimateModel),
|
content_type=ContentType.objects.get_for_model(EstimateModel),
|
||||||
related_content_type=ContentType.objects.get_for_model(models.Staff),
|
related_content_type=ContentType.objects.get_for_model(models.Staff),
|
||||||
)
|
)
|
||||||
else:
|
elif self.request.is_staff:
|
||||||
qs = models.ExtraInfo.objects.filter(
|
qs = models.ExtraInfo.objects.filter(
|
||||||
content_type=ContentType.objects.get_for_model(EstimateModel),
|
content_type=ContentType.objects.get_for_model(EstimateModel),
|
||||||
related_content_type=ContentType.objects.get_for_model(models.Staff),
|
related_content_type=ContentType.objects.get_for_model(models.Staff),
|
||||||
related_object_id=staff.pk if staff else self.request.user.pk,
|
related_object_id=staff.pk,
|
||||||
)
|
)
|
||||||
context["staff_estimates"] = qs
|
context["staff_estimates"] = qs
|
||||||
return context
|
return context
|
||||||
@ -4450,17 +4449,17 @@ def create_estimate(request, dealer_slug, slug=None):
|
|||||||
}
|
}
|
||||||
for item in items_txs
|
for item in items_txs
|
||||||
}
|
}
|
||||||
else:
|
# else:
|
||||||
item = entity.get_items_all().filter(pk=items).first()
|
# item = entity.get_items_all().filter(pk=items).first()
|
||||||
instance = models.Car.objects.get(vin=item.name)
|
# instance = models.Car.objects.get(vin=item.name)
|
||||||
estimate_itemtxs = {
|
# estimate_itemtxs = {
|
||||||
item.item_number: {
|
# item.item_number: {
|
||||||
"unit_cost": instance.finances.cost_price,
|
# "unit_cost": instance.finances.cost_price,
|
||||||
"unit_revenue": instance.finances.selling_price,
|
# "unit_revenue": instance.finances.selling_price,
|
||||||
"quantity": Decimal(quantities),
|
# "quantity": Decimal(quantities),
|
||||||
"total_amount": instance.finances.total_vat * int(quantities),
|
# "total_amount": instance.finances.total_vat * int(quantities),
|
||||||
}
|
# }
|
||||||
}
|
# }
|
||||||
|
|
||||||
try:
|
try:
|
||||||
estimate.migrate_itemtxs(
|
estimate.migrate_itemtxs(
|
||||||
@ -4478,16 +4477,14 @@ def create_estimate(request, dealer_slug, slug=None):
|
|||||||
)
|
)
|
||||||
if isinstance(items, list):
|
if isinstance(items, list):
|
||||||
for item in estimate_itemtxs.keys():
|
for item in estimate_itemtxs.keys():
|
||||||
item_instance = ItemModel.objects.filter(item_number=item).first()
|
item_instance = entity.get_items_all().filter(item_number=item).first()
|
||||||
instance = models.Car.objects.get(vin=item_instance.name)
|
|
||||||
# reserve_car(instance, request) #TODO
|
|
||||||
|
|
||||||
else:
|
# else:
|
||||||
item_instance = ItemModel.objects.filter(
|
# item_instance = ItemModel.objects.filter(
|
||||||
additioinal_info__car_info__hash=items
|
# additioinal_info__car_info__hash=items
|
||||||
).first()
|
# ).first()
|
||||||
instance = models.Car.objects.get(hash=item)
|
# instance = models.Car.objects.get(hash=item)
|
||||||
# reserve_car(instance, request) #TODO
|
# reserve_car(instance, request) #TODO
|
||||||
|
|
||||||
opportunity_id = data.get("opportunity_id")
|
opportunity_id = data.get("opportunity_id")
|
||||||
if opportunity_id != "None":
|
if opportunity_id != "None":
|
||||||
@ -4518,7 +4515,8 @@ def create_estimate(request, dealer_slug, slug=None):
|
|||||||
"url": f"{url}",
|
"url": f"{url}",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
#######################################
|
||||||
|
##GET
|
||||||
form = forms.EstimateModelCreateForm()
|
form = forms.EstimateModelCreateForm()
|
||||||
form.fields["customer"].queryset = models.Customer.objects.filter(
|
form.fields["customer"].queryset = models.Customer.objects.filter(
|
||||||
dealer=dealer, active=True
|
dealer=dealer, active=True
|
||||||
@ -4860,6 +4858,9 @@ def estimate_mark_as(request, dealer_slug, pk):
|
|||||||
)
|
)
|
||||||
estimate.mark_as_approved()
|
estimate.mark_as_approved()
|
||||||
estimate.save()
|
estimate.save()
|
||||||
|
#Reserve The Car
|
||||||
|
car = estimate.get_itemtxs_data()[0].first().item_model.car
|
||||||
|
reserve_car(car, request)
|
||||||
messages.success(request, _("Quotation approved successfully"))
|
messages.success(request, _("Quotation approved successfully"))
|
||||||
return redirect(
|
return redirect(
|
||||||
"estimate_list", dealer_slug=dealer.slug
|
"estimate_list", dealer_slug=dealer.slug
|
||||||
@ -4934,8 +4935,20 @@ class InvoiceListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
|||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
|
dealer = get_object_or_404(models.Dealer, slug=self.kwargs["dealer_slug"])
|
||||||
|
entity = dealer.entity
|
||||||
|
staff = getattr(self.request.user.staffmember, "staff", None)
|
||||||
|
qs = []
|
||||||
|
try:
|
||||||
|
if self.request.is_dealer:
|
||||||
|
qs = models.ExtraInfo.get_invoices(staff=staff,is_dealer=True)
|
||||||
|
elif self.request.is_staff:
|
||||||
|
qs = models.ExtraInfo.get_invoices(staff=staff)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
query = self.request.GET.get("q")
|
query = self.request.GET.get("q")
|
||||||
invoices = dealer.entity.get_invoices()
|
invoices = qs
|
||||||
|
# invoices = dealer.entity.get_invoices()
|
||||||
return apply_search_filters(invoices, query)
|
return apply_search_filters(invoices, query)
|
||||||
|
|
||||||
|
|
||||||
@ -5624,7 +5637,8 @@ class LeadDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
|
|||||||
dealer=dealer,
|
dealer=dealer,
|
||||||
content_type__model="lead", object_id=self.object.id,
|
content_type__model="lead", object_id=self.object.id,
|
||||||
scheduled_by=self.request.user
|
scheduled_by=self.request.user
|
||||||
)
|
).order_by("-created_at")
|
||||||
|
|
||||||
context["status_history"] = models.LeadStatusHistory.objects.filter(
|
context["status_history"] = models.LeadStatusHistory.objects.filter(
|
||||||
lead=self.object
|
lead=self.object
|
||||||
)
|
)
|
||||||
@ -6193,6 +6207,14 @@ def schedule_event(request, dealer_slug,content_type,slug):
|
|||||||
)
|
)
|
||||||
|
|
||||||
instance.save()
|
instance.save()
|
||||||
|
models.Activity.objects.create(
|
||||||
|
dealer=dealer,
|
||||||
|
content_object=obj,
|
||||||
|
notes=instance.notes,
|
||||||
|
created_by=request.user,
|
||||||
|
activity_type=instance.scheduled_type,
|
||||||
|
)
|
||||||
|
|
||||||
# --- Logging for successful AppointmentRequest and Appointment creation ---
|
# --- Logging for successful AppointmentRequest and Appointment creation ---
|
||||||
logger.info(
|
logger.info(
|
||||||
f"User {user_username} successfully scheduled {content_type} ID: {obj.pk} ('{obj.slug}'). "
|
f"User {user_username} successfully scheduled {content_type} ID: {obj.pk} ('{obj.slug}'). "
|
||||||
@ -6551,6 +6573,7 @@ class OpportunityDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailV
|
|||||||
permission_required = ["inventory.view_opportunity"]
|
permission_required = ["inventory.view_opportunity"]
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
|
dealer = get_object_or_404(models.Dealer,slug=self.kwargs.get("dealer_slug"))
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
form = forms.OpportunityStatusForm()
|
form = forms.OpportunityStatusForm()
|
||||||
url = reverse("opportunity_update_status", kwargs={"dealer_slug": self.kwargs["dealer_slug"], "slug": self.object.slug})
|
url = reverse("opportunity_update_status", kwargs={"dealer_slug": self.kwargs["dealer_slug"], "slug": self.object.slug})
|
||||||
@ -6596,11 +6619,24 @@ class OpportunityDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailV
|
|||||||
context["tasks"] = models.Tasks.objects.filter(
|
context["tasks"] = models.Tasks.objects.filter(
|
||||||
content_type__model="opportunity", object_id=self.object.id
|
content_type__model="opportunity", object_id=self.object.id
|
||||||
)
|
)
|
||||||
|
qs = models.Schedule.objects.filter(
|
||||||
|
dealer=dealer,
|
||||||
|
content_type__model="lead", object_id=self.object.lead.id,
|
||||||
|
scheduled_by=self.request.user
|
||||||
|
)
|
||||||
|
|
||||||
|
context["schedules"] = qs | models.Schedule.objects.filter(
|
||||||
|
dealer=dealer,
|
||||||
|
content_type__model="opportunity", object_id=self.object.id,
|
||||||
|
scheduled_by=self.request.user
|
||||||
|
)
|
||||||
|
context["schedules"] = context["schedules"].order_by("-created_at")
|
||||||
context["upcoming_events"] = {
|
context["upcoming_events"] = {
|
||||||
"schedules": self.object.lead.get_all_schedules().filter(
|
"schedules": qs.filter(
|
||||||
scheduled_at__gt=timezone.now()
|
scheduled_at__gt=timezone.now()
|
||||||
),
|
)[:5],
|
||||||
}
|
}
|
||||||
|
context["schedule_form"] = forms.ScheduleForm()
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
@ -7504,6 +7540,7 @@ class OrderListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
|||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
dealer = get_user_type(self.request)
|
dealer = get_user_type(self.request)
|
||||||
qs = super().get_queryset()
|
qs = super().get_queryset()
|
||||||
|
print(qs)
|
||||||
return qs.filter(estimate__entity=dealer.entity)
|
return qs.filter(estimate__entity=dealer.entity)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -86,7 +86,7 @@
|
|||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-12 overflow-auto" style="max-height: 200px;">
|
<div class="col-12 overflow-auto" style="max-height: 200px;">
|
||||||
<ul class="list-group list-group-flush">
|
<ul class="list-group list-group-flush">
|
||||||
{% for event in opportunity.get_schedules %}
|
{% for event in schedules %}
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<span class="badge rounded-pill bg-phoenix-primary text-primary me-2 fs-9">{{ event.scheduled_type|capfirst }}</span>
|
<span class="badge rounded-pill bg-phoenix-primary text-primary me-2 fs-9">{{ event.scheduled_type|capfirst }}</span>
|
||||||
@ -348,7 +348,7 @@
|
|||||||
<div class="mb-1 d-flex justify-content-between align-items-center">
|
<div class="mb-1 d-flex justify-content-between align-items-center">
|
||||||
<h3 class="mb-0" id="scrollspyEmails">{{ _("Tasks") }}</h3>
|
<h3 class="mb-0" id="scrollspyEmails">{{ _("Tasks") }}</h3>
|
||||||
{% if perms.inventory.change_opportunity%}
|
{% if perms.inventory.change_opportunity%}
|
||||||
<button class="btn btn-phoenix-primary btn-sm" type="button" data-bs-toggle="modal" data-bs-target="#taskModal"><span class="fas fa-plus me-1"></span>{{ _("Add Task") }}</button>
|
<button class="btn btn-phoenix-primary btn-sm" type="button" data-bs-toggle="modal" data-bs-target="#scheduleModal"><span class="fas fa-plus me-1"></span>{{ _("Add Task") }}</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@ -364,13 +364,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="sort white-space-nowrap align-middle pe-3 ps-0 text-uppercase" scope="col" data-sort="subject" style="width:31%; min-width:350px">Title</th>
|
<th class="sort white-space-nowrap align-middle pe-3 ps-0 text-uppercase" scope="col" data-sort="subject" style="width:31%; min-width:350px">Title</th>
|
||||||
|
<th class="sort white-space-nowrap align-middle pe-3 ps-0 text-uppercase" scope="col" data-sort="subject" style="width:31%; min-width:350px">Notes</th>
|
||||||
<th class="sort align-middle pe-3 text-uppercase" scope="col" data-sort="sent" style="width:15%; min-width:130px">Assigned to</th>
|
<th class="sort align-middle pe-3 text-uppercase" scope="col" data-sort="sent" style="width:15%; min-width:130px">Assigned to</th>
|
||||||
<th class="sort align-middle text-start text-uppercase" scope="col" data-sort="date" style="min-width:165px">Due Date</th>
|
<th class="sort align-middle text-start text-uppercase" scope="col" data-sort="date" style="min-width:165px">Due Date</th>
|
||||||
<th class="sort align-middle text-start text-uppercase" scope="col" data-sort="date" style="min-width:165px">Completed</th>
|
<th class="sort align-middle text-start text-uppercase" scope="col" data-sort="date" style="min-width:165px">Completed</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="list" id="all-tasks-table-body">
|
<tbody class="list" id="all-tasks-table-body">
|
||||||
{% for task in opportunity.get_tasks %}
|
{% for task in schedules %}
|
||||||
{% include "partials/task.html" %}
|
{% include "partials/task.html" %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -697,7 +698,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{%if perms.inventory.change_opportunity%}
|
{%if perms.inventory.change_opportunity%}
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<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>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
@ -752,4 +753,6 @@
|
|||||||
{% include "components/task_modal.html" with content_type="opportunity" slug=opportunity.slug %}
|
{% include "components/task_modal.html" with content_type="opportunity" slug=opportunity.slug %}
|
||||||
<!-- note Modal -->
|
<!-- note Modal -->
|
||||||
{% include "components/note_modal.html" with content_type="opportunity" slug=opportunity.slug %}
|
{% include "components/note_modal.html" with content_type="opportunity" slug=opportunity.slug %}
|
||||||
|
<!-- schedule Modal -->
|
||||||
|
{% include "components/schedule_modal.html" with content_type="opportunity" slug=opportunity.slug %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -470,7 +470,7 @@
|
|||||||
</li>
|
</li>
|
||||||
{% if request.is_staff %}
|
{% if request.is_staff %}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link px-3 d-block" href="{% url 'appointment:get_user_appointments' %}"> <span class="me-2 text-body align-bottom" data-feather="calendar"></span>{{ _("Calendar") }}</a>
|
<a class="nav-link px-3 d-block" href="{% url 'appointment:get_user_appointments' %}"> <span class="me-2 text-body align-bottom" data-feather="calendar"></span>{{ _("My Calendar") }}</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<!--<li class="nav-item"><a class="nav-link px-3 d-block" href=""> Language</a></li>-->
|
<!--<li class="nav-item"><a class="nav-link px-3 d-block" href=""> Language</a></li>-->
|
||||||
|
|||||||
@ -2,12 +2,13 @@
|
|||||||
<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" {% if task.completed %}checked{% endif %} type="checkbox" hx-post="{% url 'update_schedule' request.dealer.slug 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_schedule' request.dealer.slug 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.purpose|capfirst}}</a>
|
<td class="subject order align-middle white-space-nowrap py-2 ps-0"><a class="fw-semibold text-primary" href="">{{task.purpose|capfirst}}</a>
|
||||||
<div class="fs-10 d-block">{{task.scheduled_type|capfirst}}</div>
|
<div class="fs-10 d-block">{{task.scheduled_type|capfirst}}</div>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="sent align-middle white-space-nowrap text-start fw-thin text-body-tertiary py-2">{{task.notes}}</td>
|
||||||
<td class="sent align-middle white-space-nowrap text-start fw-bold text-body-tertiary py-2">{{task.scheduled_by}}</td>
|
<td class="sent align-middle white-space-nowrap text-start fw-bold text-body-tertiary py-2">{{task.scheduled_by}}</td>
|
||||||
<td class="date align-middle white-space-nowrap text-body py-2">{{task.created_at|naturalday|capfirst}}</td>
|
<td class="date align-middle white-space-nowrap text-body py-2">{{task.created_at|naturalday|capfirst}}</td>
|
||||||
<td class="date align-middle white-space-nowrap text-body py-2">
|
<td class="date align-middle white-space-nowrap text-body py-2">
|
||||||
|
|||||||
@ -166,6 +166,7 @@
|
|||||||
<span>{{item.make}} {{item.model}} {{item.serie}} {{item.trim}} {{item.color_name}}</span>
|
<span>{{item.make}} {{item.model}} {{item.serie}} {{item.trim}} {{item.color_name}}</span>
|
||||||
<div class="color-box" style="background-color: rgb({{ item.exterior_color }});"></div>
|
<div class="color-box" style="background-color: rgb({{ item.exterior_color }});"></div>
|
||||||
<div class="color-box" style="background-color: rgb({{ item.interior_color }});"></div>
|
<div class="color-box" style="background-color: rgb({{ item.interior_color }});"></div>
|
||||||
|
<span style="color:gray;">({{item.hash_count}} in stock)</span>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user