some changes in invoice
This commit is contained in:
parent
da1b53c775
commit
a03bb8ccf1
@ -801,6 +801,7 @@ class Customer(models.Model):
|
||||
middle = f" {self.middle_name}" if self.middle_name else ""
|
||||
return f"{self.first_name}{middle} {self.last_name}"
|
||||
|
||||
|
||||
@property
|
||||
def get_full_name(self):
|
||||
return f"{self.first_name} {self.middle_name} {self.last_name}"
|
||||
|
||||
@ -218,7 +218,7 @@ def create_ledger_entity(sender, instance, created, **kwargs):
|
||||
active=True,
|
||||
)
|
||||
#Create Deferred Revenue Account
|
||||
entity.create_account(
|
||||
deferred_revenue = entity.create_account(
|
||||
coa_model=coa,
|
||||
code="2060",
|
||||
role=roles.LIABILITY_CL_DEFERRED_REVENUE,
|
||||
@ -226,6 +226,9 @@ def create_ledger_entity(sender, instance, created, **kwargs):
|
||||
balance_type="credit",
|
||||
active=True,
|
||||
)
|
||||
deferred_revenue.role_default = True
|
||||
deferred_revenue.save()
|
||||
|
||||
|
||||
# Create Vendor
|
||||
@receiver(post_save, sender=models.Vendor)
|
||||
|
||||
@ -91,7 +91,7 @@ urlpatterns = [
|
||||
path('generate_invoice/<int:pk>/', views.generate_invoice, name='generate_invoice'),
|
||||
path('sales/quotations/<int:pk>/mark_quotation/', views.mark_quotation, name='mark_quotation'),
|
||||
path('sales/quotations/<int:pk>/post_quotation/', views.post_quotation, name='post_quotation'),
|
||||
path('sales/quotations/<int:pk>/invoice_detail/', views.invoice_detail, name='invoice_detail'),
|
||||
# path('sales/quotations/<int:pk>/invoice_detail/', views.invoice_detail, name='invoice_detail'),
|
||||
path('subscriptions', views.SubscriptionPlans.as_view(), name='subscriptions'),
|
||||
#Payment URLs
|
||||
# path('sales/quotations/<int:pk>/payment/', views.PaymentCreateView.as_view(), name='payment_create'),
|
||||
@ -140,6 +140,7 @@ urlpatterns = [
|
||||
path('sales/estimates/<uuid:pk>/send_email', views.send_email_view, name='send_email'),
|
||||
# Invoice
|
||||
path('sales/invoices/', views.InvoiceListView.as_view(), name='invoice_list'),
|
||||
path('sales/invoices/create/', views.invoice_create, name='invoice_create'),
|
||||
path('sales/invoices/<uuid:pk>/create/', views.invoice_create, name='invoice_create'),
|
||||
path('sales/invoices/<uuid:pk>/', views.InvoiceDetailView.as_view(), name='invoice_detail'),
|
||||
path('sales/invoices/<uuid:pk>/preview/', views.InvoicePreviewView.as_view(), name='invoice_preview'),
|
||||
|
||||
@ -749,7 +749,12 @@ class CustomerDetailView(LoginRequiredMixin, DetailView):
|
||||
model = models.Customer
|
||||
template_name = "customers/view_customer.html"
|
||||
context_object_name = "customer"
|
||||
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
name = f"{context['customer'].first_name} {context['customer'].middle_name} {context['customer'].last_name}"
|
||||
context["estimates"] = self.request.entity.get_estimates().filter(customer__customer_name=name)
|
||||
return context
|
||||
|
||||
class CustomerCreateView(
|
||||
LoginRequiredMixin,
|
||||
@ -1274,23 +1279,6 @@ def UserDeleteview(request, pk):
|
||||
return redirect("user_list")
|
||||
|
||||
|
||||
# errors
|
||||
def custom_page_not_found_view(request, exception):
|
||||
return render(request, "errors/404.html", {})
|
||||
|
||||
|
||||
def custom_error_view(request, exception=None):
|
||||
return render(request, "errors/500.html", {})
|
||||
|
||||
|
||||
def custom_permission_denied_view(request, exception=None):
|
||||
return render(request, "errors/403.html", {})
|
||||
|
||||
|
||||
def custom_bad_request_view(request, exception=None):
|
||||
return render(request, "errors/400.html", {})
|
||||
|
||||
|
||||
class OrganizationListView(LoginRequiredMixin, ListView):
|
||||
model = models.Organization
|
||||
template_name = "organizations/organization_list.html"
|
||||
@ -1378,31 +1366,6 @@ class RepresentativeDeleteView(LoginRequiredMixin, SuccessMessageMixin, DeleteVi
|
||||
success_message = "Representative deleted successfully."
|
||||
|
||||
|
||||
# def quotation_pdf_view(request, pk):
|
||||
# # Get the quotation object
|
||||
# quotation = models.SaleQuotation.objects.get(pk=pk)
|
||||
#
|
||||
# # Render the HTML template for the quotation page
|
||||
# context = {
|
||||
# "quotation": quotation,
|
||||
# }
|
||||
# context_result = get_calculations(quotation)
|
||||
# context = context.update(context_result)
|
||||
#
|
||||
# html_content = render_to_string("sales/quotation_pdf.html", context)
|
||||
#
|
||||
# # Create a PDF file
|
||||
#
|
||||
# pdf_file = HTML(string=html_content).render()
|
||||
#
|
||||
# # Save the PDF file to a file
|
||||
# with open("quotation.pdf", "wb") as f:
|
||||
# f.write(pdf_file.write_pdf())
|
||||
#
|
||||
# # Return the PDF file as a response
|
||||
# return HttpResponse(pdf_file, content_type="application/pdf")
|
||||
|
||||
|
||||
@login_required
|
||||
def download_quotation_pdf(request, quotation_id):
|
||||
try:
|
||||
@ -1427,59 +1390,40 @@ def download_quotation_pdf(request, quotation_id):
|
||||
return HttpResponse("Quotation not found", status=404)
|
||||
|
||||
|
||||
@login_required
|
||||
def invoice_detail(request, pk):
|
||||
quotation = get_object_or_404(models.SaleQuotation, pk=pk)
|
||||
dealer = request.user.dealer
|
||||
entity = dealer.entity
|
||||
customer = (
|
||||
entity.get_customers()
|
||||
.filter(customer_name=quotation.customer.get_full_name)
|
||||
.first()
|
||||
)
|
||||
invoice_model = entity.get_invoices()
|
||||
# @login_required
|
||||
# def invoice_detail(request, pk):
|
||||
# quotation = get_object_or_404(models.SaleQuotation, pk=pk)
|
||||
# dealer = request.user.dealer
|
||||
# entity = dealer.entity
|
||||
# customer = (
|
||||
# entity.get_customers()
|
||||
# .filter(customer_name=quotation.customer.get_full_name)
|
||||
# .first()
|
||||
# )
|
||||
# invoice_model = entity.get_invoices()
|
||||
|
||||
invoice = invoice_model.filter(
|
||||
customer=customer, date_draft=quotation.date_draft
|
||||
).first()
|
||||
return redirect("quotation_detail", pk=pk)
|
||||
# invoice = invoice_model.filter(
|
||||
# customer=customer, date_draft=quotation.date_draft
|
||||
# ).first()
|
||||
# return redirect("quotation_detail", pk=pk)
|
||||
|
||||
|
||||
@login_required
|
||||
def payment_invoice(request, pk):
|
||||
quotation = get_object_or_404(models.SaleQuotation, pk=pk)
|
||||
dealer = request.user.dealer
|
||||
entity = dealer.entity
|
||||
customer = (
|
||||
entity.get_customers()
|
||||
.filter(customer_name=quotation.customer.get_full_name)
|
||||
.first()
|
||||
)
|
||||
invoice_model = entity.get_invoices()
|
||||
invoice = invoice_model.filter(
|
||||
customer=customer, date_draft=quotation.date_draft
|
||||
).first()
|
||||
|
||||
return redirect("quotation_detail", pk=pk)
|
||||
|
||||
|
||||
# class PaymentCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
|
||||
# model = models.Payment
|
||||
# form_class = forms.PaymentForm
|
||||
# template_name = "sales/payments/payment_form.html"
|
||||
# success_url = reverse_lazy("quotation_list")
|
||||
# success_message = "Payment created successfully."
|
||||
|
||||
# def form_valid(self, form):
|
||||
# quotation = get_object_or_404(models.SaleQuotation, pk=self.kwargs["pk"])
|
||||
# form.instance.quotation = quotation
|
||||
# form.save()
|
||||
# return super().form_valid(form)
|
||||
# def get_context_data(self, **kwargs):
|
||||
# context = super().get_context_data(**kwargs)
|
||||
# context["quotation"] = get_object_or_404(models.SaleQuotation, pk=self.kwargs["pk"])
|
||||
# return context
|
||||
# @login_required
|
||||
# def payment_invoice(request, pk):
|
||||
# quotation = get_object_or_404(models.SaleQuotation, pk=pk)
|
||||
# dealer = request.user.dealer
|
||||
# entity = dealer.entity
|
||||
# customer = (
|
||||
# entity.get_customers()
|
||||
# .filter(customer_name=quotation.customer.get_full_name)
|
||||
# .first()
|
||||
# )
|
||||
# invoice_model = entity.get_invoices()
|
||||
# invoice = invoice_model.filter(
|
||||
# customer=customer, date_draft=quotation.date_draft
|
||||
# ).first()
|
||||
|
||||
# return redirect("quotation_detail", pk=pk)
|
||||
|
||||
def payment_create(request, pk):
|
||||
quotation = get_object_or_404(models.SaleQuotation, pk=pk)
|
||||
@ -1629,7 +1573,6 @@ def bank_account_delete(request, pk):
|
||||
|
||||
# Accounts
|
||||
|
||||
|
||||
class AccountListView(LoginRequiredMixin, ListView):
|
||||
model = AccountModel
|
||||
template_name = "ledger/coa_accounts/account_list.html"
|
||||
@ -1705,36 +1648,6 @@ class EstimateListView(LoginRequiredMixin, ListView):
|
||||
return entity.get_estimates()
|
||||
|
||||
|
||||
# class EstimateCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
|
||||
# model = EstimateModel
|
||||
# form_class = EstimateModelCreateForm
|
||||
# template_name = "sales/estimates/estimate_form.html"
|
||||
# success_url = reverse_lazy("estimate_list")
|
||||
# success_message = "Estimate created successfully."
|
||||
|
||||
# def get_form_kwargs(self):
|
||||
# """
|
||||
# Override this method to pass additional keyword arguments to the form.
|
||||
# """
|
||||
# entity = self.request.user.dealer.entity
|
||||
# kwargs = super().get_form_kwargs()
|
||||
# kwargs['entity_slug'] = entity.slug
|
||||
# kwargs['user_model'] = entity.admin
|
||||
# return kwargs
|
||||
|
||||
# def get_context_data(self, **kwargs):
|
||||
# entity = self.request.user.dealer.entity
|
||||
# kwargs['items'] = entity.get_items_all()
|
||||
# return super().get_context_data(**kwargs)
|
||||
# def get_customer_queryset(self):
|
||||
# entity = self.request.user.dealer.entity
|
||||
# return entity.get_customer_queryset()
|
||||
|
||||
# def form_valid(self, form):
|
||||
# form.instance.entity = self.request.user.dealer.entity
|
||||
# return super().form_valid(form)
|
||||
|
||||
|
||||
# @csrf_exempt
|
||||
@login_required
|
||||
def create_estimate(request):
|
||||
@ -1831,12 +1744,12 @@ def create_estimate(request):
|
||||
for item in items:
|
||||
item_instance = ItemModel.objects.get(pk=item)
|
||||
instance = models.Car.objects.get(vin=item_instance.name)
|
||||
response = reserve_car(instance, request)
|
||||
reserve_car(instance, request)
|
||||
|
||||
else:
|
||||
item_instance = ItemModel.objects.get(pk=items)
|
||||
instance = models.Car.objects.get(vin=item_instance.name)
|
||||
response = reserve_car(instance, request)
|
||||
reserve_car(instance, request)
|
||||
|
||||
url = reverse("estimate_detail", kwargs={"pk": estimate.pk})
|
||||
return JsonResponse(
|
||||
@ -1846,16 +1759,7 @@ def create_estimate(request):
|
||||
"url": f"{url}",
|
||||
}
|
||||
)
|
||||
|
||||
# except Exception as e:
|
||||
# return JsonResponse(
|
||||
# {
|
||||
# "status": "error",
|
||||
# "message": f"An error occurred while processing the request: {str(e)}",
|
||||
# },
|
||||
# status=400,
|
||||
# )
|
||||
|
||||
|
||||
form = EstimateModelCreateForm(entity_slug=entity.slug, user_model=entity.admin)
|
||||
car_list = models.Car.objects.filter(
|
||||
dealer=dealer, finances__selling_price__gt=0
|
||||
@ -1894,13 +1798,10 @@ class EstimateDetailView(LoginRequiredMixin, DetailView):
|
||||
)
|
||||
vat = models.VatRate.objects.filter(is_active=True).first()
|
||||
|
||||
# Calculate VAT and total with 2 decimal places
|
||||
vat_amount = round(total * vat.vat_rate, 2) # Round to 2 decimal places
|
||||
vat_amount = round(total * vat.vat_rate, 2)
|
||||
grand_total = round(
|
||||
(total * vat.vat_rate) + total, 2
|
||||
) # Round to 2 decimal places
|
||||
|
||||
# Add values to the context
|
||||
)
|
||||
kwargs["vat_amount"] = vat_amount
|
||||
kwargs["total"] = grand_total
|
||||
kwargs["vat"] = vat.rate
|
||||
@ -1945,7 +1846,6 @@ class EstimatePreviewView(LoginRequiredMixin, DetailView):
|
||||
@login_required
|
||||
def estimate_mark_as(request, pk):
|
||||
estimate = get_object_or_404(EstimateModel, pk=pk)
|
||||
entity = estimate.entity
|
||||
mark = request.GET.get("mark")
|
||||
if mark:
|
||||
if mark == "review":
|
||||
@ -1953,13 +1853,11 @@ def estimate_mark_as(request, pk):
|
||||
messages.error(request, "Estimate is not ready for review")
|
||||
return redirect("estimate_detail", pk=estimate.pk)
|
||||
estimate.mark_as_review()
|
||||
|
||||
elif mark == "approved":
|
||||
if not estimate.can_approve():
|
||||
messages.error(request, "Estimate is not ready for approval")
|
||||
return redirect("estimate_detail", pk=estimate.pk)
|
||||
estimate.mark_as_approved()
|
||||
|
||||
messages.success(request, "Estimate approved successfully.")
|
||||
elif mark == "rejected":
|
||||
if not estimate.can_cancel():
|
||||
@ -1967,36 +1865,10 @@ def estimate_mark_as(request, pk):
|
||||
return redirect("estimate_detail", pk=estimate.pk)
|
||||
estimate.mark_as_canceled()
|
||||
messages.success(request, "Estimate canceled successfully.")
|
||||
|
||||
elif mark == "completed":
|
||||
if not estimate.can_complete():
|
||||
messages.error(request, "Estimate is not ready for completion")
|
||||
return redirect("estimate_detail", pk=estimate.pk)
|
||||
|
||||
# invoice = entity.create_invoice(customer_model=estimate.customer,
|
||||
# terms=estimate.terms,
|
||||
# cash_account=entity.get_default_coa_accounts().get(name="Cash"),
|
||||
# prepaid_account=entity.get_default_coa_accounts().get(name="Accounts Receivable"),
|
||||
# coa_model=entity.get_default_coa()
|
||||
# )
|
||||
|
||||
# unit_items = estimate.get_itemtxs_data()[0]
|
||||
# invoice_itemtxs = {
|
||||
# i.item_model.item_number: {
|
||||
# 'unit_cost': i.ce_unit_cost_estimate,
|
||||
# 'quantity': i.ce_quantity,
|
||||
# 'total_amount': i.ce_cost_estimate
|
||||
# } for i in unit_items
|
||||
# }
|
||||
|
||||
# invoice_itemtxs = invoice.migrate_itemtxs(itemtxs=invoice_itemtxs,
|
||||
# commit=True,
|
||||
# operation=InvoiceModel.ITEMIZE_APPEND)
|
||||
# invoice.bind_estimate(estimate)
|
||||
# invoice.mark_as_review()
|
||||
# estimate.mark_as_completed()
|
||||
# estimate.save()
|
||||
# invoice.save()
|
||||
return redirect("estimate_detail", pk=estimate.pk)
|
||||
estimate.save()
|
||||
messages.success(request, "Estimate marked as " + mark.upper())
|
||||
|
||||
@ -2032,6 +1904,7 @@ class InvoiceDetailView(LoginRequiredMixin, DetailView):
|
||||
kwargs["vat_amount"] = total * vat.vat_rate
|
||||
kwargs["total"] = (total * vat.vat_rate) + total
|
||||
kwargs["vat"] = vat.rate
|
||||
kwargs["amount_left"] = invoice.amount_due - invoice.amount_paid
|
||||
kwargs["payments"] = JournalEntryModel.objects.filter(
|
||||
ledger=invoice.ledger
|
||||
).all()
|
||||
@ -2067,7 +1940,7 @@ def invoice_mark_as(request, pk):
|
||||
|
||||
def invoice_create(request, pk):
|
||||
estimate = get_object_or_404(EstimateModel, pk=pk)
|
||||
entity = request.user.dealer.entity
|
||||
entity = request.entity
|
||||
|
||||
form = InvoiceModelCreateForm(entity_slug=entity.slug, user_model=entity.admin)
|
||||
if request.method == "POST":
|
||||
@ -2081,6 +1954,7 @@ def invoice_create(request, pk):
|
||||
terms=invoice.terms,
|
||||
cash_account=invoice.cash_account,
|
||||
prepaid_account=invoice.prepaid_account,
|
||||
payable_account=invoice.unearned_account,
|
||||
coa_model=entity.get_default_coa(),
|
||||
)
|
||||
ledger = entity.create_ledger(name=f"Invoice {str(invoice_model.pk)}")
|
||||
@ -2242,58 +2116,6 @@ class UserActivityLogListView(ListView):
|
||||
return queryset
|
||||
|
||||
|
||||
# email
|
||||
def send_email_view(request, pk):
|
||||
estimate = get_object_or_404(EstimateModel, pk=pk)
|
||||
if request.method == "POST":
|
||||
# if not estimate.can_review():
|
||||
# messages.error(request, "Estimate is not ready for review")
|
||||
# return redirect("estimate_detail", pk=estimate.pk)
|
||||
if not estimate.get_itemtxs_data()[0]:
|
||||
messages.error(request, "Estimate has no items")
|
||||
return redirect("estimate_detail", pk=estimate.pk)
|
||||
|
||||
send_email(
|
||||
"manager@tenhal.com",
|
||||
request.POST.get("to"),
|
||||
request.POST.get("subject"),
|
||||
request.POST.get("message"),
|
||||
)
|
||||
# estimate.mark_as_review()
|
||||
messages.success(request, "Email sent successfully!")
|
||||
return redirect("estimate_detail", pk=estimate.pk)
|
||||
link = reverse_lazy("estimate_preview", kwargs={"pk": estimate.pk})
|
||||
msg = f"""
|
||||
السلام عليكم
|
||||
Dear {estimate.customer.customer_name},
|
||||
|
||||
أود أن أشارككم تقدير المشروع الذي ناقشناه. يرجى العثور على الوثيقة التفصيلية للمقترح المرفقة.
|
||||
|
||||
I hope this email finds you well. I wanted to share with you the estimate for the project we discussed. Please find the detailed estimate document attached.
|
||||
|
||||
يرجى مراجعة المقترح وإعلامي إذا كانت لديك أي أسئلة أو مخاوف. إذا كانت كل شيء يبدو جيدًا، يمكننا المضي قدمًا في المشروع.
|
||||
|
||||
Please review the estimate and let me know if you have any questions or concerns. If everything looks good, we can proceed with the project.
|
||||
|
||||
Estimate Link:
|
||||
{link}
|
||||
|
||||
شكراً لاهتمامكم بهذا الأمر.
|
||||
Thank you for your attention to this matter.
|
||||
|
||||
تحياتي,
|
||||
Best regards,
|
||||
[Your Name]
|
||||
[Your Position]
|
||||
[Your Company]
|
||||
[Your Contact Information]
|
||||
"""
|
||||
return render(
|
||||
request,
|
||||
"sales/estimates/estimate_send.html",
|
||||
{"estimate": estimate, "message": msg},
|
||||
)
|
||||
|
||||
|
||||
# CRM RELATED VIEWS
|
||||
def create_lead(request, pk):
|
||||
@ -2467,3 +2289,72 @@ class SubscriptionPlans(ListView):
|
||||
model = models.SubscriptionPlan
|
||||
template_name = "subscriptions/subscription_plan.html"
|
||||
context_object_name = "plans"
|
||||
|
||||
|
||||
# email
|
||||
def send_email_view(request, pk):
|
||||
estimate = get_object_or_404(EstimateModel, pk=pk)
|
||||
if request.method == "POST":
|
||||
# if not estimate.can_review():
|
||||
# messages.error(request, "Estimate is not ready for review")
|
||||
# return redirect("estimate_detail", pk=estimate.pk)
|
||||
if not estimate.get_itemtxs_data()[0]:
|
||||
messages.error(request, "Estimate has no items")
|
||||
return redirect("estimate_detail", pk=estimate.pk)
|
||||
|
||||
send_email(
|
||||
"manager@tenhal.com",
|
||||
request.POST.get("to"),
|
||||
request.POST.get("subject"),
|
||||
request.POST.get("message"),
|
||||
)
|
||||
# estimate.mark_as_review()
|
||||
messages.success(request, "Email sent successfully!")
|
||||
return redirect("estimate_detail", pk=estimate.pk)
|
||||
link = reverse_lazy("estimate_preview", kwargs={"pk": estimate.pk})
|
||||
msg = f"""
|
||||
السلام عليكم
|
||||
Dear {estimate.customer.customer_name},
|
||||
|
||||
أود أن أشارككم تقدير المشروع الذي ناقشناه. يرجى العثور على الوثيقة التفصيلية للمقترح المرفقة.
|
||||
|
||||
I hope this email finds you well. I wanted to share with you the estimate for the project we discussed. Please find the detailed estimate document attached.
|
||||
|
||||
يرجى مراجعة المقترح وإعلامي إذا كانت لديك أي أسئلة أو مخاوف. إذا كانت كل شيء يبدو جيدًا، يمكننا المضي قدمًا في المشروع.
|
||||
|
||||
Please review the estimate and let me know if you have any questions or concerns. If everything looks good, we can proceed with the project.
|
||||
|
||||
Estimate Link:
|
||||
{link}
|
||||
|
||||
شكراً لاهتمامكم بهذا الأمر.
|
||||
Thank you for your attention to this matter.
|
||||
|
||||
تحياتي,
|
||||
Best regards,
|
||||
[Your Name]
|
||||
[Your Position]
|
||||
[Your Company]
|
||||
[Your Contact Information]
|
||||
"""
|
||||
return render(
|
||||
request,
|
||||
"sales/estimates/estimate_send.html",
|
||||
{"estimate": estimate, "message": msg},
|
||||
)
|
||||
|
||||
# errors
|
||||
def custom_page_not_found_view(request, exception):
|
||||
return render(request, "errors/404.html", {})
|
||||
|
||||
|
||||
def custom_error_view(request, exception=None):
|
||||
return render(request, "errors/500.html", {})
|
||||
|
||||
|
||||
def custom_permission_denied_view(request, exception=None):
|
||||
return render(request, "errors/403.html", {})
|
||||
|
||||
|
||||
def custom_bad_request_view(request, exception=None):
|
||||
return render(request, "errors/400.html", {})
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
</button>
|
||||
<a type="button"
|
||||
class="btn btn-sm btn-danger"
|
||||
href="{% url 'customer_delete' customer.id %}">
|
||||
href="{% url 'customer_delete' customer.pk %}">
|
||||
{% trans 'Yes' %}
|
||||
</a>
|
||||
</div>
|
||||
@ -37,8 +37,7 @@
|
||||
<!-- Delete Modal -->
|
||||
|
||||
<div class="container">
|
||||
|
||||
<div class="mb-9">
|
||||
<div class="mb-9">
|
||||
<div class="row align-items-center justify-content-between g-3 mb-4">
|
||||
<div class="col-auto">
|
||||
<h3 class="mb-0">{% trans 'Customer details' %}</h3>
|
||||
@ -119,7 +118,7 @@
|
||||
</div>
|
||||
<div class="col-12 col-xxl-8">
|
||||
<div class="mb-6">
|
||||
<h3 class="mb-4">{{ _("Cars") }} <span class="text-body-tertiary fw-normal">(4)</span></h3>
|
||||
<h3 class="mb-4">{{ _("Cars") }} <span class="text-body-tertiary fw-normal">({{ estimates.count }})</span></h3>
|
||||
<div class="border-top border-bottom border-translucent" id="customerOrdersTable" data-list='{"valueNames":["order","total","payment_status","fulfilment_status","delivery_type","date"],"page":6,"pagination":true}'>
|
||||
<div class="table-responsive scrollbar">
|
||||
<table class="table table-sm fs-9 mb-0">
|
||||
@ -135,10 +134,21 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list" id="customer-order-table-body">
|
||||
{% for estimate in estimates %}
|
||||
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
|
||||
<td class="order align-middle white-space-nowrap ps-0"><a class="fw-semibold" href="#!">#2453</a></td>
|
||||
<td class="order align-middle white-space-nowrap ps-0"><a class="fw-semibold" href="{% url 'estimate_detail' estimate.pk %}">#{{ estimate.estimate_number }}</a></td>
|
||||
<td class="total align-middle text-end fw-semibold pe-7 text-body-highlight">$87</td>
|
||||
<td class="payment_status align-middle white-space-nowrap text-start fw-bold text-body-tertiary"><span class="badge badge-phoenix fs-10 badge-phoenix-success"><span class="badge-label">Paid</span><span class="ms-1" data-feather="check" style="height:12.8px;width:12.8px;"></span></span></td>
|
||||
<td class="payment_status align-middle white-space-nowrap text-start fw-bold text-body-tertiary">
|
||||
{% if estimate.is_draft %}
|
||||
<span class="badge badge-phoenix badge-phoenix-warning text-uppercase">{% trans 'Draft' %}</span>
|
||||
{% elif estimate.is_review %}
|
||||
<span class="badge badge-phoenix badge-phoenix-info text-uppercase">{% trans 'Review' %}</span>
|
||||
{% elif estimate.is_approved %}
|
||||
<span class="badge badge-phoenix badge-phoenix-success text-uppercase">{% trans 'Approved' %}</span>
|
||||
{% else %}
|
||||
<span class="badge badge-phoenix badge-phoenix-success text-uppercase">{% trans 'Paid' %}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="fulfilment_status align-middle white-space-nowrap text-start fw-bold text-body-tertiary"><span class="badge badge-phoenix fs-10 badge-phoenix-success"><span class="badge-label">Order Fulfilled</span><span class="ms-1" data-feather="check" style="height:12.8px;width:12.8px;"></span></span></td>
|
||||
<td class="delivery_type align-middle white-space-nowrap text-body fs-9 text-start">Cash on delivery</td>
|
||||
<td class="date align-middle white-space-nowrap text-body-tertiary fs-9 ps-4 text-end">Dec 12, 12:56 PM</td>
|
||||
@ -151,55 +161,7 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
|
||||
<td class="order align-middle white-space-nowrap ps-0"><a class="fw-semibold" href="#!">#2452</a></td>
|
||||
<td class="total align-middle text-end fw-semibold pe-7 text-body-highlight">$7264</td>
|
||||
<td class="payment_status align-middle white-space-nowrap text-start fw-bold text-body-tertiary"><span class="badge badge-phoenix fs-10 badge-phoenix-secondary"><span class="badge-label">Cancelled</span><span class="ms-1" data-feather="x" style="height:12.8px;width:12.8px;"></span></span></td>
|
||||
<td class="fulfilment_status align-middle white-space-nowrap text-start fw-bold text-body-tertiary"><span class="badge badge-phoenix fs-10 badge-phoenix-info"><span class="badge-label">Ready to pickup</span><span class="ms-1" data-feather="info" style="height:12.8px;width:12.8px;"></span></span></td>
|
||||
<td class="delivery_type align-middle white-space-nowrap text-body fs-9 text-start">Free shipping</td>
|
||||
<td class="date align-middle white-space-nowrap text-body-tertiary fs-9 ps-4 text-end">Dec 9, 2:28PM</td>
|
||||
<td class="align-middle white-space-nowrap text-end pe-0 ps-5">
|
||||
<div class="btn-reveal-trigger position-static">
|
||||
<button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10" type="button" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h fs-10"></span></button>
|
||||
<div class="dropdown-menu dropdown-menu-end py-2"><a class="dropdown-item" href="#!">View</a><a class="dropdown-item" href="#!">Export</a>
|
||||
<div class="dropdown-divider"></div><a class="dropdown-item text-danger" href="#!">Remove</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
|
||||
<td class="order align-middle white-space-nowrap ps-0"><a class="fw-semibold" href="#!">#2451</a></td>
|
||||
<td class="total align-middle text-end fw-semibold pe-7 text-body-highlight">$375</td>
|
||||
<td class="payment_status align-middle white-space-nowrap text-start fw-bold text-body-tertiary"><span class="badge badge-phoenix fs-10 badge-phoenix-warning"><span class="badge-label">Pending</span><span class="ms-1" data-feather="alert-octagon" style="height:12.8px;width:12.8px;"></span></span></td>
|
||||
<td class="fulfilment_status align-middle white-space-nowrap text-start fw-bold text-body-tertiary"><span class="badge badge-phoenix fs-10 badge-phoenix-warning"><span class="badge-label">Partial FulfiLled</span><span class="ms-1" data-feather="alert-octagon" style="height:12.8px;width:12.8px;"></span></span></td>
|
||||
<td class="delivery_type align-middle white-space-nowrap text-body fs-9 text-start">Local pickup</td>
|
||||
<td class="date align-middle white-space-nowrap text-body-tertiary fs-9 ps-4 text-end">Dec 4, 12:56 PM</td>
|
||||
<td class="align-middle white-space-nowrap text-end pe-0 ps-5">
|
||||
<div class="btn-reveal-trigger position-static">
|
||||
<button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10" type="button" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h fs-10"></span></button>
|
||||
<div class="dropdown-menu dropdown-menu-end py-2"><a class="dropdown-item" href="#!">View</a><a class="dropdown-item" href="#!">Export</a>
|
||||
<div class="dropdown-divider"></div><a class="dropdown-item text-danger" href="#!">Remove</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
|
||||
<td class="order align-middle white-space-nowrap ps-0"><a class="fw-semibold" href="#!">#2450</a></td>
|
||||
<td class="total align-middle text-end fw-semibold pe-7 text-body-highlight">$657</td>
|
||||
<td class="payment_status align-middle white-space-nowrap text-start fw-bold text-body-tertiary"><span class="badge badge-phoenix fs-10 badge-phoenix-secondary"><span class="badge-label">Cancelled</span><span class="ms-1" data-feather="x" style="height:12.8px;width:12.8px;"></span></span></td>
|
||||
<td class="fulfilment_status align-middle white-space-nowrap text-start fw-bold text-body-tertiary"><span class="badge badge-phoenix fs-10 badge-phoenix-secondary"><span class="badge-label">Order CancelLed</span><span class="ms-1" data-feather="x" style="height:12.8px;width:12.8px;"></span></span></td>
|
||||
<td class="delivery_type align-middle white-space-nowrap text-body fs-9 text-start">Standard shipping</td>
|
||||
<td class="date align-middle white-space-nowrap text-body-tertiary fs-9 ps-4 text-end">Dec 1, 4:07 AM</td>
|
||||
<td class="align-middle white-space-nowrap text-end pe-0 ps-5">
|
||||
<div class="btn-reveal-trigger position-static">
|
||||
<button class="btn btn-sm dropdown-toggle dropdown-caret-none transition-none btn-reveal fs-10" type="button" data-bs-toggle="dropdown" data-boundary="window" aria-haspopup="true" aria-expanded="false" data-bs-reference="parent"><span class="fas fa-ellipsis-h fs-10"></span></button>
|
||||
<div class="dropdown-menu dropdown-menu-end py-2"><a class="dropdown-item" href="#!">View</a><a class="dropdown-item" href="#!">Export</a>
|
||||
<div class="dropdown-divider"></div><a class="dropdown-item text-danger" href="#!">Remove</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@ -55,6 +55,7 @@
|
||||
<div>
|
||||
<p class="fw-bold mb-1">{% trans 'Paid Amount' %}</p>
|
||||
<h4 class="fw-bolder text-nowrap">${{invoice.amount_paid}}</h4>
|
||||
<h6 class="fw-normal text-nowrap text-success">${{amount_left}} Left</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user