latest update
This commit is contained in:
parent
5ef0d68f7c
commit
ecf1c375c1
20
inventory/migrations/0012_saleorder_created.py
Normal file
20
inventory/migrations/0012_saleorder_created.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Generated by Django 4.2.17 on 2025-01-29 12:59
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.utils.timezone
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('inventory', '0011_alter_saleorder_estimate'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='saleorder',
|
||||||
|
name='created',
|
||||||
|
field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
||||||
17
inventory/migrations/0013_alter_saleorder_options.py
Normal file
17
inventory/migrations/0013_alter_saleorder_options.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Generated by Django 4.2.17 on 2025-01-29 13:02
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('inventory', '0012_saleorder_created'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='saleorder',
|
||||||
|
options={'ordering': ['created']},
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -1562,6 +1562,10 @@ class SaleOrder(models.Model):
|
|||||||
])
|
])
|
||||||
comments = models.TextField(blank=True, null=True)
|
comments = models.TextField(blank=True, null=True)
|
||||||
formatted_order_id = models.CharField(max_length=10, unique=True, editable=False)
|
formatted_order_id = models.CharField(max_length=10, unique=True, editable=False)
|
||||||
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['-created']
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if not self.formatted_order_id:
|
if not self.formatted_order_id:
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
from django import template
|
from django import template
|
||||||
from calendar import month_abbr
|
from calendar import month_abbr
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_ledger.io.io_core import get_localdate
|
from django_ledger.io.io_core import get_localdate,validate_activity
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
@ -146,3 +146,35 @@ def balance_sheet_statement(context, io_model, to_date=None):
|
|||||||
'user_model': user_model,
|
'user_model': user_model,
|
||||||
'tx_digest': io_digest.get_io_data(),
|
'tx_digest': io_digest.get_io_data(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@register.inclusion_tag('django_ledger/financial_statements/tags/income_statement.html', takes_context=True)
|
||||||
|
def income_statement_table(context, io_model, from_date=None, to_date=None):
|
||||||
|
user_model = context['user']
|
||||||
|
activity = context['request'].GET.get('activity')
|
||||||
|
activity = validate_activity(activity, raise_404=True)
|
||||||
|
entity_slug = context['view'].kwargs.get('entity_slug')
|
||||||
|
|
||||||
|
if not from_date:
|
||||||
|
from_date = context['from_date']
|
||||||
|
if not to_date:
|
||||||
|
to_date = context['to_date']
|
||||||
|
|
||||||
|
io_digest = io_model.digest(
|
||||||
|
activity=activity,
|
||||||
|
user_model=user_model,
|
||||||
|
entity_slug=entity_slug,
|
||||||
|
unit_slug=context['unit_slug'],
|
||||||
|
by_unit=context['by_unit'],
|
||||||
|
from_date=from_date,
|
||||||
|
to_date=to_date,
|
||||||
|
equity_only=True,
|
||||||
|
process_groups=True,
|
||||||
|
income_statement=True,
|
||||||
|
signs=True
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'entity_slug': entity_slug,
|
||||||
|
'user_model': user_model,
|
||||||
|
'tx_digest': io_digest.get_io_data()
|
||||||
|
}
|
||||||
|
|||||||
@ -546,7 +546,23 @@ urlpatterns = [
|
|||||||
path('entity/<slug:entity_slug>/balance-sheet/date/<int:year>/<int:month>/<int:day>/',
|
path('entity/<slug:entity_slug>/balance-sheet/date/<int:year>/<int:month>/<int:day>/',
|
||||||
views.DateBalanceSheetView.as_view(),
|
views.DateBalanceSheetView.as_view(),
|
||||||
name='entity-bs-date'),
|
name='entity-bs-date'),
|
||||||
|
# INCOME STATEMENT Reports ----
|
||||||
|
# Entity .....
|
||||||
|
path('entity/<slug:entity_slug>/income-statement/',
|
||||||
|
views.BaseIncomeStatementRedirectViewBase.as_view(),
|
||||||
|
name='entity-ic'),
|
||||||
|
path('entity/<slug:entity_slug>/income-statement/year/<int:year>/',
|
||||||
|
views.FiscalYearIncomeStatementViewBase.as_view(),
|
||||||
|
name='entity-ic-year'),
|
||||||
|
# path('entity/<slug:entity_slug>/income-statement/quarter/<int:year>/<int:quarter>/',
|
||||||
|
# views.QuarterlyIncomeStatementView.as_view(),
|
||||||
|
# name='entity-ic-quarter'),
|
||||||
|
# path('entity/<slug:entity_slug>/income-statement/month/<int:year>/<int:month>/',
|
||||||
|
# views.MonthlyIncomeStatementView.as_view(),
|
||||||
|
# name='entity-ic-month'),
|
||||||
|
# path('entity/<slug:entity_slug>/income-statement/date/<int:year>/<int:month>/<int:day>/',
|
||||||
|
# views.MonthlyIncomeStatementView.as_view(),
|
||||||
|
# name='entity-ic-date'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -284,15 +284,11 @@ def set_invoice_payment(dealer, entity, invoice, amount, payment_method):
|
|||||||
vat_amount = 0
|
vat_amount = 0
|
||||||
total_amount = 0
|
total_amount = 0
|
||||||
|
|
||||||
if invoice.terms == "on_receipt":
|
calculator = CarFinanceCalculator(invoice)
|
||||||
for x in invoice.get_itemtxs_data()[0].all():
|
finance_data = calculator.get_finance_data()
|
||||||
# vat_amount += models.Car.objects.get(
|
# if invoice.terms == "on_receipt":
|
||||||
# vin=x.item_model.name
|
# for x in invoice.get_itemtxs_data()[0].all():
|
||||||
# ).finances.vat_amount * Decimal(x.quantity)
|
# total_amount += Decimal(x.unit_cost) * Decimal(x.quantity)
|
||||||
total_amount += Decimal(x.unit_cost) * Decimal(x.quantity)
|
|
||||||
|
|
||||||
# grand_total = total_amount - Decimal(vat_amount)
|
|
||||||
total_amount
|
|
||||||
|
|
||||||
ledger = LedgerModel.objects.filter(
|
ledger = LedgerModel.objects.filter(
|
||||||
name__icontains=str(invoice.pk), entity=entity
|
name__icontains=str(invoice.pk), entity=entity
|
||||||
@ -323,26 +319,24 @@ def set_invoice_payment(dealer, entity, invoice, amount, payment_method):
|
|||||||
TransactionModel.objects.create(
|
TransactionModel.objects.create(
|
||||||
journal_entry=journal,
|
journal_entry=journal,
|
||||||
account=debit_account, # Debit Cash
|
account=debit_account, # Debit Cash
|
||||||
amount=amount, # Payment amount
|
amount=finance_data["grand_total"], # Payment amount
|
||||||
tx_type="debit",
|
tx_type="debit",
|
||||||
description="Payment Received",
|
description="Payment Received",
|
||||||
)
|
)
|
||||||
|
|
||||||
# if total_amount + invoice.
|
|
||||||
|
|
||||||
TransactionModel.objects.create(
|
TransactionModel.objects.create(
|
||||||
journal_entry=journal,
|
journal_entry=journal,
|
||||||
account=credit_account, # Credit Accounts Receivable
|
account=credit_account, # Credit Accounts Receivable
|
||||||
amount=total_amount, # Payment amount
|
amount=finance_data["total_price"], # Payment amount
|
||||||
tx_type="credit",
|
tx_type="credit",
|
||||||
description="Payment Received",
|
description="Payment Received",
|
||||||
)
|
)
|
||||||
|
|
||||||
if vat_amount > 0:
|
|
||||||
TransactionModel.objects.create(
|
TransactionModel.objects.create(
|
||||||
journal_entry=journal,
|
journal_entry=journal,
|
||||||
account=vat_payable_account, # Credit VAT Payable
|
account=vat_payable_account, # Credit VAT Payable
|
||||||
amount=vat_amount,
|
amount=finance_data["total_vat_amount"],
|
||||||
tx_type="credit",
|
tx_type="credit",
|
||||||
description="VAT Payable on Invoice",
|
description="VAT Payable on Invoice",
|
||||||
)
|
)
|
||||||
@ -622,7 +616,8 @@ class CarFinanceCalculator:
|
|||||||
"make": car_info.get('make'),
|
"make": car_info.get('make'),
|
||||||
"model": car_info.get('model'),
|
"model": car_info.get('model'),
|
||||||
"year": car_info.get('year'),
|
"year": car_info.get('year'),
|
||||||
"trim": car_info.get('mileage'), # Verify if this should actually be mileage
|
"trim": car_info.get('trim'),
|
||||||
|
"mileage": car_info.get('mileage'),
|
||||||
"cost_price": car_finance.get('cost_price'),
|
"cost_price": car_finance.get('cost_price'),
|
||||||
"selling_price": car_finance.get('selling_price'),
|
"selling_price": car_finance.get('selling_price'),
|
||||||
"discount": car_finance.get('discount_amount'),
|
"discount": car_finance.get('discount_amount'),
|
||||||
@ -657,7 +652,7 @@ class CarFinanceCalculator:
|
|||||||
"total_price": total_price,
|
"total_price": total_price,
|
||||||
"total_vat_amount": total_vat_amount,
|
"total_vat_amount": total_vat_amount,
|
||||||
"total_discount": total_discount,
|
"total_discount": total_discount,
|
||||||
"grand_total": (total_price + total_vat_amount) - total_discount,
|
"grand_total": (total_price + total_vat_amount) - total_discount ,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_finance_data(self):
|
def get_finance_data(self):
|
||||||
@ -668,6 +663,7 @@ class CarFinanceCalculator:
|
|||||||
"quantity": sum(self._get_quantity(item) for item in self.item_transactions),
|
"quantity": sum(self._get_quantity(item) for item in self.item_transactions),
|
||||||
"total_price": totals['total_price'],
|
"total_price": totals['total_price'],
|
||||||
"total_vat": totals['total_vat_amount'] + totals['total_price'],
|
"total_vat": totals['total_vat_amount'] + totals['total_price'],
|
||||||
|
"total_vat_amount": totals['total_vat_amount'],
|
||||||
"total_discount": totals['total_discount'],
|
"total_discount": totals['total_discount'],
|
||||||
"grand_total": totals['grand_total'],
|
"grand_total": totals['grand_total'],
|
||||||
"additionals": self.additional_services,
|
"additionals": self.additional_services,
|
||||||
|
|||||||
@ -2381,15 +2381,8 @@ class EstimateDetailView(LoginRequiredMixin, DetailView):
|
|||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
estimate = kwargs.get("object")
|
estimate = kwargs.get("object")
|
||||||
if estimate.get_itemtxs_data():
|
if estimate.get_itemtxs_data():
|
||||||
# data = get_financial_values(estimate)
|
|
||||||
calculator = CarFinanceCalculator(estimate)
|
calculator = CarFinanceCalculator(estimate)
|
||||||
finance_data = calculator.get_finance_data()
|
finance_data = calculator.get_finance_data()
|
||||||
# kwargs["vat_amount"] = data["vat_amount"]
|
|
||||||
# kwargs["total"] = data["grand_total"]
|
|
||||||
# kwargs["discount_amount"] = data["discount_amount"]
|
|
||||||
# kwargs["vat"] = data["vat"]
|
|
||||||
# kwargs["car_and_item_info"] = data["car_and_item_info"]
|
|
||||||
# kwargs["additional_services"] = data["additional_services"]
|
|
||||||
kwargs['data'] = finance_data
|
kwargs['data'] = finance_data
|
||||||
print(finance_data)
|
print(finance_data)
|
||||||
kwargs["invoice"] = (
|
kwargs["invoice"] = (
|
||||||
@ -2518,15 +2511,9 @@ class InvoiceDetailView(LoginRequiredMixin, DetailView):
|
|||||||
invoice = kwargs.get("object")
|
invoice = kwargs.get("object")
|
||||||
|
|
||||||
if invoice.get_itemtxs_data():
|
if invoice.get_itemtxs_data():
|
||||||
# data = get_financial_values(invoice)
|
|
||||||
calculator = CarFinanceCalculator(invoice)
|
calculator = CarFinanceCalculator(invoice)
|
||||||
finance_data = calculator.get_finance_data()
|
finance_data = calculator.get_finance_data()
|
||||||
# kwargs["vat_amount"] = data["vat_amount"]
|
print((finance_data["total_vat_amount"]+finance_data["total_price"]) == finance_data["grand_total"])
|
||||||
# kwargs["total"] = data["grand_total"]
|
|
||||||
# kwargs["discount_amount"] = data["discount_amount"]
|
|
||||||
# kwargs["vat"] = data["vat"]
|
|
||||||
# kwargs["car_and_item_info"] = data["car_and_item_info"]
|
|
||||||
# kwargs["additional_services"] = data["additional_services"]
|
|
||||||
kwargs["data"] = finance_data
|
kwargs["data"] = finance_data
|
||||||
kwargs["payments"] = JournalEntryModel.objects.filter(
|
kwargs["payments"] = JournalEntryModel.objects.filter(
|
||||||
ledger=invoice.ledger
|
ledger=invoice.ledger
|
||||||
@ -2627,38 +2614,41 @@ def invoice_create(request, pk):
|
|||||||
ledger.save()
|
ledger.save()
|
||||||
invoice.save()
|
invoice.save()
|
||||||
|
|
||||||
unit_items = estimate.get_itemtxs_data()[0]
|
# unit_items = estimate.get_itemtxs_data()[0]
|
||||||
vat = models.VatRate.objects.filter(is_active=True).first()
|
# vat = models.VatRate.objects.filter(is_active=True).first()
|
||||||
total = 0
|
calculator = CarFinanceCalculator(estimate)
|
||||||
discount_amount = 0
|
finance_data = calculator.get_finance_data()
|
||||||
|
|
||||||
itemtxs = []
|
# total = 0
|
||||||
for item in unit_items:
|
# discount_amount = 0
|
||||||
car = models.Car.objects.get(vin=item.item_model.name)
|
|
||||||
|
|
||||||
total = Decimal(car.finances.total) * Decimal(item.ce_quantity)
|
# itemtxs = []
|
||||||
discount_amount = car.finances.discount_amount
|
# for item in unit_items:
|
||||||
|
# car = models.Car.objects.get(vin=item.item_model.name)
|
||||||
|
|
||||||
grand_total = Decimal(total) - Decimal(discount_amount)
|
# total = Decimal(car.finances.total) * Decimal(item.ce_quantity)
|
||||||
vat_amount = round(Decimal(grand_total) * Decimal(vat.rate), 2)
|
# discount_amount = car.finances.discount_amount
|
||||||
grand_total += Decimal(vat_amount)
|
|
||||||
unit_cost = grand_total / Decimal(item.ce_quantity)
|
# grand_total = Decimal(total) - Decimal(discount_amount)
|
||||||
itemtxs.append(
|
# vat_amount = round(Decimal(grand_total) * Decimal(vat.rate), 2)
|
||||||
{
|
# grand_total += Decimal(vat_amount)
|
||||||
"item_number": item.item_model.item_number,
|
# unit_cost = grand_total / Decimal(item.ce_quantity)
|
||||||
"unit_cost": unit_cost,
|
# itemtxs.append(
|
||||||
"unit_revenue": unit_cost,
|
# {
|
||||||
"quantity": item.ce_quantity,
|
# "item_number": item.item_model.item_number,
|
||||||
"total_amount": grand_total,
|
# "unit_cost": unit_cost,
|
||||||
}
|
# "unit_revenue": unit_cost,
|
||||||
)
|
# "quantity": item.ce_quantity,
|
||||||
|
# "total_amount": grand_total,
|
||||||
|
# }
|
||||||
|
# )
|
||||||
invoice_itemtxs = {
|
invoice_itemtxs = {
|
||||||
i.get("item_number"): {
|
i.get("item_number"): {
|
||||||
"unit_cost": i.get("unit_cost"),
|
"unit_cost": i.get("total_vat"),
|
||||||
"quantity": i.get("quantity"),
|
"quantity": i.get("quantity"),
|
||||||
"total_amount": i.get("total_amount"),
|
"total_amount": i.get("total_vat"),
|
||||||
}
|
}
|
||||||
for i in itemtxs
|
for i in finance_data.get("cars")
|
||||||
}
|
}
|
||||||
|
|
||||||
invoice_itemtxs = invoice.migrate_itemtxs(
|
invoice_itemtxs = invoice.migrate_itemtxs(
|
||||||
@ -2705,14 +2695,16 @@ class InvoicePreviewView(LoginRequiredMixin, DetailView):
|
|||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
invoice = kwargs.get("object")
|
invoice = kwargs.get("object")
|
||||||
if invoice.get_itemtxs_data():
|
if invoice.get_itemtxs_data():
|
||||||
data = get_financial_values(invoice)
|
# data = get_financial_values(invoice)
|
||||||
|
calculator = CarFinanceCalculator(invoice)
|
||||||
kwargs["vat_amount"] = data["vat_amount"]
|
finance_data = calculator.get_finance_data()
|
||||||
kwargs["total"] = data["grand_total"]
|
kwargs["data"] = finance_data
|
||||||
kwargs["discount_amount"] = data["discount_amount"]
|
# kwargs["vat_amount"] = data["vat_amount"]
|
||||||
kwargs["vat"] = data["vat"]
|
# kwargs["total"] = data["grand_total"]
|
||||||
kwargs["car_and_item_info"] = data["car_and_item_info"]
|
# kwargs["discount_amount"] = data["discount_amount"]
|
||||||
kwargs["additional_services"] = data["additional_services"]
|
# kwargs["vat"] = data["vat"]
|
||||||
|
# kwargs["car_and_item_info"] = data["car_and_item_info"]
|
||||||
|
# kwargs["additional_services"] = data["additional_services"]
|
||||||
return super().get_context_data(**kwargs)
|
return super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
@ -3435,6 +3427,7 @@ class OrderListView(ListView):
|
|||||||
template_name = "sales/orders/order_list.html"
|
template_name = "sales/orders/order_list.html"
|
||||||
context_object_name = "orders"
|
context_object_name = "orders"
|
||||||
|
|
||||||
|
|
||||||
# email
|
# email
|
||||||
def send_email_view(request, pk):
|
def send_email_view(request, pk):
|
||||||
estimate = get_object_or_404(EstimateModel, pk=pk)
|
estimate = get_object_or_404(EstimateModel, pk=pk)
|
||||||
@ -3509,7 +3502,7 @@ def custom_bad_request_view(request, exception=None):
|
|||||||
# from django_ledger.io.io_core import get_localdate
|
# from django_ledger.io.io_core import get_localdate
|
||||||
# from django_ledger.views.mixins import (DjangoLedgerSecurityMixIn)
|
# from django_ledger.views.mixins import (DjangoLedgerSecurityMixIn)
|
||||||
# from django.views.generic import RedirectView
|
# from django.views.generic import RedirectView
|
||||||
from django_ledger.views.financial_statement import FiscalYearBalanceSheetView
|
from django_ledger.views.financial_statement import FiscalYearBalanceSheetView,BaseIncomeStatementRedirectView,FiscalYearIncomeStatementView
|
||||||
from django.views.generic import DetailView, RedirectView
|
from django.views.generic import DetailView, RedirectView
|
||||||
|
|
||||||
from django_ledger.io.io_core import get_localdate
|
from django_ledger.io.io_core import get_localdate
|
||||||
@ -3548,3 +3541,34 @@ class DateBalanceSheetView(FiscalYearBalanceSheetViewBase, DateReportMixIn):
|
|||||||
"""
|
"""
|
||||||
Date Balance Sheet View.
|
Date Balance Sheet View.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
class BaseIncomeStatementRedirectViewBase(BaseIncomeStatementRedirectView):
|
||||||
|
|
||||||
|
def get_redirect_url(self, *args, **kwargs):
|
||||||
|
year = get_localdate().year
|
||||||
|
dealer = get_user_type(self.request)
|
||||||
|
return reverse('entity-ic-year',
|
||||||
|
kwargs={
|
||||||
|
'entity_slug': dealer.entity.slug,
|
||||||
|
'year': year
|
||||||
|
})
|
||||||
|
|
||||||
|
class FiscalYearIncomeStatementViewBase(FiscalYearIncomeStatementView):
|
||||||
|
template_name = "ledger/reports/income_statement.html"
|
||||||
|
|
||||||
|
class QuarterlyIncomeStatementView(FiscalYearIncomeStatementView, QuarterlyReportMixIn):
|
||||||
|
"""
|
||||||
|
Quarter Income Statement View.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class MonthlyIncomeStatementView(FiscalYearIncomeStatementView, MonthlyReportMixIn):
|
||||||
|
"""
|
||||||
|
Monthly Income Statement View.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class DateModelIncomeStatementView(FiscalYearIncomeStatementView, DateReportMixIn):
|
||||||
|
"""
|
||||||
|
Date Income Statement View.
|
||||||
|
"""
|
||||||
|
|||||||
504
requirements.txt
504
requirements.txt
@ -1,252 +1,252 @@
|
|||||||
aiohappyeyeballs==2.4.4
|
aiohappyeyeballs
|
||||||
aiohttp==3.11.11
|
aiohttp
|
||||||
aiohttp-retry==2.9.1
|
aiohttp-retry
|
||||||
aiosignal==1.3.2
|
aiosignal
|
||||||
alabaster==1.0.0
|
alabaster
|
||||||
albucore==0.0.23
|
albucore
|
||||||
albumentations==2.0.1
|
albumentations
|
||||||
annotated-types==0.7.0
|
annotated-types
|
||||||
anyio==4.8.0
|
anyio
|
||||||
arabic-reshaper==3.0.0
|
arabic-reshaper
|
||||||
asgiref==3.8.1
|
asgiref
|
||||||
astor==0.8.1
|
astor
|
||||||
astroid==3.3.8
|
astroid
|
||||||
attrs==23.2.0
|
attrs
|
||||||
autopep8==2.3.2
|
autopep8
|
||||||
Babel==2.15.0
|
Babel
|
||||||
beautifulsoup4==4.12.3
|
beautifulsoup4
|
||||||
bleach==6.2.0
|
bleach
|
||||||
blinker==1.9.0
|
blinker
|
||||||
Brotli==1.1.0
|
Brotli
|
||||||
certifi==2024.12.14
|
certifi
|
||||||
cffi==1.17.1
|
cffi
|
||||||
chardet==5.2.0
|
chardet
|
||||||
charset-normalizer==3.4.1
|
charset-normalizer
|
||||||
click==8.1.8
|
click
|
||||||
colorama==0.4.6
|
colorama
|
||||||
commonmark==0.9.1
|
commonmark
|
||||||
contourpy==1.3.1
|
contourpy
|
||||||
crispy-bootstrap5==2024.10
|
crispy-bootstrap5
|
||||||
cryptography==44.0.0
|
cryptography
|
||||||
cssselect2==0.7.0
|
cssselect2
|
||||||
ctranslate2==4.5.0
|
ctranslate2
|
||||||
cycler==0.12.1
|
cycler
|
||||||
Cython==3.0.11
|
Cython
|
||||||
decorator==5.1.1
|
decorator
|
||||||
desert==2022.9.22
|
desert
|
||||||
dill==0.3.9
|
dill
|
||||||
distro==1.9.0
|
distro
|
||||||
dj-rest-auth==7.0.1
|
dj-rest-auth
|
||||||
dj-shop-cart==7.1.1
|
dj-shop-cart
|
||||||
Django==5.1.5
|
Django
|
||||||
django-allauth==65.3.1
|
django-allauth
|
||||||
django-appointment==3.7.4
|
django-appointment
|
||||||
django-autoslug==1.9.9
|
django-autoslug
|
||||||
django-bootstrap5==24.3
|
django-bootstrap5
|
||||||
django-classy-tags==4.1.0
|
django-classy-tags
|
||||||
django-cors-headers==4.6.0
|
django-cors-headers
|
||||||
django-countries==7.6.1
|
django-countries
|
||||||
django-crispy-forms==2.3
|
django-crispy-forms
|
||||||
django-debug-toolbar==5.0.1
|
django-debug-toolbar
|
||||||
django-extensions==3.2.3
|
django-extensions
|
||||||
django-filter==24.3
|
django-filter
|
||||||
django-formtools==2.5.1
|
django-formtools
|
||||||
django-ledger==0.7.3
|
django-ledger
|
||||||
django-money==3.5.3
|
django-money
|
||||||
django-next-url-mixin==0.4.0
|
django-next-url-mixin
|
||||||
django-nine==0.2.7
|
django-nine
|
||||||
django-nonefield==0.4
|
django-nonefield
|
||||||
django-ordered-model==3.7.4
|
django-ordered-model
|
||||||
django-phonenumber-field==8.0.0
|
django-phonenumber-field
|
||||||
django-picklefield==3.2
|
django-picklefield
|
||||||
django-plans==1.2.0
|
django-plans
|
||||||
django-prometheus==2.3.1
|
django-prometheus
|
||||||
django-q2==1.7.6
|
django-q2
|
||||||
django-sekizai==4.1.0
|
django-sekizai
|
||||||
django-sequences==3.0
|
django-sequences
|
||||||
django-silk==5.3.2
|
django-silk
|
||||||
django-sms==0.7.0
|
django-sms
|
||||||
django-sslserver==0.22
|
django-sslserver
|
||||||
django-tables2==2.7.5
|
django-tables2
|
||||||
django-treebeard==4.7.1
|
django-treebeard
|
||||||
django-view-breadcrumbs==2.5.1
|
django-view-breadcrumbs
|
||||||
djangocms-admin-style==3.3.1
|
djangocms-admin-style
|
||||||
djangorestframework==3.15.2
|
djangorestframework
|
||||||
djangorestframework_simplejwt==5.4.0
|
djangorestframework_simplejwt
|
||||||
djangoviz==0.1.1
|
djangoviz
|
||||||
docutils==0.21.2
|
docutils
|
||||||
easy-thumbnails==2.10
|
easy-thumbnails
|
||||||
emoji==2.14.1
|
emoji
|
||||||
et_xmlfile==2.0.0
|
et_xmlfile
|
||||||
Faker==35.0.0
|
Faker
|
||||||
filelock==3.17.0
|
filelock
|
||||||
fire==0.7.0
|
fire
|
||||||
Flask==3.1.0
|
Flask
|
||||||
fonttools==4.55.6
|
fonttools
|
||||||
frozenlist==1.5.0
|
frozenlist
|
||||||
fsspec==2024.12.0
|
fsspec
|
||||||
gprof2dot==2024.6.6
|
gprof2dot
|
||||||
graphqlclient==0.2.4
|
graphqlclient
|
||||||
greenlet==3.1.1
|
greenlet
|
||||||
h11==0.14.0
|
h11
|
||||||
h2==4.1.0
|
h2
|
||||||
hpack==4.1.0
|
hpack
|
||||||
hstspreload==2025.1.1
|
hstspreload
|
||||||
httpcore==1.0.7
|
httpcore
|
||||||
httpx==0.28.1
|
httpx
|
||||||
hyperframe==6.1.0
|
hyperframe
|
||||||
idna==3.10
|
idna
|
||||||
imageio==2.37.0
|
imageio
|
||||||
imagesize==1.4.1
|
imagesize
|
||||||
imgaug==0.4.0
|
imgaug
|
||||||
iso4217==1.12.20240625
|
iso4217
|
||||||
isodate==0.7.2
|
isodate
|
||||||
isort==5.13.2
|
isort
|
||||||
itsdangerous==2.2.0
|
itsdangerous
|
||||||
Jinja2==3.1.5
|
Jinja2
|
||||||
jiter==0.8.2
|
jiter
|
||||||
joblib==1.4.2
|
joblib
|
||||||
kiwisolver==1.4.8
|
kiwisolver
|
||||||
lazy_loader==0.4
|
lazy_loader
|
||||||
ledger==1.0.1
|
ledger
|
||||||
libretranslatepy==2.1.4
|
libretranslatepy
|
||||||
lmdb==1.6.2
|
lmdb
|
||||||
lxml==5.3.0
|
lxml
|
||||||
Markdown==3.7
|
Markdown
|
||||||
markdown-it-py==3.0.0
|
markdown-it-py
|
||||||
MarkupSafe==3.0.2
|
MarkupSafe
|
||||||
marshmallow==3.26.0
|
marshmallow
|
||||||
matplotlib==3.10.0
|
matplotlib
|
||||||
mccabe==0.7.0
|
mccabe
|
||||||
mdurl==0.1.2
|
mdurl
|
||||||
MouseInfo==0.1.3
|
MouseInfo
|
||||||
mpmath==1.3.0
|
mpmath
|
||||||
multidict==6.1.0
|
multidict
|
||||||
mypy-extensions==1.0.0
|
mypy-extensions
|
||||||
networkx==3.4.2
|
networkx
|
||||||
newrelic==10.4.0
|
newrelic
|
||||||
nltk==3.9.1
|
nltk
|
||||||
numpy==2.2.2
|
numpy
|
||||||
oauthlib==3.2.2
|
oauthlib
|
||||||
ofxtools==0.9.5
|
ofxtools
|
||||||
openai==1.60.0
|
openai
|
||||||
opencv-contrib-python==4.11.0.86
|
opencv-contrib-python
|
||||||
opencv-python==4.11.0.86
|
opencv-python
|
||||||
opencv-python-headless==4.11.0.86
|
opencv-python-headless
|
||||||
openpyxl==3.1.5
|
openpyxl
|
||||||
opt_einsum==3.4.0
|
opt_einsum
|
||||||
outcome==1.3.0.post0
|
outcome
|
||||||
packaging==24.2
|
packaging
|
||||||
pandas==2.2.3
|
pandas
|
||||||
pango==0.0.1
|
pango
|
||||||
pdfkit==1.0.0
|
pdfkit
|
||||||
phonenumbers==8.13.42
|
phonenumbers
|
||||||
pillow==10.4.0
|
pillow
|
||||||
platformdirs==4.3.6
|
platformdirs
|
||||||
prometheus_client==0.21.1
|
prometheus_client
|
||||||
propcache==0.2.1
|
propcache
|
||||||
protobuf==5.29.3
|
protobuf
|
||||||
psycopg==3.2.4
|
psycopg
|
||||||
psycopg-binary==3.2.4
|
psycopg-binary
|
||||||
psycopg-c==3.2.4
|
psycopg-c
|
||||||
py-moneyed==3.0
|
py-moneyed
|
||||||
PyAutoGUI==0.9.54
|
PyAutoGUI
|
||||||
pyclipper==1.3.0.post6
|
pyclipper
|
||||||
pycodestyle==2.12.1
|
pycodestyle
|
||||||
pycparser==2.22
|
pycparser
|
||||||
pydantic==2.10.5
|
pydantic
|
||||||
pydantic_core==2.27.2
|
pydantic_core
|
||||||
pydotplus==2.0.2
|
pydotplus
|
||||||
pydyf==0.11.0
|
pydyf
|
||||||
PyGetWindow==0.0.9
|
PyGetWindow
|
||||||
Pygments==2.19.1
|
Pygments
|
||||||
PyJWT==2.10.1
|
PyJWT
|
||||||
pylint==3.3.3
|
pylint
|
||||||
PyMsgBox==1.0.9
|
PyMsgBox
|
||||||
PyMySQL==1.1.1
|
PyMySQL
|
||||||
pyobjc-core==11.0
|
pyobjc-core
|
||||||
pyobjc-framework-Cocoa==11.0
|
pyobjc-framework-Cocoa
|
||||||
pyobjc-framework-Quartz==11.0
|
pyobjc-framework-Quartz
|
||||||
pyparsing==3.2.1
|
pyparsing
|
||||||
pyperclip==1.9.0
|
pyperclip
|
||||||
pyphen==0.17.2
|
pyphen
|
||||||
pypng==0.20220715.0
|
pypng
|
||||||
PyRect==0.2.0
|
PyRect
|
||||||
PyScreeze==1.0.1
|
PyScreeze
|
||||||
pyserial==3.5
|
pyserial
|
||||||
PySocks==1.7.1
|
PySocks
|
||||||
python-bidi==0.6.3
|
python-bidi
|
||||||
python-dateutil==2.9.0.post0
|
python-dateutil
|
||||||
python-docx==1.1.2
|
python-docx
|
||||||
python-openid==2.2.5
|
python-openid
|
||||||
python-stdnum==1.20
|
python-stdnum
|
||||||
python3-saml==1.16.0
|
python3-saml
|
||||||
pytweening==1.2.0
|
pytweening
|
||||||
pytz==2024.2
|
pytz
|
||||||
pyvin==0.0.2
|
pyvin
|
||||||
pywa==2.7.0
|
pywa
|
||||||
pywhat==5.1.0
|
pywhat
|
||||||
pywhatkit==5.4
|
pywhatkit
|
||||||
PyYAML==6.0.2
|
PyYAML
|
||||||
pyzbar==0.1.9
|
pyzbar
|
||||||
qrcode==8.0
|
qrcode
|
||||||
RapidFuzz==3.11.0
|
RapidFuzz
|
||||||
regex==2024.11.6
|
regex
|
||||||
reportlab==4.2.5
|
reportlab
|
||||||
requests==2.32.3
|
requests
|
||||||
requests-oauthlib==2.0.0
|
requests-oauthlib
|
||||||
rfc3986==2.0.0
|
rfc3986
|
||||||
rich==13.9.4
|
rich
|
||||||
rubicon-objc==0.5.0
|
rubicon-objc
|
||||||
sacremoses==0.1.1
|
sacremoses
|
||||||
scikit-image==0.25.0
|
scikit-image
|
||||||
scikit-learn==1.6.1
|
scikit-learn
|
||||||
scipy==1.15.1
|
scipy
|
||||||
selenium==4.28.1
|
selenium
|
||||||
sentencepiece==0.2.0
|
sentencepiece
|
||||||
shapely==2.0.6
|
shapely
|
||||||
simsimd==6.2.1
|
simsimd
|
||||||
six==1.17.0
|
six
|
||||||
sniffio==1.3.1
|
sniffio
|
||||||
snowballstemmer==2.2.0
|
snowballstemmer
|
||||||
sortedcontainers==2.4.0
|
sortedcontainers
|
||||||
soupsieve==2.6
|
soupsieve
|
||||||
SQLAlchemy==2.0.37
|
SQLAlchemy
|
||||||
sqlparse==0.5.3
|
sqlparse
|
||||||
stanza==1.10.1
|
stanza
|
||||||
stringzilla==3.11.3
|
stringzilla
|
||||||
suds==1.2.0
|
suds
|
||||||
swapper==1.3.0
|
swapper
|
||||||
sympy==1.13.1
|
sympy
|
||||||
tablib==3.8.0
|
tablib
|
||||||
termcolor==2.5.0
|
termcolor
|
||||||
threadpoolctl==3.5.0
|
threadpoolctl
|
||||||
tifffile==2025.1.10
|
tifffile
|
||||||
tinycss2==1.4.0
|
tinycss2
|
||||||
tinyhtml5==2.0.0
|
tinyhtml5
|
||||||
tomli==2.2.1
|
tomli
|
||||||
tomlkit==0.13.2
|
tomlkit
|
||||||
torch==2.5.1
|
torch
|
||||||
tqdm==4.67.1
|
tqdm
|
||||||
trio==0.28.0
|
trio
|
||||||
trio-websocket==0.11.1
|
trio-websocket
|
||||||
twilio==9.4.3
|
twilio
|
||||||
typing-inspect==0.9.0
|
typing-inspect
|
||||||
typing_extensions==4.12.2
|
typing_extensions
|
||||||
tzdata==2025.1
|
tzdata
|
||||||
Unidecode==1.3.8
|
Unidecode
|
||||||
upgrade-requirements==1.7.0
|
upgrade-requirements
|
||||||
urllib3==2.3.0
|
urllib3
|
||||||
vin==0.6.2
|
vin
|
||||||
vininfo==1.8.0
|
vininfo
|
||||||
vishap==0.1.5
|
vishap
|
||||||
vpic-api==0.7.4
|
vpic-api
|
||||||
weasyprint==63.1
|
weasyprint
|
||||||
webencodings==0.5.1
|
webencodings
|
||||||
websocket-client==1.8.0
|
websocket-client
|
||||||
Werkzeug==3.1.3
|
Werkzeug
|
||||||
wikipedia==1.4.0
|
wikipedia
|
||||||
wsproto==1.2.0
|
wsproto
|
||||||
xmlsec==1.3.14
|
xmlsec
|
||||||
yarl==1.18.3
|
yarl
|
||||||
zopfli==0.2.3.post1
|
zopfli
|
||||||
|
|||||||
@ -35,11 +35,11 @@ def run():
|
|||||||
|
|
||||||
invoice_itemtxs = {
|
invoice_itemtxs = {
|
||||||
i.get("item_number"): {
|
i.get("item_number"): {
|
||||||
"unit_cost": i.get("total"),
|
"unit_cost": i.get("total_price"),
|
||||||
"quantity": i.get("quantity"),
|
"quantity": i.get("quantity"),
|
||||||
"total_amount": i.get("total_vat"),
|
"total_amount": i.get("total_vat"),
|
||||||
}
|
}
|
||||||
for i in finance_data.get("cars")
|
for i in finance_data.get("cars")
|
||||||
}
|
}
|
||||||
|
|
||||||
print(invoice_itemtxs)
|
print(finance_data)
|
||||||
@ -236,13 +236,36 @@
|
|||||||
<span class="nav-link-icon"><span data-feather="package"></span></span><span class="nav-link-text">{% trans 'bills'|capfirst %}</span>
|
<span class="nav-link-icon"><span data-feather="package"></span></span><span class="nav-link-text">{% trans 'bills'|capfirst %}</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="nav-item-wrapper">
|
||||||
|
<a class="nav-link dropdown-indicator label-1" href="#nv-reports" role="button" data-bs-toggle="collapse" aria-expanded="false" aria-controls="nv-reports">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<div class="dropdown-indicator-icon-wrapper"><span class="fas fa-caret-right dropdown-indicator-icon"></span></div>
|
||||||
|
<span class="nav-link-icon"><span class="fas fa-money-check-alt"></span></span><span class="nav-link-text">{% trans 'Reports' %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<div class="parent-wrapper label-1">
|
||||||
|
<ul class="nav collapse parent" data-bs-parent="#navbarVerticalCollapse" id="nv-reports">
|
||||||
|
<li class="nav-item">
|
||||||
|
{% if request.user.is_authenticated %}
|
||||||
|
<a class="nav-link" href="{% url 'entity-ic' request.user.dealer.entity.slug %}">
|
||||||
|
{% else %}
|
||||||
|
<a class="nav-link" href="#">
|
||||||
|
{% endif %}
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="nav-link-icon"><span data-feather="package"></span></span><span class="nav-link-text">{% trans 'Income Statement'|capfirst %}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
<a class="nav-link" href="{% url 'entity-bs' request.user.dealer.entity.slug %}">
|
<a class="nav-link" href="{% url 'entity-bs' request.user.dealer.entity.slug %}">
|
||||||
{% else %}
|
{% else %}
|
||||||
<a class="nav-link" href="#">
|
<a class="nav-link" href="#">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<span class="nav-link-icon"><span data-feather="package"></span></span><span class="nav-link-text">{% trans 'Reports'|capfirst %}</span>
|
<span class="nav-link-icon"><span data-feather="package"></span></span><span class="nav-link-text">{% trans 'Balance Sheet'|capfirst %}</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@ -0,0 +1,63 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load static %}
|
||||||
|
{% load custom_filters %}
|
||||||
|
|
||||||
|
{% block period_navigation %}
|
||||||
|
{% if unit_model %}
|
||||||
|
<div class="column is-12">{% period_navigation 'unit-ic' %}</div>
|
||||||
|
{% elif entity %}
|
||||||
|
<div class="column is-12">{% period_navigation 'entity-ic' %}</div>
|
||||||
|
{% elif ledger %}
|
||||||
|
<div class="column is-12">{% period_navigation 'ledger-ic' %}</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content has-text-centered">
|
||||||
|
<div class="container mb-4">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
{% if entity %}
|
||||||
|
<h1 class="is-size-2 has-text-weight-light">{{ entity.name }}</h1>
|
||||||
|
{% elif ledger %}
|
||||||
|
<h1 class="is-size-2 has-text-weight-light">{{ ledger.name }}</h1>
|
||||||
|
{% endif %}
|
||||||
|
{% if unit_model %}
|
||||||
|
<h3 class="is-size-4 has-text-weight-medium is-italic">{{ unit_model.name }} {% trans 'Unit' %}</h3>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<h1 class="is-size-2 has-text-weight-bold">{% trans 'Income Statement' %}</h1>
|
||||||
|
<h2 class="is-size-2 has-text-weight-light">
|
||||||
|
{% if quarter %}{{ year }} | Q{{ quarter }}
|
||||||
|
{% elif month %}{{ start_date | date:'F, Y' }}
|
||||||
|
{% else %}Fiscal Year {{ year }}
|
||||||
|
{% endif %}</h2>
|
||||||
|
<h3 class="is-size-4 is-italic has-font-weight-light">
|
||||||
|
{{ from_date | date:'m/d/Y' }} - {{ to_date | date:'m/d/Y' }}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% income_statement_table io_model=object %}
|
||||||
|
|
||||||
|
{% if ledger %}
|
||||||
|
<a class="button is-fullwidth is-dark my-2"
|
||||||
|
href="{% url 'django_ledger:ledger-list' entity_slug=view.kwargs.entity_slug %}">Go
|
||||||
|
Back</a>
|
||||||
|
{% elif entity %}
|
||||||
|
<a class="button is-fullwidth is-dark my-2"
|
||||||
|
href="{% url 'django_ledger:entity-dashboard' entity_slug=view.kwargs.entity_slug %}">Go
|
||||||
|
Back</a>
|
||||||
|
{% endif %}
|
||||||
|
<a class="button is-fullwidth is-light my-2"
|
||||||
|
href="?by_unit=1">{% trans 'By Unit' %}</a>
|
||||||
|
|
||||||
|
<a class="button is-fullwidth is-link my-2"
|
||||||
|
href="{{ request.path }}?format=pdf">{% trans 'Download PDF' %}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@ -45,9 +45,12 @@
|
|||||||
{% elif estimate.status == 'in_review' %}
|
{% elif estimate.status == 'in_review' %}
|
||||||
<button id="accept_estimate" onclick="setFormAction('approved')" class="btn btn-phoenix-secondary" data-bs-toggle="modal" data-bs-target="#confirmModal"><span class="d-none d-sm-inline-block">{% trans 'Mark As Accept' %}</span></button>
|
<button id="accept_estimate" onclick="setFormAction('approved')" class="btn btn-phoenix-secondary" data-bs-toggle="modal" data-bs-target="#confirmModal"><span class="d-none d-sm-inline-block">{% trans 'Mark As Accept' %}</span></button>
|
||||||
{% elif estimate.status == 'approved' %}
|
{% elif estimate.status == 'approved' %}
|
||||||
<a href="{% url 'create_sale_order' estimate.pk %}" class="btn btn-phoenix-primary"><span class="d-none d-sm-inline-block">{% trans 'Create Sale Order' %}</span></a>
|
{% if estimate.sale_orders.first %}
|
||||||
<a href="{% url 'invoice_create' estimate.pk %}" class="btn btn-phoenix-primary"><span class="d-none d-sm-inline-block">{% trans 'Create Invoice' %}</span></a>
|
<a href="{% url 'invoice_create' estimate.pk %}" class="btn btn-phoenix-primary"><span class="d-none d-sm-inline-block">{% trans 'Create Invoice' %}</span></a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{% url 'create_sale_order' estimate.pk %}" class="btn btn-phoenix-primary"><span class="d-none d-sm-inline-block">{% trans 'Create Sale Order' %}</span></a>
|
||||||
<a href="{% url 'preview_sale_order' estimate.pk %}" class="btn btn-phoenix-primary"><span class="d-none d-sm-inline-block">{% trans 'Preview Sale Order' %}</span></a>
|
<a href="{% url 'preview_sale_order' estimate.pk %}" class="btn btn-phoenix-primary"><span class="d-none d-sm-inline-block">{% trans 'Preview Sale Order' %}</span></a>
|
||||||
|
{% endif %}
|
||||||
{% elif estimate.status == 'in_review' %}
|
{% elif estimate.status == 'in_review' %}
|
||||||
<a href="{% url 'estimate_preview' estimate.pk %}" class="btn btn-phoenix-primary"><span class="d-none d-sm-inline-block">{% trans 'Preview' %}</span></a>
|
<a href="{% url 'estimate_preview' estimate.pk %}" class="btn btn-phoenix-primary"><span class="d-none d-sm-inline-block">{% trans 'Preview' %}</span></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -137,15 +140,15 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<tr class="bg-body-secondary total-sum">
|
<tr class="bg-body-secondary total-sum">
|
||||||
<td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="4">{% trans "Discount Amount" %}</td>
|
<td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="4">{% trans "Vat" %} ({{data.vat}}%)</td>
|
||||||
<td class="align-middle text-start fw-semibold">
|
<td class="align-middle text-start fw-semibold">
|
||||||
<span id="grand-total">- {{data.total_discount}}</span>
|
<span id="grand-total">+ {{data.total_vat_amount}}</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="bg-body-secondary total-sum">
|
<tr class="bg-body-secondary total-sum">
|
||||||
<td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="4">{% trans "Vat" %} ({{data.vat}}%)</td>
|
<td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="4">{% trans "Discount Amount" %}</td>
|
||||||
<td class="align-middle text-start fw-semibold">
|
<td class="align-middle text-start text-danger fw-semibold ">
|
||||||
<span id="grand-total"></span>
|
<span id="grand-total">- {{data.total_discount}}</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="bg-body-secondary total-sum">
|
<tr class="bg-body-secondary total-sum">
|
||||||
|
|||||||
@ -84,6 +84,20 @@
|
|||||||
<p class="ps-6 ps-sm-0 fw-semibold mb-0">{{ estimate.customer.address_1 }}</p>
|
<p class="ps-6 ps-sm-0 fw-semibold mb-0">{{ estimate.customer.address_1 }}</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="py-2">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<div class="d-flex bg-info-subtle rounded-circle flex-center me-3" style="width:24px; height:24px">
|
||||||
|
<span class="text-info-dark" data-feather="trending-up" style="width:16px; height:16px"></span>
|
||||||
|
</div>
|
||||||
|
<p class="fw-bold mb-0">Total Discount</p>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="py-2 d-none d-sm-block pe-sm-2">:</td>
|
||||||
|
<td class="py-2">
|
||||||
|
<p class="ps-6 ps-sm-0 fw-semibold mb-0">${{ data.total_discount }}</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="py-2">
|
<td class="py-2">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
@ -98,6 +112,7 @@
|
|||||||
<p class="ps-6 ps-sm-0 fw-semibold mb-0">${{ data.grand_total }}</p>
|
<p class="ps-6 ps-sm-0 fw-semibold mb-0">${{ data.grand_total }}</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -143,7 +158,7 @@
|
|||||||
<td class="create_by align-middle white-space-nowrap fw-semibold text-body-highlight">{{car.year}}</td>
|
<td class="create_by align-middle white-space-nowrap fw-semibold text-body-highlight">{{car.year}}</td>
|
||||||
<td class="last_activity align-middle text-center py-2">
|
<td class="last_activity align-middle text-center py-2">
|
||||||
<div class="d-flex align-items-center flex-1">
|
<div class="d-flex align-items-center flex-1">
|
||||||
<span class="fw-bold fs-9 text-body">${{car.total_vat}}</span>
|
<span class="fw-bold fs-9 text-body">${{car.total}}</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@ -237,7 +237,7 @@
|
|||||||
<tr class="bg-body-secondary total-sum">
|
<tr class="bg-body-secondary total-sum">
|
||||||
<td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="4">{% trans "VAT" %} ({{data.vat}}%)</td>
|
<td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="4">{% trans "VAT" %} ({{data.vat}}%)</td>
|
||||||
<td class="align-middle text-start fw-semibold">
|
<td class="align-middle text-start fw-semibold">
|
||||||
<span id="grand-total">+ {{vat_amount}}</span>
|
<span id="grand-total">+ {{data.total_vat_amount}}</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="bg-body-secondary total-sum">
|
<tr class="bg-body-secondary total-sum">
|
||||||
|
|||||||
@ -208,11 +208,11 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for item in car_and_item_info %}
|
{% for item in data.cars %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="">{{item.info.make}}</td>
|
<td class="">{{item.make}}</td>
|
||||||
<td class="align-middle">{{item.quantity}}</td>
|
<td class="align-middle">{{item.quantity}}</td>
|
||||||
<td class="align-middle ps-5">{{item.finances.selling_price}}</td>
|
<td class="align-middle ps-5">{{item.selling_price}}</td>
|
||||||
<td class="align-middle text-body-tertiary fw-semibold">{{item.total}}</td>
|
<td class="align-middle text-body-tertiary fw-semibold">{{item.total}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -222,10 +222,10 @@
|
|||||||
|
|
||||||
<!-- Additional Charges (VAT and Services) -->
|
<!-- Additional Charges (VAT and Services) -->
|
||||||
<div class="additional-charges">
|
<div class="additional-charges">
|
||||||
<p><strong>VAT/ضريبة القيمة المضافة ({{vat}}%):</strong> <span class="highlight">{{vat_amount}} {{ _("SAR") }}</span></p>
|
<p><strong>VAT/ضريبة القيمة المضافة ({{vat}}%):</strong> <span class="highlight">{{data.vat}} {{ _("SAR") }}</span></p>
|
||||||
<p><strong>Additional Services/ الخدمات الإضافية</strong>
|
<p><strong>Additional Services/ الخدمات الإضافية</strong>
|
||||||
<br>
|
<br>
|
||||||
{% for service in additional_services %}
|
{% for service in data.additional_services %}
|
||||||
<span class="highlight">{{service.name}} - {{service.price}} {{ _("SAR") }}</span><br>
|
<span class="highlight">{{service.name}} - {{service.price}} {{ _("SAR") }}</span><br>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</p>
|
</p>
|
||||||
@ -233,7 +233,7 @@
|
|||||||
|
|
||||||
<!-- Total -->
|
<!-- Total -->
|
||||||
<div class="invoice-total">
|
<div class="invoice-total">
|
||||||
<p><strong>Total/الإجمالي</strong> <span class="highlight">{{total}} {{ _("SAR") }}</span></p>
|
<p><strong>Total/الإجمالي</strong> <span class="highlight">{{data.grand_total}} {{ _("SAR") }}</span></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Footer Note -->
|
<!-- Footer Note -->
|
||||||
|
|||||||
@ -21,8 +21,11 @@
|
|||||||
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
|
<tr class="hover-actions-trigger btn-reveal-trigger position-static">
|
||||||
<td class="align-middle product white-space-nowrap py-0">{{ order.formatted_order_id }}</td>
|
<td class="align-middle product white-space-nowrap py-0">{{ order.formatted_order_id }}</td>
|
||||||
<td class="align-middle product white-space-nowrap py-0">{{ order.estimate.customer.customer_name }}</td>
|
<td class="align-middle product white-space-nowrap py-0">{{ order.estimate.customer.customer_name }}</td>
|
||||||
<td class="align-middle product white-space-nowrap">{{ order.estimate }}</td>
|
<td class="align-middle product white-space-nowrap">
|
||||||
|
<a href="{% url 'estimate_detail' order.estimate.pk %}">
|
||||||
|
{{ order.estimate }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
{% comment %} <a href="{% url 'estimate_detail' estimate.pk %}"
|
{% comment %} <a href="{% url 'estimate_detail' estimate.pk %}"
|
||||||
class="btn btn-sm btn-phoenix-success">
|
class="btn btn-sm btn-phoenix-success">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user