add validation for car finance and estimate discount
This commit is contained in:
parent
bd1e4d73ae
commit
4cc61a6fa3
@ -432,25 +432,20 @@ class CarFinanceForm(forms.ModelForm):
|
|||||||
additional services associated with a car finance application.
|
additional services associated with a car finance application.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# additional_finances = forms.ModelMultipleChoiceField(
|
def clean(self):
|
||||||
# queryset=AdditionalServices.objects.all(),
|
cleaned_data = super().clean()
|
||||||
# widget=forms.CheckboxSelectMultiple(attrs={"class": "form-check-input"}),
|
cost_price = cleaned_data.get("cost_price")
|
||||||
# required=False,
|
marked_price = cleaned_data.get("marked_price")
|
||||||
# )
|
|
||||||
|
if cost_price > marked_price:
|
||||||
|
raise forms.ValidationError({"cost_price": "Cost price should not be greater than marked price"})
|
||||||
|
|
||||||
|
return cleaned_data
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CarFinance
|
model = CarFinance
|
||||||
fields = ["cost_price","marked_price"]
|
fields = ["cost_price","marked_price"]
|
||||||
|
|
||||||
# def save(self, commit=True):
|
|
||||||
# instance = super().save()
|
|
||||||
# try:
|
|
||||||
# instance.additional_services.set(self.cleaned_data["additional_finances"])
|
|
||||||
# except KeyError:
|
|
||||||
# pass
|
|
||||||
# instance.save()
|
|
||||||
# return instance
|
|
||||||
|
|
||||||
|
|
||||||
class CarLocationForm(forms.ModelForm):
|
class CarLocationForm(forms.ModelForm):
|
||||||
"""
|
"""
|
||||||
@ -1172,6 +1167,7 @@ class ScheduleForm(forms.ModelForm):
|
|||||||
scheduled_at = forms.DateTimeField(
|
scheduled_at = forms.DateTimeField(
|
||||||
widget=DateTimeInput(attrs={"type": "datetime-local"})
|
widget=DateTimeInput(attrs={"type": "datetime-local"})
|
||||||
)
|
)
|
||||||
|
reminder = forms.BooleanField(help_text=_("Send a reminder?"),required=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Schedule
|
model = Schedule
|
||||||
|
|||||||
@ -4912,10 +4912,19 @@ def update_estimate_discount(request, dealer_slug, pk):
|
|||||||
object_id=estimate.pk,
|
object_id=estimate.pk,
|
||||||
)
|
)
|
||||||
discount_amount = request.POST.get("discount_amount", 0)
|
discount_amount = request.POST.get("discount_amount", 0)
|
||||||
|
calculator = CarFinanceCalculator(estimate)
|
||||||
|
finance_data = calculator.get_finance_data()
|
||||||
|
if Decimal(discount_amount) >= finance_data.get('cars')[0]['marked_price']:
|
||||||
|
messages.error(request, _("Discount amount cannot be greater than marked price"))
|
||||||
|
return redirect("estimate_detail", dealer_slug=dealer_slug, pk=pk)
|
||||||
|
|
||||||
|
print(finance_data.get('cars')[0]['marked_price'] * Decimal('0.5'))
|
||||||
|
if Decimal(discount_amount) > finance_data.get('cars')[0]['marked_price'] * Decimal('0.5'):
|
||||||
|
messages.warning(request, _("Discount amount is greater than 50% of the marked price, proceed with caution."))
|
||||||
|
else:
|
||||||
|
messages.success(request, _("Discount updated successfully"))
|
||||||
extra_info.data.update({"discount": Decimal(discount_amount)})
|
extra_info.data.update({"discount": Decimal(discount_amount)})
|
||||||
extra_info.save()
|
extra_info.save()
|
||||||
messages.success(request, "Discount updated successfully")
|
|
||||||
return redirect("estimate_detail", dealer_slug=dealer_slug, pk=pk)
|
return redirect("estimate_detail", dealer_slug=dealer_slug, pk=pk)
|
||||||
|
|
||||||
|
|
||||||
@ -6535,6 +6544,7 @@ def schedule_event(request, dealer_slug, content_type, slug):
|
|||||||
|
|
||||||
form = forms.ScheduleForm(request.POST)
|
form = forms.ScheduleForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
|
reminder = form.cleaned_data['reminder']
|
||||||
instance = form.save(commit=False)
|
instance = form.save(commit=False)
|
||||||
instance.dealer = dealer
|
instance.dealer = dealer
|
||||||
instance.content_object = obj
|
instance.content_object = obj
|
||||||
@ -6581,20 +6591,21 @@ def schedule_event(request, dealer_slug, content_type, slug):
|
|||||||
created_by=request.user,
|
created_by=request.user,
|
||||||
activity_type=instance.scheduled_type,
|
activity_type=instance.scheduled_type,
|
||||||
)
|
)
|
||||||
scheduled_at_aware = timezone.make_aware(instance.scheduled_at, timezone.get_current_timezone()) if timezone.is_naive(instance.scheduled_at) else instance.scheduled_at
|
if reminder:
|
||||||
|
scheduled_at_aware = timezone.make_aware(instance.scheduled_at, timezone.get_current_timezone()) if timezone.is_naive(instance.scheduled_at) else instance.scheduled_at
|
||||||
|
|
||||||
reminder_time = scheduled_at_aware - timezone.timedelta(minutes=15)
|
reminder_time = scheduled_at_aware - timezone.timedelta(minutes=15)
|
||||||
# Only schedule if the reminder time is in the future
|
# Only schedule if the reminder time is in the future
|
||||||
# Reminder emails are scheduled to be sent 15 minutes before the scheduled time
|
# Reminder emails are scheduled to be sent 15 minutes before the scheduled time
|
||||||
if reminder_time > timezone.now():
|
if reminder_time > timezone.now():
|
||||||
DjangoQSchedule.objects.create(
|
DjangoQSchedule.objects.create(
|
||||||
name=f"send_schedule_reminder_email_to_{instance.scheduled_by.email}_for_{content_type}_with_PK_{instance.pk}",
|
name=f"send_schedule_reminder_email_to_{instance.scheduled_by.email}_for_{content_type}_with_PK_{instance.pk}",
|
||||||
func='inventory.tasks.send_schedule_reminder_email',
|
func='inventory.tasks.send_schedule_reminder_email',
|
||||||
args=f'"{instance.pk}"',
|
args=f'"{instance.pk}"',
|
||||||
schedule_type=DjangoQSchedule.ONCE,
|
schedule_type=DjangoQSchedule.ONCE,
|
||||||
next_run=reminder_time,
|
next_run=reminder_time,
|
||||||
hook='inventory.tasks.log_email_status',
|
hook='inventory.tasks.log_email_status',
|
||||||
)
|
)
|
||||||
messages.success(request, _("Appointment Created Successfully"))
|
messages.success(request, _("Appointment Created Successfully"))
|
||||||
|
|
||||||
return redirect(f'{content_type}_detail',dealer_slug=dealer_slug, slug=slug)
|
return redirect(f'{content_type}_detail',dealer_slug=dealer_slug, slug=slug)
|
||||||
@ -9689,10 +9700,10 @@ def update_task(request, dealer_slug, pk):
|
|||||||
@permission_required("inventory.change_schedule", raise_exception=True)
|
@permission_required("inventory.change_schedule", raise_exception=True)
|
||||||
def update_schedule(request, dealer_slug, pk):
|
def update_schedule(request, dealer_slug, pk):
|
||||||
task = get_object_or_404(models.Schedule, pk=pk)
|
task = get_object_or_404(models.Schedule, pk=pk)
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
task.completed = False if task.completed else True
|
task.completed = False if task.completed else True
|
||||||
task.save()
|
task.save()
|
||||||
|
print("task")
|
||||||
|
|
||||||
return render(request, "partials/task.html", {"task": task})
|
return render(request, "partials/task.html", {"task": task})
|
||||||
|
|
||||||
|
|||||||
@ -138,7 +138,8 @@ html[dir="rtl"] .form-icon-container .form-control {
|
|||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
z-index: 10;
|
z-index: 9999;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#spinner-bg {
|
#spinner-bg {
|
||||||
@ -150,11 +151,14 @@ html[dir="rtl"] .form-icon-container .form-control {
|
|||||||
background-color: rgba(255, 255, 255, 0.7);
|
background-color: rgba(255, 255, 255, 0.7);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 500ms ease-in;
|
transition: opacity 500ms ease-in;
|
||||||
z-index: 5;
|
visibility: hidden;
|
||||||
|
z-index: 10000;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#spinner-bg.htmx-request {
|
#spinner-bg.htmx-request {
|
||||||
opacity: .8;
|
opacity: .8;
|
||||||
|
visibility: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -84,10 +84,10 @@
|
|||||||
{% include "plans/expiration_messages.html" %}
|
{% include "plans/expiration_messages.html" %}
|
||||||
{% block period_navigation %}
|
{% block period_navigation %}
|
||||||
{% endblock period_navigation %}
|
{% endblock period_navigation %}
|
||||||
<div id="main_content" class="fade-me-in" hx-boost="false" hx-target="#main_content" hx-select="#main_content" hx-swap="outerHTML transition:true" hx-select-oob="#toast-container" hx-history-elt>
|
<div id="spinner" class="htmx-indicator spinner-bg">
|
||||||
<div id="spinner" class="htmx-indicator spinner-bg">
|
|
||||||
<img src="{% static 'spinner.svg' %}" width="100" height="100" alt="">
|
<img src="{% static 'spinner.svg' %}" width="100" height="100" alt="">
|
||||||
</div>
|
</div>
|
||||||
|
<div id="main_content" class="fade-me-in" hx-boost="false" hx-target="#main_content" hx-select="#main_content" hx-swap="outerHTML transition:true" hx-select-oob="#toast-container" hx-history-elt>
|
||||||
{% block customCSS %}{% endblock %}
|
{% block customCSS %}{% endblock %}
|
||||||
{% block content %}{% endblock content %}
|
{% block content %}{% endblock content %}
|
||||||
{% block customJS %}{% endblock %}
|
{% block customJS %}{% endblock %}
|
||||||
|
|||||||
@ -7,9 +7,10 @@
|
|||||||
<input class="form-check-input"
|
<input class="form-check-input"
|
||||||
{% if task.completed %}checked{% endif %}
|
{% if task.completed %}checked{% endif %}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
hx-post="{% url 'update_schedule' request.dealer.slug task.pk %}"
|
hx-post="{% url 'update_schedule' request.dealer.slug task.pk %}"
|
||||||
hx-trigger="change"
|
hx-trigger="change"
|
||||||
hx-swap="outerHTML"
|
hx-swap="none"
|
||||||
|
hx-on:click="$(this).closest('tr').toggleClass('completed-task')"
|
||||||
hx-target="#task-{{ task.pk }}" />
|
hx-target="#task-{{ task.pk }}" />
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@ -18,7 +19,7 @@
|
|||||||
<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-thin text-body-tertiary py-2">{{ task.notes }}</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.scheduled_at|naturaltime|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">
|
||||||
{% if task.completed %}
|
{% if task.completed %}
|
||||||
<span class="badge badge-phoenix fs-10 badge-phoenix-success"><i class="fa-solid fa-check"></i></span>
|
<span class="badge badge-phoenix fs-10 badge-phoenix-success"><i class="fa-solid fa-check"></i></span>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user