Compare commits
3 Commits
094deebf58
...
20e1811fc7
| Author | SHA1 | Date | |
|---|---|---|---|
| 20e1811fc7 | |||
| 40abbdbdaf | |||
| 29532ffbd0 |
@ -2448,12 +2448,7 @@ class Opportunity(models.Model):
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
probability = models.PositiveIntegerField(validators=[validate_probability],null=True, blank=True)
|
||||
amount = models.DecimalField(
|
||||
max_digits=10,
|
||||
decimal_places=2,
|
||||
verbose_name=_("Amount"),
|
||||
)
|
||||
|
||||
expected_revenue = models.DecimalField(
|
||||
max_digits=10,
|
||||
decimal_places=2,
|
||||
@ -2461,8 +2456,6 @@ class Opportunity(models.Model):
|
||||
blank=True,
|
||||
null=True,
|
||||
)
|
||||
vehicle_of_interest_make = models.CharField(max_length=50, blank=True, null=True)
|
||||
vehicle_of_interest_model = models.CharField(max_length=100, blank=True, null=True)
|
||||
expected_close_date = models.DateField(blank=True, null=True)
|
||||
created = models.DateTimeField(auto_now_add=True, verbose_name=_("Created"))
|
||||
updated = models.DateTimeField(auto_now=True, verbose_name=_("Updated"))
|
||||
@ -2523,8 +2516,6 @@ class Opportunity(models.Model):
|
||||
return objects
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.amount:
|
||||
self.expected_revenue = self.amount * self.probability / 100
|
||||
opportinity_for = ""
|
||||
if self.lead.lead_type == "customer":
|
||||
self.customer = self.lead.customer
|
||||
|
||||
@ -1129,7 +1129,6 @@ class ChartOfAccountModelCreateView(ChartOfAccountModelModelBaseViewMixIn, Creat
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class ChartOfAccountModelUpdateView(ChartOfAccountModelModelBaseViewMixIn, UpdateView):
|
||||
context_object_name = "coa_model"
|
||||
slug_url_kwarg = "coa_slug"
|
||||
|
||||
@ -4360,7 +4360,8 @@ class AccountListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
|
||||
def get_queryset(self):
|
||||
query = self.request.GET.get("q")
|
||||
dealer = get_user_type(self.request)
|
||||
accounts = dealer.entity.get_all_accounts()
|
||||
coa = ChartOfAccountModel.objects.get(entity=dealer.entity,pk=self.kwargs["coa_pk"]) or self.request.entity.get_default_coa()
|
||||
accounts = coa.get_coa_accounts()
|
||||
return apply_search_filters(accounts, query)
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
@ -4410,9 +4411,20 @@ class AccountCreateView(
|
||||
permission_required = ["django_ledger.add_accountmodel"]
|
||||
|
||||
def form_valid(self, form):
|
||||
dealer = get_user_type(self.request)
|
||||
dealer = get_user_type(self.request)
|
||||
instance = form.save(commit=False)
|
||||
coa = ChartOfAccountModel.objects.get(entity=dealer.entity,pk=self.kwargs["coa_pk"]) or self.request.entity.get_default_coa()
|
||||
# coa.insert_account(account_model=instance)
|
||||
account = coa.entity.create_account(
|
||||
coa_model=coa,
|
||||
code=instance.code,
|
||||
name=instance.name,
|
||||
role=instance.role,
|
||||
balance_type=_(instance.balance_type),
|
||||
active=True,
|
||||
)
|
||||
form.instance.entity_model = dealer.entity
|
||||
form.instance.coa_model = dealer.entity.get_default_coa()
|
||||
form.instance.coa_model = coa
|
||||
form.instance.depth = 0
|
||||
form.instance.path = form.instance.code
|
||||
return super().form_valid(form)
|
||||
@ -4420,13 +4432,15 @@ class AccountCreateView(
|
||||
def get_form_kwargs(self):
|
||||
dealer = get_user_type(self.request)
|
||||
kwargs = super().get_form_kwargs()
|
||||
kwargs["coa_model"] = dealer.entity.get_default_coa()
|
||||
coa = ChartOfAccountModel.objects.get(entity=dealer.entity,pk=self.kwargs["coa_pk"]) or self.request.entity.get_default_coa()
|
||||
kwargs["coa_model"] = coa
|
||||
return kwargs
|
||||
|
||||
def get_form(self, form_class=None):
|
||||
form = super().get_form(form_class)
|
||||
entity = get_user_type(self.request).entity
|
||||
form.initial["coa_model"] = entity.get_default_coa()
|
||||
coa = ChartOfAccountModel.objects.get(entity=entity,pk=self.kwargs["coa_pk"]) or self.request.entity.get_default_coa()
|
||||
form.initial["coa_model"] = coa
|
||||
return form
|
||||
|
||||
def get_success_url(self):
|
||||
@ -4436,12 +4450,13 @@ class AccountCreateView(
|
||||
def get_context_data(self,**kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["url_kwargs"] = self.kwargs
|
||||
coa_pk = context["url_kwargs"]["coa_pk"]
|
||||
coa_pk = context["url_kwargs"]["coa_pk"]
|
||||
try:
|
||||
kwargs["coa_model"] = ChartOfAccountModel.objects.get(pk=coa_pk) or self.request.entity.get_default_coa()
|
||||
context["coa_model"] = ChartOfAccountModel.objects.get(entity=self.request.entity,pk=coa_pk)
|
||||
except Exception:
|
||||
kwargs["coa_model"] = self.request.entity.get_default_coa()
|
||||
context["coa_model"] = self.request.entity.get_default_coa()
|
||||
return context
|
||||
|
||||
class AccountDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
|
||||
"""
|
||||
Represents the detailed view for an account with additional context data related to account
|
||||
@ -4540,7 +4555,11 @@ class AccountUpdateView(
|
||||
form.fields["_ref_node_id"].widget = HiddenInput()
|
||||
form.fields["_position"].widget = HiddenInput()
|
||||
return form
|
||||
|
||||
|
||||
def form_valid(self, form):
|
||||
form.instance.coa_model = ChartOfAccountModel.objects.get(pk=self.kwargs['coa_pk']) or self.request.entity.get_default_coa()
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse_lazy(
|
||||
"account_list", kwargs={"dealer_slug": self.kwargs["dealer_slug"],"coa_pk":self.kwargs["coa_pk"]}
|
||||
@ -4551,9 +4570,9 @@ class AccountUpdateView(
|
||||
context["url_kwargs"] = self.kwargs
|
||||
coa_pk = context["url_kwargs"]["coa_pk"]
|
||||
try:
|
||||
kwargs["coa_model"] = ChartOfAccountModel.objects.get(pk=coa_pk) or self.request.entity.get_default_coa()
|
||||
context["coa_model"] = ChartOfAccountModel.objects.get(pk=coa_pk) or self.request.entity.get_default_coa()
|
||||
except Exception:
|
||||
kwargs["coa_model"] = self.request.entity.get_default_coa()
|
||||
context["coa_model"] = self.request.entity.get_default_coa()
|
||||
return context
|
||||
@login_required
|
||||
@permission_required("django_ledger.delete_accountmodel")
|
||||
@ -6750,12 +6769,26 @@ def delete_note(request, dealer_slug, pk):
|
||||
:return: An HTTP redirection to the lead detail page of the corresponding note's lead.
|
||||
:rtype: HttpResponseRedirect
|
||||
"""
|
||||
note = get_object_or_404(models.Notes, pk=pk, created_by=request.user)
|
||||
lead_pk = note.content_object.pk
|
||||
lead = models.Lead.objects.get(pk=lead_pk)
|
||||
note.delete()
|
||||
messages.success(request, _("Note deleted successfully."))
|
||||
return redirect("lead_detail", dealer_slug=dealer_slug, slug=lead.slug)
|
||||
try:
|
||||
note = get_object_or_404(models.Notes, pk=pk, created_by=request.user)
|
||||
print(note)
|
||||
if isinstance(note.content_object, models.Lead):
|
||||
url = "lead_detail"
|
||||
slug = note.content_object.slug
|
||||
if hasattr(note.content_object, "opportunity"):
|
||||
url = "opportunity_detail"
|
||||
slug = note.content_object.opportunity.slug
|
||||
elif isinstance(note.content_object, models.Opportunity):
|
||||
url = "opportunity_detail"
|
||||
slug = note.content_object.slug
|
||||
|
||||
note.delete()
|
||||
messages.success(request, _("Note deleted successfully."))
|
||||
except Exception as e:
|
||||
print("Errroooorrr: ",e)
|
||||
print(url)
|
||||
print(dealer_slug)
|
||||
return redirect(url, dealer_slug=dealer_slug,slug=slug)
|
||||
|
||||
|
||||
@login_required
|
||||
@ -6837,9 +6870,9 @@ def schedule_event(request, dealer_slug, content_type, slug):
|
||||
dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
|
||||
obj = get_object_or_404(model, slug=slug)
|
||||
|
||||
if not request.is_staff:
|
||||
messages.error(request, _("You do not have permission to schedule."))
|
||||
return redirect(f"{content_type}_detail", dealer_slug=dealer_slug, slug=slug)
|
||||
# if not request.is_staff:
|
||||
# messages.error(request, _("You do not have permission to schedule."))
|
||||
# return redirect(f"{content_type}_detail", dealer_slug=dealer_slug, slug=slug)
|
||||
|
||||
if request.method == "POST":
|
||||
from django_q.models import Schedule as DjangoQSchedule
|
||||
@ -7340,7 +7373,6 @@ class OpportunityDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailV
|
||||
form.fields["stage"].widget.attrs["hx-get"] = url
|
||||
form.fields["stage"].initial = self.object.stage
|
||||
context["status_form"] = form
|
||||
|
||||
context["lead_notes"] = models.Notes.objects.filter(
|
||||
content_type__model="lead", object_id=self.object.id
|
||||
).order_by("-created")
|
||||
@ -10188,8 +10220,9 @@ def add_note(request, dealer_slug, content_type, slug):
|
||||
@require_http_methods(["POST"])
|
||||
@permission_required("inventory.change_notes", raise_exception=True)
|
||||
def update_note(request, dealer_slug, pk):
|
||||
print(pk)
|
||||
note = get_object_or_404(models.Notes, pk=pk)
|
||||
lead = get_object_or_404(models.Lead, pk=note.content_object.id)
|
||||
# lead = get_object_or_404(models.Lead, pk=note.content_object.id)
|
||||
dealer = get_object_or_404(models.Dealer, slug=dealer_slug)
|
||||
if request.method == "POST":
|
||||
note.note = request.POST.get("note")
|
||||
@ -11421,7 +11454,10 @@ def staff_password_reset_view(request, dealer_slug, user_pk):
|
||||
|
||||
if request.method == 'POST':
|
||||
form = forms.CustomSetPasswordForm(staff.user, request.POST)
|
||||
|
||||
if form.is_valid():
|
||||
print(form.cleaned_data['new_password1'])
|
||||
print(form.cleaned_data['new_password2'])
|
||||
form.save()
|
||||
messages.success(request, _('Your password has been set. You may go ahead and log in now.'))
|
||||
return redirect('user_detail',dealer_slug=dealer_slug,slug=staff.slug)
|
||||
@ -11662,12 +11698,12 @@ def ticket_update(request, ticket_id):
|
||||
})
|
||||
|
||||
|
||||
class ChartOfAccountModelListView(ChartOfAccountModelListViewBase):
|
||||
template_name = 'chart_of_accounts/coa_list.html'
|
||||
permission_required = 'django_ledger.view_chartofaccountmodel'
|
||||
# class ChartOfAccountModelListView(ChartOfAccountModelListViewBase):
|
||||
# template_name = 'chart_of_accounts/coa_list.html'
|
||||
# permission_required = 'django_ledger.view_chartofaccountmodel'
|
||||
class ChartOfAccountModelCreateView(ChartOfAccountModelCreateViewBase):
|
||||
template_name = 'chart_of_accounts/coa_create.html'
|
||||
permission_required = 'django_ledger.add_chartofaccountmodel'
|
||||
permission_required = 'django_ledger.add_chartofaccountmodel'
|
||||
class ChartOfAccountModelListView(ChartOfAccountModelListViewBase):
|
||||
template_name = 'chart_of_accounts/coa_list.html'
|
||||
permission_required = 'django_ledger.view_chartofaccountmodel'
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 334 KiB |
@ -13,7 +13,7 @@
|
||||
<p class="text-body-tertiary">{{ _("Are you sure you want to sign out?") }}</p>
|
||||
</div>
|
||||
<div class="d-grid">
|
||||
<form hx-boost="false" method="post" action="{% url 'account_logout' %}">
|
||||
<form method="post" action="{% url 'account_logout' %}">
|
||||
{% csrf_token %}
|
||||
{{ redirect_field }}
|
||||
<div class="d-grid gap-2 mt-3">
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
<h3 class="mb-4">{% trans "Change Password" %}</h3>
|
||||
</div>
|
||||
<form method="post"
|
||||
hx-boost="false"
|
||||
|
||||
action="{% url 'account_change_password' %}"
|
||||
class="form needs-validation"
|
||||
novalidate>
|
||||
|
||||
@ -24,7 +24,8 @@
|
||||
<h3 class="text-body-highlight">{% trans 'Car Dealership Registration' %}</h3>
|
||||
<p class="text-body-tertiary fs-9">{% trans 'Create your dealership account today' %}</p>
|
||||
</div>
|
||||
|
||||
<div class="mx-auto mt-4 text-center">
|
||||
</div>
|
||||
<form method="post" action="{% url 'account_signup' %}" class="needs-validation">
|
||||
{% csrf_token %}
|
||||
<div class="card theme-wizard">
|
||||
|
||||
@ -87,13 +87,7 @@
|
||||
<img src="{% static 'spinner.svg' %}" width="100" height="100" alt="">
|
||||
</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>
|
||||
class="fade-me-in">
|
||||
{% block customCSS %}{% endblock %}
|
||||
{% block content %}
|
||||
{% endblock content %}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{% load django_ledger %}
|
||||
{% load i18n %}
|
||||
<div id="djl-bill-card-widget" class="" hx-boost="false">
|
||||
<div id="djl-bill-card-widget" class="">
|
||||
{% if not create_bill %}
|
||||
{% if style == 'dashboard' %}
|
||||
<!-- Dashboard Style Card -->
|
||||
@ -54,7 +54,7 @@
|
||||
<a href="{% url 'django_ledger:bill-detail' entity_slug=entity_slug bill_pk=bill.uuid %}"
|
||||
class="btn btn-sm btn-phoenix-primary me-md-2">{% trans 'View' %}</a>
|
||||
{% if perms.django_ledger.change_billmodel %}
|
||||
<a hx-boost="true"
|
||||
<a
|
||||
href="{% url 'django_ledger:bill-update' entity_slug=entity_slug bill_pk=bill.uuid %}"
|
||||
class="btn btn-sm btn-phoenix-warning me-md-2">{% trans 'Update' %}</a>
|
||||
{% if bill.can_pay %}
|
||||
@ -203,7 +203,7 @@
|
||||
<!-- Update Button -->
|
||||
{% if perms.django_ledger.change_billmodel %}
|
||||
{% if "update" not in request.path %}
|
||||
<a hx-boost="true"
|
||||
<a
|
||||
href="{% url 'bill-update' dealer_slug=dealer_slug entity_slug=entity_slug bill_pk=bill.uuid %}">
|
||||
<button class="btn btn-phoenix-primary">
|
||||
<i class="fas fa-edit me-2"></i>{% trans 'Update' %}
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
<div class="card-header bg-gradient py-4 border-0 rounded-top-4">
|
||||
<h3 class="mb-0 fs-4 fw-bold text-center">
|
||||
{% trans 'Create Chart of Accounts' %}
|
||||
<i class="fa-solid fa-chart-pie ms-2"></i>
|
||||
<i class="fa-solid fa-chart-pie ms-2"></i>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body p-4 p-md-5">
|
||||
|
||||
@ -16,11 +16,12 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="noteForm"
|
||||
hx-boost="true"
|
||||
action="{% url 'add_note' request.dealer.slug content_type slug %}"
|
||||
hx-select="#notesTable"
|
||||
hx-target="#notesTable"
|
||||
hx-on::after-request="{ resetSubmitButton(document.querySelector('.add_note_form button[type=submit]')); $('#noteModal').modal('hide'); }"
|
||||
hx-swap="outerHTML"
|
||||
hx-swap="outerHTML show:window.top"
|
||||
method="post"
|
||||
class="add_note_form">
|
||||
{% csrf_token %}
|
||||
@ -33,12 +34,13 @@
|
||||
</div>
|
||||
<script>
|
||||
function updateNote(e) {
|
||||
let form = document.querySelector('#noteForm');
|
||||
|
||||
let url = e.getAttribute('data-url');
|
||||
let note = e.getAttribute('data-note');
|
||||
|
||||
document.querySelector('#id_note').value = note;
|
||||
|
||||
let form = document.querySelector('#noteForm');
|
||||
form.action = url;
|
||||
htmx.process(form);
|
||||
}
|
||||
|
||||
@ -16,11 +16,13 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="scheduleForm"
|
||||
hx-boost="true"
|
||||
action="{% url 'schedule_event' request.dealer.slug content_type slug %}"
|
||||
hx-select=".taskTable"
|
||||
hx-target=".taskTable"
|
||||
hx-on::after-request="{ resetSubmitButton(document.querySelector('.add_schedule_form button[type=submit]')); $('#scheduleModal').modal('hide'); }"
|
||||
hx-swap="outerHTML"
|
||||
hx-select-oob="#toast-container:outerHTML"
|
||||
method="post"
|
||||
class="add_schedule_form">
|
||||
{% csrf_token %}
|
||||
|
||||
@ -23,13 +23,12 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="taskForm"
|
||||
action="{% url 'add_task' request.dealer.slug content_type slug %}"
|
||||
method="post"
|
||||
class="add_task_form"
|
||||
hx-post="{% url 'add_task' request.dealer.slug content_type slug %}"
|
||||
hx-target="#your-content-container"
|
||||
hx-swap="innerHTML"
|
||||
hx-boost="true">
|
||||
>
|
||||
{% csrf_token %}
|
||||
{{ staff_task_form|crispy }}
|
||||
<button type="submit" class="btn btn-phoenix-success w-100">{% trans 'Save' %}</button>
|
||||
|
||||
@ -324,11 +324,7 @@
|
||||
<div class="tab-content" id="myTabContent">
|
||||
<div class="tab-pane fade"
|
||||
id="tab-activity"
|
||||
hx-get="{% url 'lead_detail' request.dealer.slug lead.slug %}"
|
||||
hx-trigger="htmx:afterRequest from:#noteForm, htmx:afterRequest from:#scheduleForm"
|
||||
hx-select="#tab-activity"
|
||||
hx-target="this"
|
||||
hx-swap="outerHTML"
|
||||
|
||||
role="tabpanel"
|
||||
aria-labelledby="activity-tab">
|
||||
<div class="mb-1 d-flex justify-content-between align-items-center">
|
||||
@ -619,7 +615,7 @@
|
||||
<td class="sent align-middle white-space-nowrap text-start fw-bold text-body-tertiary py-2">{{ email.from_email }}</td>
|
||||
<td class="date align-middle white-space-nowrap text-body py-2">{{ email.created|naturalday }}</td>
|
||||
<td class="align-middle white-space-nowrap ps-3">
|
||||
<a class="text-body" href=""><span class="fa-solid fa-phone text-primary me-2"></span>{%trans "Call"%</a>
|
||||
<a class="text-body" href=""><span class="fa-solid fa-phone text-primary me-2"></span>{%trans "Call"%}</a>
|
||||
</td>
|
||||
<td class="status align-middle fw-semibold text-end py-2">
|
||||
<span class="badge badge-phoenix fs-10 badge-phoenix-success">{%trans "sent"%}</span>
|
||||
|
||||
@ -9,7 +9,6 @@
|
||||
<h5 class="card-header">{% trans "Send Mail" %}</h5>
|
||||
<div class="card-body">
|
||||
<form class="email-form d-flex flex-column h-100"
|
||||
hx-boost="true"
|
||||
action="{% url 'send_lead_email' request.dealer.slug lead.slug %}"
|
||||
method="post">
|
||||
{% csrf_token %}
|
||||
@ -49,9 +48,7 @@
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div class="d-flex gap-2">
|
||||
{% comment %} <a href="{{ request.META.HTTP_REFERER }}" class="btn btn-phoenix-danger">Discard</a> {% endcomment %}
|
||||
<a hx-boost="true"
|
||||
hx-push-url='false'
|
||||
hx-include="#message,#subject,#to"
|
||||
<a
|
||||
href="{% url 'send_lead_email' request.dealer.slug lead.slug %}?status=draft"
|
||||
class="btn btn-phoenix-success">{% trans "Save as Draft" %}</a>
|
||||
<button class="btn btn-phoenix-primary fs-10" type="submit">
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body p-4 p-md-5">
|
||||
<form hx-boost="false"
|
||||
<form
|
||||
method="post"
|
||||
enctype="multipart/form-data"
|
||||
class="needs-validation"
|
||||
|
||||
@ -5,12 +5,7 @@
|
||||
<div class="navbar-vertical-content d-flex flex-column">
|
||||
<ul class="navbar-nav flex-column"
|
||||
id="navbarVerticalNav"
|
||||
hx-boost="false"
|
||||
hx-target="#main_content"
|
||||
hx-select="#main_content"
|
||||
hx-swap="outerHTML"
|
||||
hx-select-oob="#toast-container"
|
||||
hx-indicator="#spinner">
|
||||
>
|
||||
|
||||
<li class="nav-item">
|
||||
{% comment %} <p class="navbar-vertical-label text-primary fs-8 text-truncate">{{request.dealer|default:"Apps"}}</p>
|
||||
@ -38,7 +33,7 @@
|
||||
<li class="collapsed-nav-item-title d-none">{% trans "Inventory"|capfirst %}</li>
|
||||
{% if perms.inventory.add_car %}
|
||||
<li class="nav-item">
|
||||
<a hx-boost="false"
|
||||
<a
|
||||
id="btn-add-car"
|
||||
class="nav-link btn-add-car"
|
||||
href="{% url 'car_add' request.dealer.slug %}">
|
||||
@ -201,7 +196,7 @@
|
||||
<li class="collapsed-nav-item-title d-none">{% trans 'sales'|capfirst %}</li>
|
||||
{% if perms.django_ledger.add_estimatemodel %}
|
||||
<li class="nav-item">
|
||||
<a hx-boost="false"
|
||||
<a
|
||||
class="nav-link"
|
||||
href="{% url 'estimate_create' request.dealer.slug %}">
|
||||
<div class="d-flex align-items-center">
|
||||
@ -495,11 +490,26 @@
|
||||
title="{% trans 'Logged in as ' %}{{ request.user.username }}">
|
||||
{% trans 'Hello, ' %}{{ name_to_display }}
|
||||
</h6>
|
||||
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="navbar-logo ">
|
||||
|
||||
<div class="d-flex align-items-center">
|
||||
|
||||
<small class="text-gray-600 ms-2 d-none d-sm-block fs-9"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-placement="bottom"
|
||||
>
|
||||
{% now "l, F j, Y g:i A" %}
|
||||
</small>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<ul class="navbar-nav navbar-nav-icons flex-row gap-2" hx-boost="false">
|
||||
<ul class="navbar-nav navbar-nav-icons flex-row gap-2">
|
||||
<li class="nav-item">
|
||||
<div class="theme-control-toggle fa-icon-wait">
|
||||
<input class="form-check-input ms-0 theme-control-toggle-input"
|
||||
@ -551,7 +561,7 @@
|
||||
{% endif %}
|
||||
{% if user.is_authenticated and request.is_dealer or request.is_staff %}
|
||||
<li class="nav-item dropdown">
|
||||
<a hx-boost="false"
|
||||
<a
|
||||
class="nav-link lh-1 pe-0"
|
||||
id="navbarDropdownUser"
|
||||
role="button"
|
||||
@ -599,7 +609,7 @@
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a hx-boost="false"
|
||||
<a
|
||||
class="nav-link px-3 d-block"
|
||||
href="{% url 'staff_detail' request.dealer.slug request.staff.slug %}"> <span class="me-2 text-body align-bottom" data-feather="user"></span><span>{% translate 'profile'|capfirst %}</span></a>
|
||||
</li>
|
||||
@ -633,7 +643,7 @@
|
||||
{% endif %}
|
||||
{% if request.is_staff %}
|
||||
<li class="nav-item">
|
||||
<a hx-boost="false"
|
||||
<a
|
||||
class="nav-link px-3 d-block"
|
||||
href="{% url 'schedule_calendar' request.dealer.slug %}"> <span class="me-2 text-body align-bottom" data-feather="calendar"></span>{{ _("My Calendar") }}</a>
|
||||
</li>
|
||||
|
||||
@ -170,7 +170,7 @@
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#mainModal"
|
||||
hx-get="{% url 'add_custom_card' request.dealer.slug car.slug %}"
|
||||
hx-target=".main-modal-body"
|
||||
hx-target="#mainModalBody"
|
||||
hx-swap="innerHTML">{% trans 'Add' %}</button>
|
||||
{% endif %}
|
||||
</td>
|
||||
@ -518,7 +518,7 @@
|
||||
data-bs-dismiss="modal"
|
||||
aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="main-modal-body" style="padding: 20px;">
|
||||
<div id="mainModalBody" class="main-modal-body" style="padding: 20px;">
|
||||
<!-- Content will be loaded here via AJAX -->
|
||||
</div>
|
||||
</div>
|
||||
@ -693,5 +693,18 @@
|
||||
button.classList.add("d-none");
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('htmx:afterRequest', e => {
|
||||
console.log('PUT Success!')
|
||||
});
|
||||
document.addEventListener('htmx:beforeSwap', e => {
|
||||
console.log('Before Swap!')
|
||||
});
|
||||
document.addEventListener('htmx:swapError', e => {
|
||||
console.log('Swap Error!')
|
||||
});
|
||||
document.addEventListener('htmx:afterSwap', e => {
|
||||
console.log('After Swap!')
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
{% endif %}
|
||||
<!---->
|
||||
<div class="row justify-content-center mt-5 mb-3 {% if not vendor_exists %}d-none{% endif %}"
|
||||
hx-boost="false">
|
||||
>
|
||||
<div class="col-lg-8 col-md-10">
|
||||
<div class="card shadow-sm border-0 rounded-3">
|
||||
<div class="card-header bg-gray-200 py-3 border-0 rounded-top-3">
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
{{ _("Create Bill") }}
|
||||
{% endblock title %}
|
||||
{% block content %}
|
||||
<div class="row mt-4" hx-boost="true">
|
||||
<div class="row mt-4">
|
||||
<h3 class="text-center">
|
||||
{% trans "Create Bill" %}<span class="fas fa-money-bills ms-2 text-primary"></span>
|
||||
</h3>
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
{% else %}
|
||||
{% trans "Add New Account" %}
|
||||
<i class="fa-solid fa-book ms-2"></i>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body p-4 p-md-5">
|
||||
|
||||
@ -24,8 +24,10 @@
|
||||
</div>
|
||||
<div class="modal-footer flex justify-content-center border-top-0">
|
||||
<a id="deleteModalConfirm"
|
||||
hx-boost="true"
|
||||
hx-select-oob="#notesTable:outerHTML,#toast-container:outerHTML"
|
||||
hx-swap="none"
|
||||
hx-on::after-request="{ $('#deleteModal').modal('hide'); }"
|
||||
hx-swap="none show:#notesTable"
|
||||
type="button"
|
||||
class="btn btn-sm btn-phoenix-danger w-100"
|
||||
href="">{{ _("Delete") }}</a>
|
||||
@ -57,6 +59,7 @@
|
||||
if (!deleteModal || !confirmDeleteBtn || !deleteModalMessage) return;
|
||||
|
||||
const deleteUrl = this.getAttribute("data-url");
|
||||
console.log(deleteUrl)
|
||||
const deleteMessage = this.getAttribute("data-message") || "Are you sure you want to delete this item?";
|
||||
|
||||
// Update modal content
|
||||
@ -68,11 +71,13 @@
|
||||
htmx.process(confirmDeleteBtn);
|
||||
}
|
||||
|
||||
|
||||
// Show the modal
|
||||
/*if (typeof bootstrap !== 'undefined') {
|
||||
const modal = new bootstrap.Modal(deleteModal);
|
||||
modal.show();
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -1,79 +1,108 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}
|
||||
{% trans 'Order Details' %}
|
||||
{% endblock %}
|
||||
{% block title %}{% trans 'Order Details' %}{% endblock %}
|
||||
{% block head %}
|
||||
<script>
|
||||
$(function () {
|
||||
$('a.invoice').click(function () {
|
||||
$('a.invoice-link').on('click', function (event) {
|
||||
event.preventDefault();
|
||||
window.open($(this).attr('href'), 'plans_invoice_{{ invoice.id }}', 'width=860,resizable=1,location=0,status=0,titlebar=1');
|
||||
window.open($(this).attr('href'), 'invoice_' + $(this).data('invoice-id'), 'width=860,resizable=1,location=0,status=0,titlebar=1');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<h1 class="mt-4">
|
||||
{% blocktrans with object.id as order_id and object.get_status_display as order_status %}Order #{{ order_id }}
|
||||
(status: {{ order_status }}){% endblocktrans %}
|
||||
</h1>
|
||||
{# You should provide displaying django messages in this template #}
|
||||
{% with object as order %}
|
||||
{% include "plans/order_detail_table.html" %}
|
||||
{% endwith %}
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h1 class="text-3xl font-bold text-gray-800">
|
||||
{% blocktrans with object.id as order_id %}Order #{{ order_id }}{% endblocktrans %}
|
||||
</h1>
|
||||
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium
|
||||
{% if object.status == object.STATUS.COMPLETED %}bg-green-100 text-green-800{% elif object.status == object.STATUS.PENDING %}bg-yellow-100 text-yellow-800{% else %}bg-gray-100 text-gray-800{% endif %}">
|
||||
<i class="fas {% if object.status == object.STATUS.COMPLETED %}fa-check-circle{% elif object.status == object.STATUS.PENDING %}fa-clock{% else %}fa-info-circle{% endif %} mr-2"></i>
|
||||
{{ object.get_status_display }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{# Order Summary Section #}
|
||||
<div class="rounded-xl shadow-sm overflow-hidden mb-6">
|
||||
<div class="px-6 py-4">
|
||||
<h2 class="text-xl font-semibold text-gray-800 mb-4">{% trans "Order Summary" %}</h2>
|
||||
{% with object as order %}
|
||||
{% include "plans/order_detail_table.html" %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Printable Documents Section #}
|
||||
{% if object.get_all_invoices.count %}
|
||||
<h2 class="mt-4">{% trans "Printable documents" %}</h2>
|
||||
<ul id="order_printable_documents">
|
||||
{% for invoice in object.get_all_invoices %}
|
||||
<div class="rounded-xl shadow-sm overflow-hidden mb-6">
|
||||
<div class="px-6 py-4">
|
||||
<h2 class="text-xl font-semibold text-gray-800 mb-4">
|
||||
<i class="fas fa-file-pdf text-gray-400 mr-2"></i> {% trans "Printable documents" %}
|
||||
</h2>
|
||||
<ul class="space-y-2">
|
||||
{% for invoice in object.get_all_invoices %}
|
||||
<li>
|
||||
<a href="{{ invoice.get_absolute_url }}" class="invoice">{{ invoice.get_type_display }} {{ invoice }}</a>
|
||||
<a href="{{ invoice.get_absolute_url }}" data-invoice-id="{{ invoice.id }}" class="invoice-link text-blue-600 hover:text-blue-800 font-medium transition-colors duration-200">
|
||||
{{ invoice.get_type_display }} {{ invoice }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
<h2 class="mt-4">{% trans "Payment" %}</h2>
|
||||
{% if object.completed %}
|
||||
<p class="alert alert-phoenix-success mt-2">
|
||||
{% blocktrans with object.completed as completed %}
|
||||
Payment completed on: {{ completed }}
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
{% else %}
|
||||
{% if object.is_ready_for_payment %}
|
||||
{% block payment_method %}
|
||||
<p class="mt-2">
|
||||
Here should go bindings to your payment. We recommend using <a href="https://github.com/cypreess/django-getpaid">django-getpaid</a> for payment processing.
|
||||
Use a fake payment below to simulate paying for an order:
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Payment Section #}
|
||||
<div class="rounded-xl overflow-hidden mb-6">
|
||||
<div class="px-6 py-4">
|
||||
<h2 class="text-xl font-semibold text-gray-800 mb-4">
|
||||
<i class="fas fa-credit-card text-gray-400 mr-2"></i> {% trans "Payment" %}
|
||||
</h2>
|
||||
{% if object.completed %}
|
||||
<div class="bg-green-50 text-green-700 px-4 py-3 rounded-lg flex items-center">
|
||||
<i class="fas fa-check-circle mr-3 text-lg"></i>
|
||||
<p class="text-sm font-medium">
|
||||
{% blocktrans with object.completed as completed %}
|
||||
Payment completed on: {{ completed|date:"F j, Y" }}
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<a class="btn btn-phoenix-success"
|
||||
role="button"
|
||||
href="{% url "fake_payments" pk=object.id %}">Pay using
|
||||
FakePayments™ ;</a>
|
||||
{# An example code snippet for accepting payments using django-getpaid #}
|
||||
{# <form action="{% url "getpaid-new-payment" currency=object.currency %}" method="post"#}
|
||||
{# class="standard_form payment_form">#}
|
||||
{# {% csrf_token %}#}
|
||||
{# <ul>{{ payment_form.as_ul }}</ul>#}
|
||||
{# <p><label> </label><input type="submit"
|
||||
value="{% trans "Pay the order" %}"
|
||||
class="submit_button">#}
|
||||
{# </p>#}
|
||||
{# </form>#}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="alert alert-phoenix-warning mt-2">
|
||||
{% blocktrans %}
|
||||
This order is expired. It will accept an incoming payment made earlier, but new payment cannot be
|
||||
initialized. Please make a new order if necessary.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
{% if object.is_ready_for_payment %}
|
||||
<p class="text-gray-600 mb-4">
|
||||
You can use a fake payment below to simulate paying for this order.
|
||||
</p>
|
||||
<a class="inline-flex items-center px-6 py-3 border border-transparent text-base font-medium rounded-lg shadow-sm text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 transition-colors duration-200"
|
||||
role="button"
|
||||
href="{% url "fake_payments" pk=object.id %}">
|
||||
<i class="fas fa-money-bill-wave mr-2"></i>
|
||||
Pay using FakePayments™
|
||||
</a>
|
||||
{% else %}
|
||||
<div class="bg-yellow-50 text-yellow-700 px-4 py-3 rounded-lg flex items-center">
|
||||
<i class="fas fa-exclamation-triangle mr-3 text-lg"></i>
|
||||
<p class="text-sm font-medium">
|
||||
{% blocktrans %}
|
||||
This order is expired. New payments cannot be initialized. Please make a new order if necessary.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if object.status == object.STATUS.NOT_VALID %}
|
||||
<p class="alert alert-phoenix-danger">
|
||||
{% blocktrans %}
|
||||
This order could not be processed as it is not valid. Please contact with customer service.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% if object.status == object.STATUS.NOT_VALID %}
|
||||
<div class="bg-red-50 text-red-700 px-4 py-3 rounded-lg mt-4 flex items-center">
|
||||
<i class="fas fa-times-circle mr-3 text-lg"></i>
|
||||
<p class="text-sm font-medium">
|
||||
{% blocktrans %}
|
||||
This order could not be processed as it is not valid. Please contact customer service.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -104,7 +104,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2" hx-boost="false">
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
{% if estimate.status == 'draft' %}
|
||||
{% if perms.django_ledger.change_estimatemodel %}
|
||||
<button id="mark_as_sent_estimate"
|
||||
|
||||
@ -87,6 +87,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
{% include "empty-illustration-page.html" with value="invoice" url="#" %}
|
||||
{% url 'estimate_create' request.dealer.slug as url %}
|
||||
{% include "empty-illustration-page.html" with value="invoice" url=url %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
@ -119,6 +119,7 @@
|
||||
</div>
|
||||
</section>
|
||||
{% else %}
|
||||
{% include "empty-illustration-page.html" with value="sale order" url='#' %}
|
||||
{% url 'estimate_create' request.dealer.slug as url %}
|
||||
{% include "empty-illustration-page.html" with value="Sale Orders" url=url %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user