update
This commit is contained in:
commit
f84c07b8e3
1
.gitignore
vendored
1
.gitignore
vendored
@ -71,6 +71,7 @@ wheels/
|
||||
*.egg
|
||||
*.manifest
|
||||
*.spec
|
||||
inventory/management/commands/run.py
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
@ -179,6 +179,10 @@ urlpatterns = [
|
||||
path('items/expeneses/', views.ItemExpenseListView.as_view(), name='item_expense_list'),
|
||||
path('items/expeneses/create/', views.ItemExpenseCreateView.as_view(), name='item_expense_create'),
|
||||
path('items/expeneses/<uuid:pk>/update/', views.ItemExpenseUpdateView.as_view(), name='item_expense_update'),
|
||||
# Bills
|
||||
path('items/bills/', views.BillListView.as_view(), name='bill_list'),
|
||||
path('items/bills/create/', views.BillCreateView.as_view(), name='bill_create'),
|
||||
# path('items/bills/<uuid:pk>/update/', views.ItemExpenseUpdateView.as_view(), name='item_expense_update'),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@ -14,11 +14,13 @@ from django_ledger.models import (
|
||||
CustomerModel,
|
||||
LedgerModel,
|
||||
ItemModel,
|
||||
BillModel
|
||||
)
|
||||
from django_ledger.forms.bank_account import (
|
||||
BankAccountCreateForm,
|
||||
BankAccountUpdateForm,
|
||||
)
|
||||
from django_ledger.forms.bill import BillModelCreateForm
|
||||
from django_ledger.forms.invoice import (
|
||||
DraftInvoiceModelUpdateForm,
|
||||
ApprovedInvoiceModelUpdateForm,
|
||||
@ -89,7 +91,6 @@ import numpy as np
|
||||
from pyzbar.pyzbar import decode
|
||||
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
@ -477,7 +478,7 @@ class AjaxHandlerView(LoginRequiredMixin, View):
|
||||
return JsonResponse(serialized_options, safe=False)
|
||||
|
||||
|
||||
@method_decorator(csrf_exempt, name='dispatch')
|
||||
@method_decorator(csrf_exempt, name="dispatch")
|
||||
class SearchCodeView(View):
|
||||
template_name = "inventory/scan_vin.html"
|
||||
|
||||
@ -486,27 +487,29 @@ class SearchCodeView(View):
|
||||
return render(request, self.template_name)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
image_file = request.FILES.get('image')
|
||||
image_file = request.FILES.get("image")
|
||||
|
||||
if image_file:
|
||||
print("image received!")
|
||||
image = cv2.imdecode(np.frombuffer(image_file.read(), np.uint8), cv2.IMREAD_COLOR)
|
||||
image = cv2.imdecode(
|
||||
np.frombuffer(image_file.read(), np.uint8), cv2.IMREAD_COLOR
|
||||
)
|
||||
decoded_objects = decode(image)
|
||||
if decoded_objects:
|
||||
print("image decoded!")
|
||||
print(decoded_objects[0])
|
||||
code = decoded_objects[0].data.decode('utf-8')
|
||||
code = decoded_objects[0].data.decode("utf-8")
|
||||
print("code received!")
|
||||
print(code)
|
||||
car = get_object_or_404(models.Car, vin=code)
|
||||
name = car.id_car_make.get_local_name
|
||||
print(name)
|
||||
return redirect('car_detail', pk=car.pk)
|
||||
return redirect("car_detail", pk=car.pk)
|
||||
else:
|
||||
print("back to else statement")
|
||||
return JsonResponse({'success': False, 'error': 'No code detected'})
|
||||
return JsonResponse({"success": False, "error": "No code detected"})
|
||||
else:
|
||||
return JsonResponse({'success': False, 'error': 'No image provided'})
|
||||
return JsonResponse({"success": False, "error": "No image provided"})
|
||||
|
||||
|
||||
class CarInventory(LoginRequiredMixin, ListView):
|
||||
@ -682,7 +685,9 @@ class CarFinanceCreateView(LoginRequiredMixin, CreateView):
|
||||
def get_form(self, form_class=None):
|
||||
form = super().get_form(form_class)
|
||||
dealer = get_user_type(self.request)
|
||||
form.fields["additional_finances"].queryset = models.AdditionalServices.objects.filter(dealer=dealer)
|
||||
form.fields[
|
||||
"additional_finances"
|
||||
].queryset = models.AdditionalServices.objects.filter(dealer=dealer)
|
||||
return form
|
||||
|
||||
# def get_initial(self):
|
||||
@ -1888,25 +1893,35 @@ class AccountDetailView(LoginRequiredMixin, DetailView):
|
||||
model = AccountModel
|
||||
template_name = "ledger/coa_accounts/account_detail.html"
|
||||
context_object_name = "account"
|
||||
slug_field = 'uuid'
|
||||
slug_field = "uuid"
|
||||
DEFAULT_TXS_DAYS = 30
|
||||
extra_context = {
|
||||
'DEFAULT_TXS_DAYS': DEFAULT_TXS_DAYS,
|
||||
'header_subtitle_icon': 'ic:round-account-tree'
|
||||
"DEFAULT_TXS_DAYS": DEFAULT_TXS_DAYS,
|
||||
"header_subtitle_icon": "ic:round-account-tree",
|
||||
}
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
account_model: AccountModel = context['object']
|
||||
context['header_title'] = f'Account {account_model.code} - {account_model.name}'
|
||||
context['page_title'] = f'Account {account_model.code} - {account_model.name}'
|
||||
txs_qs = account_model.transactionmodel_set.all().posted().order_by(
|
||||
'journal_entry__timestamp'
|
||||
).select_related(
|
||||
'journal_entry',
|
||||
'journal_entry__entity_unit',
|
||||
'journal_entry__ledger__billmodel',
|
||||
'journal_entry__ledger__invoicemodel',
|
||||
account_model: AccountModel = context["object"]
|
||||
context["header_title"] = f"Account {account_model.code} - {account_model.name}"
|
||||
context["page_title"] = f"Account {account_model.code} - {account_model.name}"
|
||||
context["total_debits"] = sum(
|
||||
x.amount for x in account_model.transactionmodel_set.filter(tx_type="debit")
|
||||
)
|
||||
context["total_credits"] = sum(
|
||||
x.amount
|
||||
for x in account_model.transactionmodel_set.filter(tx_type="credit")
|
||||
)
|
||||
txs_qs = (
|
||||
account_model.transactionmodel_set.all()
|
||||
.posted()
|
||||
.order_by("journal_entry__timestamp")
|
||||
.select_related(
|
||||
"journal_entry",
|
||||
"journal_entry__entity_unit",
|
||||
"journal_entry__ledger__billmodel",
|
||||
"journal_entry__ledger__invoicemodel",
|
||||
)
|
||||
)
|
||||
|
||||
return context
|
||||
@ -1921,10 +1936,11 @@ class AccountUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
|
||||
|
||||
def get_form(self, form_class=None):
|
||||
form = super().get_form(form_class)
|
||||
form.fields['_ref_node_id'].widget = HiddenInput()
|
||||
form.fields['_position'].widget = HiddenInput()
|
||||
form.fields["_ref_node_id"].widget = HiddenInput()
|
||||
form.fields["_position"].widget = HiddenInput()
|
||||
return form
|
||||
|
||||
|
||||
@login_required
|
||||
def account_delete(request, pk):
|
||||
account = get_object_or_404(AccountModel, pk=pk)
|
||||
@ -2038,7 +2054,7 @@ def create_estimate(request):
|
||||
{
|
||||
"item_number": item_instance.item_number,
|
||||
"quantity": Decimal(item.get("quantity")),
|
||||
"unit_cost": car_instance.finances.cost_price,
|
||||
"unit_cost": car_instance.finances.selling_price,
|
||||
"unit_revenue": car_instance.finances.selling_price,
|
||||
"total_amount": (car_instance.finances.total_vat)
|
||||
* int(item.get("quantity")),
|
||||
@ -2206,7 +2222,6 @@ class InvoiceListView(LoginRequiredMixin, ListView):
|
||||
model = InvoiceModel
|
||||
template_name = "sales/invoices/invoice_list.html"
|
||||
context_object_name = "invoices"
|
||||
paginate_by = 10
|
||||
|
||||
def get_queryset(self):
|
||||
dealer = get_user_type(self.request)
|
||||
@ -2300,28 +2315,17 @@ class PaidInvoiceModelUpdateFormView(LoginRequiredMixin, UpdateView):
|
||||
@login_required
|
||||
def invoice_mark_as(request, pk):
|
||||
invoice = get_object_or_404(InvoiceModel, pk=pk)
|
||||
entity = EntityModel.objects.first() # will change later
|
||||
user = entity.admin
|
||||
dealer = get_user_type(request)
|
||||
mark = request.GET.get("mark")
|
||||
if mark:
|
||||
if mark == "accept":
|
||||
if not invoice.can_approve():
|
||||
messages.error(request, "invoice is not ready for approval")
|
||||
return redirect("invoice_detail", pk=invoice.pk)
|
||||
invoice.mark_as_approved(entity_slug=entity.slug, user_model=user)
|
||||
# invoice.post_ledger()
|
||||
invoice.save()
|
||||
ledger = (
|
||||
entity.get_ledgers().filter(name=f"Invoice {str(invoice.pk)}").first()
|
||||
)
|
||||
if not ledger:
|
||||
ledger = entity.create_ledger(name=f"Invoice {str(invoice.pk)}")
|
||||
ledger.invoicemodel = invoice
|
||||
ledger.save()
|
||||
# elif mark == "complete":
|
||||
# if not invoice.can_complete():
|
||||
# messages.error(request, "invoice is not ready for completion")
|
||||
if mark and mark == "accept":
|
||||
if not invoice.can_approve():
|
||||
messages.error(request, "invoice is not ready for approval")
|
||||
return redirect("invoice_detail", pk=invoice.pk)
|
||||
invoice.mark_as_approved(
|
||||
entity_slug=dealer.entity.slug, user_model=dealer.entity.admin
|
||||
)
|
||||
invoice.save()
|
||||
return redirect("invoice_detail", pk=invoice.pk)
|
||||
|
||||
|
||||
def invoice_create(request, pk):
|
||||
@ -2342,18 +2346,28 @@ def invoice_create(request, pk):
|
||||
invoice.save()
|
||||
|
||||
unit_items = estimate.get_itemtxs_data()[0]
|
||||
vat = models.VatRate.objects.filter(is_active=True).first()
|
||||
total = 0
|
||||
discount_amount = 0
|
||||
|
||||
itemtxs = []
|
||||
for item in unit_items:
|
||||
car = models.Car.objects.get(vin=item.item_model.name)
|
||||
|
||||
total = Decimal(car.finances.total) * Decimal(item.ce_quantity)
|
||||
discount_amount = car.finances.discount_amount
|
||||
|
||||
grand_total = Decimal(total) - Decimal(discount_amount)
|
||||
vat_amount = round(Decimal(grand_total) * Decimal(vat.rate), 2)
|
||||
grand_total += Decimal(vat_amount)
|
||||
unit_cost = grand_total / Decimal(item.ce_quantity)
|
||||
itemtxs.append(
|
||||
{
|
||||
"item_number": item.item_model.item_number,
|
||||
"unit_cost": car.finances.total_vat,
|
||||
"unit_revenue": car.finances.total_vat,
|
||||
"unit_cost": unit_cost,
|
||||
"unit_revenue": unit_cost,
|
||||
"quantity": item.ce_quantity,
|
||||
"total_amount": Decimal(car.finances.total_vat)
|
||||
* Decimal(item.ce_quantity),
|
||||
"total_amount": grand_total,
|
||||
}
|
||||
)
|
||||
invoice_itemtxs = {
|
||||
@ -2434,8 +2448,6 @@ def PaymentCreateView(request, pk=None):
|
||||
amount = form.cleaned_data.get("amount")
|
||||
invoice = form.cleaned_data.get("invoice")
|
||||
payment_method = form.cleaned_data.get("payment_method")
|
||||
|
||||
ledger = None
|
||||
try:
|
||||
vat_amount = 0
|
||||
total_amount = 0
|
||||
@ -2444,10 +2456,10 @@ def PaymentCreateView(request, pk=None):
|
||||
for x in invoice.get_itemtxs_data()[0].all():
|
||||
vat_amount += models.Car.objects.get(
|
||||
vin=x.item_model.name
|
||||
).finances.vat_amount
|
||||
total_amount += models.Car.objects.get(
|
||||
vin=x.item_model.name
|
||||
).finances.total_discount
|
||||
).finances.vat_amount * Decimal(x.quantity)
|
||||
total_amount += Decimal(x.unit_cost) * Decimal(x.quantity)
|
||||
|
||||
grand_total = total_amount - Decimal(vat_amount)
|
||||
|
||||
ledger = LedgerModel.objects.filter(
|
||||
name=str(invoice.pk), entity=entity
|
||||
@ -2490,7 +2502,7 @@ def PaymentCreateView(request, pk=None):
|
||||
TransactionModel.objects.create(
|
||||
journal_entry=journal,
|
||||
account=credit_account, # Credit Accounts Receivable
|
||||
amount=total_amount, # Payment amount
|
||||
amount=grand_total, # Payment amount
|
||||
tx_type="credit",
|
||||
description="Payment Received",
|
||||
)
|
||||
@ -2614,9 +2626,9 @@ class LeadDetailView(DetailView):
|
||||
class LeadCreateView(CreateView, SuccessMessageMixin, LoginRequiredMixin):
|
||||
model = models.Lead
|
||||
form_class = forms.LeadForm
|
||||
template_name = 'crm/leads/lead_form.html'
|
||||
template_name = "crm/leads/lead_form.html"
|
||||
# success_message = "Lead created successfully!"
|
||||
success_url = reverse_lazy('lead_list')
|
||||
success_url = reverse_lazy("lead_list")
|
||||
|
||||
def form_valid(self, form):
|
||||
print("Form data:", form.cleaned_data) # Debug form data
|
||||
@ -2626,9 +2638,11 @@ class LeadCreateView(CreateView, SuccessMessageMixin, LoginRequiredMixin):
|
||||
|
||||
|
||||
def get_car_models(request):
|
||||
make_id = request.GET.get('id_car_make')
|
||||
make_id = request.GET.get("id_car_make")
|
||||
if make_id:
|
||||
car_models = models.CarModel.objects.filter(id_car_make=make_id).values('id_car_model', 'name', 'arabic_name')
|
||||
car_models = models.CarModel.objects.filter(id_car_make=make_id).values(
|
||||
"id_car_model", "name", "arabic_name"
|
||||
)
|
||||
return JsonResponse(list(car_models), safe=False)
|
||||
return JsonResponse([], safe=False)
|
||||
|
||||
@ -2636,8 +2650,9 @@ def get_car_models(request):
|
||||
class LeadUpdateView(UpdateView):
|
||||
model = models.Lead
|
||||
form_class = forms.LeadForm
|
||||
template_name = 'crm/leads/lead_form.html'
|
||||
success_url = reverse_lazy('lead_list')
|
||||
template_name = "crm/leads/lead_form.html"
|
||||
success_url = reverse_lazy("lead_list")
|
||||
|
||||
|
||||
class LeadDeleteView(DeleteView):
|
||||
model = models.Lead
|
||||
@ -2789,7 +2804,7 @@ def fetch_notifications(request):
|
||||
return JsonResponse({"notifications": notifications_data})
|
||||
|
||||
|
||||
class ItemServiceCreateView(LoginRequiredMixin,SuccessMessageMixin,CreateView):
|
||||
class ItemServiceCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
|
||||
model = models.AdditionalServices
|
||||
form_class = forms.AdditionalServiceForm
|
||||
template_name = "items/service/service_create.html"
|
||||
@ -2804,7 +2819,8 @@ class ItemServiceCreateView(LoginRequiredMixin,SuccessMessageMixin,CreateView):
|
||||
form.instance.price = (form.instance.price * vat.rate) + form.instance.price
|
||||
return super().form_valid(form)
|
||||
|
||||
class ItemServiceUpdateView(LoginRequiredMixin,SuccessMessageMixin,UpdateView):
|
||||
|
||||
class ItemServiceUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
|
||||
model = models.AdditionalServices
|
||||
form_class = forms.AdditionalServiceForm
|
||||
template_name = "items/service/service_create.html"
|
||||
@ -2880,6 +2896,36 @@ class ItemExpenseListView(ListView):
|
||||
return items
|
||||
|
||||
|
||||
class BillListView(ListView):
|
||||
model = ItemModel
|
||||
template_name = "ledger/bills/bill_list.html"
|
||||
context_object_name = "bills"
|
||||
|
||||
def get_queryset(self):
|
||||
dealer = get_user_type(self.request)
|
||||
items = dealer.entity.get_bills()
|
||||
return items
|
||||
|
||||
|
||||
class BillCreateView(LoginRequiredMixin,SuccessMessageMixin,CreateView):
|
||||
model = BillModel
|
||||
form_class = BillModelCreateForm
|
||||
template_name = "ledger/bills/bill_form.html"
|
||||
success_url = reverse_lazy("bill_list")
|
||||
success_message = _("Bill created successfully.")
|
||||
|
||||
def get_form_kwargs(self):
|
||||
dealer = get_user_type(self.request)
|
||||
kwargs = super().get_form_kwargs()
|
||||
kwargs["entity_model"] = dealer.entity
|
||||
return kwargs
|
||||
|
||||
# def form_valid(self, form):
|
||||
# dealer = get_user_type(self.request)
|
||||
# form.instance.entity = dealer.entity
|
||||
# return super().form_valid(form)
|
||||
|
||||
|
||||
class SubscriptionPlans(ListView):
|
||||
model = models.SubscriptionPlan
|
||||
template_name = "subscriptions/subscription_plan.html"
|
||||
|
||||
122
templates/ledger/bills/bill_detail.html
Normal file
122
templates/ledger/bills/bill_detail.html
Normal file
@ -0,0 +1,122 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{{ page_title }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Delete Modal -->
|
||||
<div class="modal fade" id="deleteModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content rounded">
|
||||
<div class="modal-body d-flex justify-content-center">
|
||||
<h1 class="text-danger me-2"><i class="bi bi-exclamation-diamond-fill"></i></h1>
|
||||
<span class="text-danger">{% trans 'Are you sure you want to delete this account?' %}</span>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">{% trans 'No' %}</button>
|
||||
<div class="btn btn-sm btn-danger">
|
||||
<form action="{% url 'account_delete' account.pk %}" method="post">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-sm btn-danger">{% trans 'Yes' %}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row my-5">
|
||||
<div class="card rounded">
|
||||
<div class="card-header">
|
||||
<p class="mb-0">{{ header_title|upper }}</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<p>
|
||||
<strong>{{ _('Account Name') }}:</strong> {{ account.name }}
|
||||
</p>
|
||||
<p>
|
||||
<strong>{{ _('Account Code') }}:</strong> {{ account.code }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<p>
|
||||
<strong>{{ _('Balance Type') }}:</strong> {{ account.balance_type }}
|
||||
</p>
|
||||
<p>
|
||||
<strong>{{ _('Active') }}:</strong> {{ account.active }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<table class="table is-fullwidth is-narrow is-striped is-bordered django-ledger-table-bottom-margin-75">
|
||||
<tr>
|
||||
<th class="has-text-centered">{{ _('JE Number') }}</th>
|
||||
<th class="has-text-centered">{{ _('Date') }}</th>
|
||||
<th class="has-text-centered">{{ _('Debit') }}</th>
|
||||
<th class="has-text-centered">{{ _('Credit') }}</th>
|
||||
<th class="has-text-centered">{{ _('Description') }}</th>
|
||||
<th class="has-text-centered">{{ _('Unit') }}</th>
|
||||
<th class="has-text-centered">{{ _('Actions') }}</th>
|
||||
</tr>
|
||||
|
||||
{% for tx in account.transactionmodel_set.all %}
|
||||
<tr class="has-text-centered">
|
||||
<td>{{ tx.journal_entry.je_number }}</td>
|
||||
<td>{{ tx.journal_entry.timestamp }}</td>
|
||||
<td>
|
||||
{% if tx.tx_type == 'debit' %}
|
||||
${{ tx.amount }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if tx.tx_type == 'credit' %}
|
||||
${{ tx.amount }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ tx.description }}</td>
|
||||
<td>{{ tx.journal_entry.entity_unit.name }}</td>
|
||||
<td>
|
||||
<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="{% url 'payment_details' tx.journal_entry.pk %}">{% trans 'view'|capfirst %}</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr class="has-text-weight-bold">
|
||||
<td></td>
|
||||
<td class="has-text-right">Total</td>
|
||||
<td class="has-text-centered">${{ total_debits }}</td>
|
||||
<td class="has-text-centered">${{ total_credits }}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer d-flex">
|
||||
<a class="btn btn-sm btn-primary me-1" href="{% url 'account_update' account.pk %}">
|
||||
<!-- <i class="bi bi-pencil-square"></i> -->
|
||||
{{ _('Edit') }}
|
||||
</a>
|
||||
<a class="btn btn-sm btn-danger me-1" data-bs-toggle="modal" data-bs-target="#deleteModal">
|
||||
<!-- <i class="bi bi-trash-fill"></i> -->
|
||||
{{ _('Delete') }}
|
||||
</a>
|
||||
<a class="btn btn-sm btn-secondary" href="{% url 'account_list' %}">
|
||||
<!-- <i class="bi bi-arrow-left-square-fill"></i> -->
|
||||
{% trans 'Back to List' %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
38
templates/ledger/bills/bill_form.html
Normal file
38
templates/ledger/bills/bill_form.html
Normal file
@ -0,0 +1,38 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n %}
|
||||
{% load crispy_forms_filters %}
|
||||
{% block title %}{% trans "account" %}{% endblock title %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row my-5">
|
||||
<!-- Display Form Errors -->
|
||||
<div class="card shadow rounded">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<p class="mb-0">
|
||||
{% if account.created %}
|
||||
<!--<i class="bi bi-pencil-square"></i>-->
|
||||
{{ _("Edit Account") }}
|
||||
{% else %}
|
||||
<!--<i class="bi bi-person-plus"></i> -->
|
||||
{{ _("Add Account") }}
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="post" class="form" novalidate>
|
||||
{% csrf_token %}
|
||||
{{ form|crispy }}
|
||||
{% for error in form.errors %}
|
||||
<div class="text-danger">{{ error }}</div>
|
||||
{% endfor %}
|
||||
<div class="d-flex justify-content-end">
|
||||
<button class="btn btn-sm btn-success me-1" type="submit">
|
||||
{{ _("Save") }}
|
||||
</button>
|
||||
<a href="{{request.META.HTTP_REFERER}}" class="btn btn-sm btn-danger">{% trans "Cancel"|capfirst %}</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
165
templates/ledger/bills/bill_list.html
Normal file
165
templates/ledger/bills/bill_list.html
Normal file
@ -0,0 +1,165 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}
|
||||
{% trans 'Bills' %}
|
||||
{% endblock %}
|
||||
{% block bills %}
|
||||
<a class="nav-link active fw-bold">
|
||||
{% trans 'Bills'|capfirst %}
|
||||
<span class="visually-hidden">(current)</span>
|
||||
</a>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="d-flex flex-column min-vh-100">
|
||||
<div class="d-flex flex-column flex-sm-grow-1 ms-sm-14 p-4">
|
||||
<main class="d-grid gap-4 p-1">
|
||||
<!-- Search Bar -->
|
||||
<div class="row g-4">
|
||||
<div class="col-12">
|
||||
<div class="row-fluid p-2">
|
||||
<form method="get">
|
||||
<div class="input-group input-group-sm">
|
||||
<button class="btn btn-sm btn-secondary rounded-start" type="submit">{% trans 'search' %}</button>
|
||||
<input type="text" name="q" class="form-control form-control-sm rounded-end" value="{{ request.GET.q }}" placeholder="{% trans 'Search bills...' %}" />
|
||||
{% if request.GET.q %}
|
||||
<a href="{% url request.resolver_match.view_name %}" class="btn btn-sm btn-outline-danger ms-1 rounded"><i class="bi bi-x-lg"></i></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Customer Table -->
|
||||
|
||||
{% if page_obj.object_list %}
|
||||
<div id="accountsTable">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm fs-9 mb-0">
|
||||
<thead>
|
||||
<tr class="bg-body-highlight">
|
||||
<th class="border-top border-translucent ps-3">
|
||||
{% trans 'Account Name' %}
|
||||
</th>
|
||||
<th class="border-top border-translucent">
|
||||
{% trans 'Code' %}
|
||||
</th>
|
||||
<th class="border-top border-translucent text-end pe-3">
|
||||
{% trans 'Balance Type' %}
|
||||
</th>
|
||||
<th class="border-top border-translucent text-end pe-3">
|
||||
{% trans 'Active' %}
|
||||
</th>
|
||||
<th class="border-top border-translucent text-end align-middle pe-0 ps-4" scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list">
|
||||
{% for bill in bills %}
|
||||
<div class="modal fade" id="deleteModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="deleteModalLabel">
|
||||
{% trans 'Delete Bill' %}
|
||||
<span data-feather="alert-circle"></span>
|
||||
</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body text-center">
|
||||
<p class="mb-0 text-danger fw-bold">
|
||||
{% trans 'Are you sure you want to delete this Bill?' %}
|
||||
</p>
|
||||
<div class="d-grid gap-2">
|
||||
<button type="button" class="btn btn-phoenix-secondary btn-sm" data-bs-dismiss="modal">{% trans 'No' %}</button>
|
||||
<a type="button" class="btn btn-phoenix-danger btn-sm" href="{% url 'account_delete' bill.uuid %}">{% trans 'Yes' %}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<tr>
|
||||
<td class="align-middle ps-3">{{ bill.name }}</td>
|
||||
<td class="align-middle">{{ bill.code }}</td>
|
||||
<td class="align-middle text-end py-3 pe-3">
|
||||
{% if bill.balance_type == 'debit' %}
|
||||
<div class="badge badge-phoenix fs-10 badge-phoenix-success">
|
||||
<span class="fw-bold">{{ _('Debit') }}</span><span class="ms-1 fas fa-arrow-circle-down"></span>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="badge badge-phoenix fs-10 badge-phoenix-danger">
|
||||
<span class="fw-bold">{{ _('Credit') }}</span><span class="ms-1 fas fa-arrow-circle-up"></span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="align-middle text-end py-3 pe-3">
|
||||
{% if bill.active %}
|
||||
<span class="fw-bold text-success fas fa-check-circle"></span>
|
||||
{% else %}
|
||||
<span class="fw-bold text-danger far fa-times-circle"></span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<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 href="{% url 'bill_detail' bill.uuid %}" class="dropdown-item text-success-dark">{% trans 'View' %}</a>
|
||||
<div class="dropdown-divider"></div><button class="dropdown-item text-danger" data-bs-toggle="modal" data-bs-target="#deleteModal">{% trans 'Delete' %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center text-muted">
|
||||
{% trans 'No bill found.' %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between mt-3">
|
||||
<span class="d-none d-sm-inline-block" data-list-info="data-list-info">{{ page_obj.start_index }} {{ _('to') }} {{ page_obj.end_index }}<span class="text-body-tertiary">{{ _('Items of') }}</span>{{ page_obj.paginator.count }}</span>
|
||||
<div class="d-flex">
|
||||
<nav aria-label="Page navigation">
|
||||
<ul class="pagination mb-0">
|
||||
{% if page_obj.has_previous %}
|
||||
<li class="page-item py-0">
|
||||
<a class="page-link" href="?page={{ page_obj.previous_page_number }}" aria-label="Previous"><span aria-hidden="true"><span class="fas fa-chevron-left"></span></span></a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item disabled">
|
||||
<a class="page-link" href="#" aria-label="Previous"><span aria-hidden="true"><span class="fas fa-chevron-left"></span></span></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% for num in page_obj.paginator.page_range %}
|
||||
{% if page_obj.number == num %}
|
||||
<li class="page-item active">
|
||||
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if page_obj.has_next %}
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="?page={{ page_obj.next_page_number }}" aria-label="Next"><span aria-hidden="true"><span class="fas fa-chevron-right"></span></span></a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item disabled">
|
||||
<a class="page-link" href="#" aria-label="Next"><span aria-hidden="true"><span class="fas fa-chevron-right"></span></span></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -1,137 +1,122 @@
|
||||
{% extends "base.html" %}
|
||||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{{ page_title }}{% endblock title %}
|
||||
{% block title %}
|
||||
{{ page_title }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Delete Modal -->
|
||||
<div class="modal fade" id="deleteModal"
|
||||
data-bs-backdrop="static"
|
||||
data-bs-keyboard="false"
|
||||
tabindex="-1"
|
||||
aria-labelledby="deleteModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog modal-sm ">
|
||||
<div class="modal-content rounded">
|
||||
<div class="modal-body d-flex justify-content-center">
|
||||
<h1 class="text-danger me-2"><i class="bi bi-exclamation-diamond-fill"></i></h1>
|
||||
<span class="text-danger">
|
||||
{% trans "Are you sure you want to delete this account?" %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-secondary"
|
||||
data-bs-dismiss="modal">
|
||||
{% trans 'No' %}
|
||||
</button>
|
||||
<div class="btn btn-sm btn-danger">
|
||||
<form action="{% url 'account_delete' account.pk %}" method="post">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-sm btn-danger">
|
||||
{% trans 'Yes' %}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Delete Modal -->
|
||||
<div class="modal fade" id="deleteModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-sm">
|
||||
<div class="modal-content rounded">
|
||||
<div class="modal-body d-flex justify-content-center">
|
||||
<h1 class="text-danger me-2"><i class="bi bi-exclamation-diamond-fill"></i></h1>
|
||||
<span class="text-danger">{% trans 'Are you sure you want to delete this account?' %}</span>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">{% trans 'No' %}</button>
|
||||
<div class="btn btn-sm btn-danger">
|
||||
<form action="{% url 'account_delete' account.pk %}" method="post">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-sm btn-danger">{% trans 'Yes' %}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row my-5">
|
||||
<div class="card rounded ">
|
||||
<div class="card-header ">
|
||||
<p class="mb-0">{{ header_title|upper }}</p>
|
||||
<div class="row my-5">
|
||||
<div class="card rounded">
|
||||
<div class="card-header">
|
||||
<p class="mb-0">{{ header_title|upper }}</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<p>
|
||||
<strong>{{ _('Account Name') }}:</strong> {{ account.name }}
|
||||
</p>
|
||||
<p>
|
||||
<strong>{{ _('Account Code') }}:</strong> {{ account.code }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<p>
|
||||
<strong>{{ _('Balance Type') }}:</strong> {{ account.balance_type }}
|
||||
</p>
|
||||
<p>
|
||||
<strong>{{ _('Active') }}:</strong> {{ account.active }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<p><strong>{{ _("Account Name") }}:</strong> {{ account.name }}</p>
|
||||
<p><strong>{{ _("Account Code") }}:</strong> {{ account.code }}</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<p><strong>{{ _("Balance Type") }}:</strong> {{ account.balance_type }}</p>
|
||||
<p><strong>{{ _("Active") }}:</strong> {{ account.active }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<table class="table is-fullwidth is-narrow is-striped is-bordered django-ledger-table-bottom-margin-75">
|
||||
<tr>
|
||||
<th class="has-text-centered">{{ _("JE Number")}}</th>
|
||||
<th class="has-text-centered">{{ _("Date") }}</th>
|
||||
<th class="has-text-centered">{{ _("Debit") }}</th>
|
||||
<th class="has-text-centered">{{ _("Credit") }}</th>
|
||||
<th class="has-text-centered">{{ _("Description") }}</th>
|
||||
<th class="has-text-centered">{{ _("Unit") }}</th>
|
||||
<th class="has-text-centered">{{ _("Actions") }}</th>
|
||||
</tr>
|
||||
{% for tx in transactions %}
|
||||
<tr class="has-text-centered">
|
||||
<td>{{ tx.journal_entry.je_number }}</td>
|
||||
<td>{{ tx.journal_entry.timestamp }}</td>
|
||||
<td>{% if tx.tx_type == 'debit' %}${{ tx.amount }}{% endif %}</td>
|
||||
<td>{% if tx.tx_type == 'credit' %}${{ tx.amount }}{% endif %}</td>
|
||||
<td>{{ tx.description }}</td>
|
||||
<td>{{ tx.journal_entry.entity_unit.name }}</td>
|
||||
<td>
|
||||
<div class="dropdown is-right is-hoverable" id="tx-action-{{ tx.uuid }}">
|
||||
<div class="dropdown-trigger">
|
||||
<button class="button is-small is-rounded is-outlined"
|
||||
aria-haspopup="true"
|
||||
aria-controls="dropdown-menu">
|
||||
<span>{% trans 'Actions' %}</span>
|
||||
<span class="icon is-small fas fa-arrow-down"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="dropdown-menu" id="dropdown-menu-{{ tx.uuid }}" role="menu">
|
||||
<div class="dropdown-content">
|
||||
{# TODO: These URLs need to be replaced with the future mode method that generates it. #}
|
||||
<a href="{% url 'django_ledger:je-detail' entity_slug=entity_slug ledger_pk=tx.journal_entry.ledger.uuid je_pk=tx.journal_entry.uuid %}"
|
||||
class="dropdown-item has-text-success">View JE</a>
|
||||
{% if tx.journal_entry.ledger.billmodel %}
|
||||
<a href="{% url 'django_ledger:bill-detail' entity_slug=entity_slug bill_pk=tx.journal_entry.ledger.billmodel.uuid %}"
|
||||
class="dropdown-item has-text-primary">View Bill</a>
|
||||
{% elif tx.journal_entry.ledger.invoicemodel %}
|
||||
<a href="{% url 'django_ledger:invoice-detail' entity_slug=entity_slug invoice_pk=tx.journal_entry.ledger.invoicemodel.uuid %}"
|
||||
class="dropdown-item has-text-info">View Invoice</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<table class="table is-fullwidth is-narrow is-striped is-bordered django-ledger-table-bottom-margin-75">
|
||||
<tr>
|
||||
<th class="has-text-centered">{{ _('JE Number') }}</th>
|
||||
<th class="has-text-centered">{{ _('Date') }}</th>
|
||||
<th class="has-text-centered">{{ _('Debit') }}</th>
|
||||
<th class="has-text-centered">{{ _('Credit') }}</th>
|
||||
<th class="has-text-centered">{{ _('Description') }}</th>
|
||||
<th class="has-text-centered">{{ _('Unit') }}</th>
|
||||
<th class="has-text-centered">{{ _('Actions') }}</th>
|
||||
</tr>
|
||||
|
||||
{% for tx in account.transactionmodel_set.all %}
|
||||
<tr class="has-text-centered">
|
||||
<td>{{ tx.journal_entry.je_number }}</td>
|
||||
<td>{{ tx.journal_entry.timestamp }}</td>
|
||||
<td>
|
||||
{% if tx.tx_type == 'debit' %}
|
||||
${{ tx.amount }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if tx.tx_type == 'credit' %}
|
||||
${{ tx.amount }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ tx.description }}</td>
|
||||
<td>{{ tx.journal_entry.entity_unit.name }}</td>
|
||||
<td>
|
||||
<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="{% url 'payment_details' tx.journal_entry.pk %}">{% trans 'view'|capfirst %}</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr class="has-text-weight-bold">
|
||||
<td></td>
|
||||
<td class="has-text-right">Total</td>
|
||||
<td class="has-text-centered">${{ total_credits }}</td>
|
||||
<td class="has-text-centered">${{ total_debits }}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer d-flex ">
|
||||
<a class="btn btn-sm btn-primary me-1" href="{% url 'account_update' account.pk %}">
|
||||
<!--<i class="bi bi-pencil-square"></i> -->
|
||||
{{ _("Edit") }}
|
||||
</a>
|
||||
<a class="btn btn-sm btn-danger me-1"
|
||||
data-bs-toggle="modal"
|
||||
data-bs-target="#deleteModal">
|
||||
<!--<i class="bi bi-trash-fill"></i>-->
|
||||
{{ _("Delete") }}
|
||||
</a>
|
||||
<a class="btn btn-sm btn-secondary"
|
||||
href="{% url 'account_list' %}">
|
||||
<!--<i class="bi bi-arrow-left-square-fill"></i>-->
|
||||
{% trans "Back to List" %}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr class="has-text-weight-bold">
|
||||
<td></td>
|
||||
<td class="has-text-right">Total</td>
|
||||
<td class="has-text-centered">${{ total_debits }}</td>
|
||||
<td class="has-text-centered">${{ total_credits }}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer d-flex">
|
||||
<a class="btn btn-sm btn-primary me-1" href="{% url 'account_update' account.pk %}">
|
||||
<!-- <i class="bi bi-pencil-square"></i> -->
|
||||
{{ _('Edit') }}
|
||||
</a>
|
||||
<a class="btn btn-sm btn-danger me-1" data-bs-toggle="modal" data-bs-target="#deleteModal">
|
||||
<!-- <i class="bi bi-trash-fill"></i> -->
|
||||
{{ _('Delete') }}
|
||||
</a>
|
||||
<a class="btn btn-sm btn-secondary" href="{% url 'account_list' %}">
|
||||
<!-- <i class="bi bi-arrow-left-square-fill"></i> -->
|
||||
{% trans 'Back to List' %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@ -177,49 +177,6 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
</main>
|
||||
<div class="row mt-4 mx-4">
|
||||
<div class="d-flex justify-content-between mb-2 p-6">
|
||||
<span></span>
|
||||
<h3 class="text-center">{% trans "Chart of Accounts" %}</h3>
|
||||
<a href="{% url 'account_create' %}" class="btn btn-sm btn-success ">{% trans "Add Account" %}</a>
|
||||
</div>
|
||||
<div class="mx-n4 px-4 mx-lg-n6 px-lg-6 bg-body-emphasis pt-7 border-y">
|
||||
|
||||
<div class="table-responsive mx-n1 px-1 scrollbar">
|
||||
<table class="table fs-9 mb-0 border-top border-translucent">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="sort white-space-nowrap align-middle" scope="col">{% trans "Name" %}</th>
|
||||
<th class="sort white-space-nowrap align-middle" scope="col">{% trans "Account Number" %}</th>
|
||||
<th class="sort white-space-nowrap align-middle" scope="col">{% trans "Balance Type" %}</th>
|
||||
<th class="sort white-space-nowrap align-middle" scope="col">{% trans "Active" %}</th>
|
||||
<th class="sort white-space-nowrap align-middle" scope="col">{% trans "Action" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="list">
|
||||
{% for account in accounts %}
|
||||
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
|
||||
<td class="align-middle product white-space-nowrap">{{ account.name }}</td>
|
||||
<td class="align-middle product white-space-nowrap py-0">{{ account.code }}</td>
|
||||
<td class="align-middle product white-space-nowrap py-0">{{ account.balance_type|capfirst }}</td>
|
||||
<td class="align-middle product white-space-nowrap py-0">{{ account.active }}</td>
|
||||
<td class="">
|
||||
<a href="{% url 'account_update' account.pk %}"
|
||||
class="btn btn-sm btn-phoenix-success">
|
||||
{% trans "Update" %}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="6" class="text-center">{% trans "No Invoice Found" %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="d-flex justify-content-center">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Loading…
x
Reference in New Issue
Block a user