This commit is contained in:
gitea 2025-01-28 12:28:05 +00:00
parent 7142975004
commit a3cb3c5f55
13 changed files with 424 additions and 113 deletions

208
Pipfile Normal file
View File

@ -0,0 +1,208 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
aiohappyeyeballs = "==2.4.4"
aiohttp = "==3.11.11"
aiohttp-retry = "==2.8.3"
aiosignal = "==1.3.2"
alabaster = "==1.0.0"
albucore = "==0.0.23"
albumentations = "==2.0.0"
annotated-types = "==0.7.0"
anyio = "==4.8.0"
arabic-reshaper = "==3.0.0"
asgiref = "==3.8.1"
astor = "==0.8.1"
astroid = "==3.3.8"
attrs = "==23.2.0"
autopep8 = "==2.3.2"
babel = "==2.15.0"
beautifulsoup4 = "==4.12.3"
bleach = "==6.2.0"
blinker = "==1.9.0"
brotli = "==1.1.0"
certifi = "==2024.12.14"
cffi = "==1.17.1"
chardet = "==5.2.0"
charset-normalizer = "==3.4.1"
click = "==8.1.8"
colorama = "==0.4.6"
commonmark = "==0.9.1"
contourpy = "==1.3.1"
crispy-bootstrap5 = "==2024.10"
cryptography = "==44.0.0"
cssselect2 = "==0.7.0"
ctranslate2 = "==4.5.0"
cycler = "==0.12.1"
cython = "==3.0.11"
decorator = "==5.1.1"
desert = "==2020.11.18"
dill = "==0.3.9"
distro = "==1.9.0"
dj-rest-auth = "==7.0.1"
dj-shop-cart = "==7.1.1"
django = "==5.1.5"
django-allauth = "==65.3.1"
django-appointment = "==3.7.4"
django-autoslug = "==1.9.9"
django-bootstrap5 = "==24.3"
django-classy-tags = "==4.1.0"
django-cors-headers = "==4.6.0"
django-countries = "==7.6.1"
django-crispy-forms = "==2.3"
django-debug-toolbar = "==5.0.1"
django-extensions = "==3.2.3"
django-filter = "==24.3"
django-formtools = "==2.5.1"
django-ledger = "==0.7.3"
django-money = "==3.5.3"
django-nine = "==0.2.7"
django-nonefield = "==0.4"
django-phonenumber-field = "==8.0.0"
django-picklefield = "==3.2"
django-prometheus = "==2.3.1"
django-q2 = "==1.7.6"
django-sekizai = "==4.1.0"
django-silk = "==5.3.2"
django-sms = "==0.7.0"
django-sslserver = "==0.22"
django-tables2 = "==2.7.5"
django-treebeard = "==4.7.1"
django-view-breadcrumbs = "==2.5.1"
djangocms-admin-style = "==3.3.1"
djangorestframework = "==3.15.2"
djangorestframework-simplejwt = "==5.4.0"
djangoviz = "==0.1.1"
docutils = "==0.21.2"
easy-thumbnails = "==2.10"
et-xmlfile = "==2.0.0"
faker = "==33.3.1"
filelock = "==3.16.1"
fire = "==0.7.0"
flask = "==3.1.0"
fonttools = "==4.55.3"
frozenlist = "==1.5.0"
fsspec = "==2024.12.0"
gprof2dot = "==2024.6.6"
graphqlclient = "==0.2.4"
greenlet = "==3.1.1"
h11 = "==0.14.0"
h2 = "==4.1.0"
hpack = "==4.0.0"
hstspreload = "==2025.1.1"
httpcore = "==1.0.7"
httpx = "==0.28.1"
hyperframe = "==6.0.1"
idna = "==3.10"
imageio = "==2.37.0"
imagesize = "==1.4.1"
imgaug = "==0.4.0"
iso4217 = "==1.12.20240625"
isodate = "==0.7.2"
isort = "==5.13.2"
itsdangerous = "==2.2.0"
jinja2 = "==3.1.5"
jiter = "==0.8.2"
joblib = "==1.4.2"
kiwisolver = "==1.4.8"
lazy-loader = "==0.4"
ledger = "==1.0.1"
libretranslatepy = "==2.1.4"
lmdb = "==1.6.2"
lxml = "==5.3.0"
markdown = "==3.7"
markdown-it-py = "==3.0.0"
markupsafe = "==3.0.2"
marshmallow = "==3.25.1"
matplotlib = "==3.10.0"
mccabe = "==0.7.0"
mdurl = "==0.1.2"
mouseinfo = "==0.1.3"
mpmath = "==1.3.0"
multidict = "==6.1.0"
mypy-extensions = "==1.0.0"
networkx = "==3.4.2"
newrelic = "==10.4.0"
nltk = "==3.9.1"
libquadmath = "==2.2.2"
oauthlib = "==3.2.2"
ofxtools = "==0.9.5"
openai = "==1.59.8"
opencv-contrib-python = "==4.11.0.86"
opencv-python = "==4.11.0.86"
opencv-python-headless = "==4.11.0.86"
openpyxl = "==3.1.5"
opt-einsum = "==3.4.0"
outcome = "==1.3.0.post0"
packaging = "==24.2"
pandas = "==2.2.3"
pango = "==0.0.1"
pdfkit = "==1.0.0"
phonenumbers = "==8.13.53"
pillow = "==11.1.0"
platformdirs = "==4.3.6"
prometheus-client = "==0.21.1"
propcache = "==0.2.1"
protobuf = "==5.29.3"
psycopg = "==3.2.4"
psycopg-binary = "==3.2.4"
psycopg-c = "==3.2.4"
py-moneyed = "==3.0"
pyautogui = "==0.9.54"
pyclipper = "==1.3.0.post6"
pycodestyle = "==2.12.1"
pycparser = "==2.22"
pydantic = "==2.10.5"
pydantic-core = "==2.27.2"
pydotplus = "==2.0.2"
pydyf = "==0.11.0"
pygetwindow = "==0.0.9"
pygments = "==2.19.1"
pyjwt = "==2.10.1"
pylint = "==3.3.3"
pymsgbox = "==1.0.9"
pymysql = "==1.1.1"
pyobjc-core = "==11.0"
pyobjc-framework-cocoa = "==11.0"
pyobjc-framework-quartz = "==11.0"
pyparsing = "==3.2.1"
pyperclip = "==1.9.0"
pyphen = "==0.17.0"
pypng = "==0.20220715.0"
pyrect = "==0.2.0"
pyscreeze = "==1.0.1"
pyserial = "==3.5"
pysocks = "==1.7.1"
python-bidi = "==0.6.3"
python-dateutil = "==2.9.0.post0"
python-docx = "==1.1.2"
python-openid = "==2.2.5"
python3-saml = "==1.16.0"
pytweening = "==1.2.0"
pytz = "==2024.2"
pyvin = "==0.0.2"
pywa = "==2.7.0"
pywhat = "==5.1.0"
pywhatkit = "==5.4"
pyyaml = "==6.0.2"
pyzbar = "==0.1.9"
qrcode = "==8.0"
rapidfuzz = "==3.11.0"
regex = "==2024.11.6"
reportlab = "==4.2.5"
requests = "==2.32.3"
requests-oauthlib = "==2.0.0"
rfc3986 = "==2.0.0"
rich = "==13.9.4"
rubicon-objc = "==0.5.0"
sacremoses = "==0.1.1"
scikit-image = "==0.25.0"
scikit-learn = "*"
[dev-packages]
[requires]
python_version = "3.12"

Binary file not shown.

View File

@ -9,6 +9,8 @@ from phonenumber_field.phonenumber import PhoneNumber
from .mixins import AddClassMixin from .mixins import AddClassMixin
from django.forms.models import inlineformset_factory from django.forms.models import inlineformset_factory
from django_ledger.forms.invoice import InvoiceModelCreateForm as InvoiceModelCreateFormBase from django_ledger.forms.invoice import InvoiceModelCreateForm as InvoiceModelCreateFormBase
from django_ledger.forms.estimate import EstimateModelCreateForm as EstimateModelCreateFormBase
from django_ledger.forms.bill import BillModelCreateForm as BillModelCreateFormBase from django_ledger.forms.bill import BillModelCreateForm as BillModelCreateFormBase
from django_ledger.forms.vendor import VendorModelForm from django_ledger.forms.vendor import VendorModelForm
from .models import ( from .models import (
@ -675,7 +677,10 @@ class InvoiceModelCreateForm(InvoiceModelCreateFormBase):
self.fields['prepaid_account'].widget = forms.HiddenInput() self.fields['prepaid_account'].widget = forms.HiddenInput()
self.fields['unearned_account'].widget = forms.HiddenInput() self.fields['unearned_account'].widget = forms.HiddenInput()
self.fields['date_draft'] = forms.DateField(widget=DateInput(attrs={'type': 'date'})) self.fields['date_draft'] = forms.DateField(widget=DateInput(attrs={'type': 'date'}))
def get_customer_queryset(self):
if 'customer' in self.fields:
self.fields['customer'].queryset = self.USER_MODEL.dealer.entity.get_customers()
class BillModelCreateForm(BillModelCreateFormBase): class BillModelCreateForm(BillModelCreateFormBase):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -692,4 +697,15 @@ class SaleOrderForm(forms.ModelForm):
fields = ['estimate','payment_method', 'comments'] fields = ['estimate','payment_method', 'comments']
widgets = { widgets = {
'comments': forms.Textarea(attrs={'rows': 3}), 'comments': forms.Textarea(attrs={'rows': 3}),
} }
class EstimateModelCreateForm(EstimateModelCreateFormBase):
def __init__(self, *args, entity_slug, user_model, **kwargs):
super(EstimateModelCreateForm, self).__init__(*args, entity_slug=entity_slug, user_model=user_model, **kwargs)
self.ENTITY_SLUG = entity_slug
self.USER_MODEL = user_model
self.fields['customer'].queryset = self.get_customer_queryset()
def get_customer_queryset(self):
return self.USER_MODEL.dealer.entity.get_customers()

View File

@ -87,13 +87,13 @@ def create_ledger_entity(sender, instance, created, **kwargs):
use_accrual_method=False, use_accrual_method=False,
fy_start_month=1, fy_start_month=1,
) )
if entity: if entity:
instance.entity = entity instance.entity = entity
instance.save() instance.save()
coa = entity.create_chart_of_accounts( coa = entity.create_chart_of_accounts(
assign_as_default=True, commit=True, coa_name=_(f"{entity_name}-COA") assign_as_default=True, commit=True, coa_name=_(f"{entity_name}-COA")
) )
if coa: if coa:
# Create unit of measures # Create unit of measures
entity.create_uom(name="Unit", unit_abbr="unit") entity.create_uom(name="Unit", unit_abbr="unit")
@ -688,9 +688,10 @@ def create_item_model(sender, instance, created, **kwargs):
name=instance.vin, name=instance.vin,
item_type=ItemModel.ITEM_TYPE_MATERIAL, item_type=ItemModel.ITEM_TYPE_MATERIAL,
uom_model=uom, uom_model=uom,
coa_model=coa, coa_model=coa,
additional_info={}
) )
product.additional_info = {}
product.save()
product = entity.get_items_all().filter(name=instance.vin).first() product = entity.get_items_all().filter(name=instance.vin).first()
product.additional_info.update({'car_info': instance.to_dict()}) product.additional_info.update({'car_info': instance.to_dict()})
@ -702,6 +703,7 @@ def update_item_model_cost(sender, instance, created, **kwargs):
entity = instance.car.dealer.entity entity = instance.car.dealer.entity
product = entity.get_items_all().filter(name=instance.car.vin).first() product = entity.get_items_all().filter(name=instance.car.vin).first()
product.default_amount = instance.selling_price product.default_amount = instance.selling_price
product.additional_info = {} product.additional_info = {}
product.additional_info.update({"car_finance":instance.to_dict()}) product.additional_info.update({"car_finance":instance.to_dict()})

View File

@ -1,3 +1,4 @@
from django.core.exceptions import ObjectDoesNotExist
import json import json
import random import random
import datetime import datetime
@ -577,3 +578,98 @@ def to_dict(obj):
else: else:
obj_dict[key] = str(value) obj_dict[key] = str(value)
return obj_dict return obj_dict
class CarFinanceCalculator:
VAT_OBJ_NAME = 'vat_rate'
CAR_FINANCE_KEY = 'car_finance'
CAR_INFO_KEY = 'car_info'
ADDITIONAL_SERVICES_KEY = 'additional_services'
def __init__(self, model):
self.model = model
self.vat_rate = self._get_vat_rate()
self.item_transactions = self._get_item_transactions()
self.additional_services = self._get_additional_services()
def _get_vat_rate(self):
vat = models.VatRate.objects.filter(is_active=True).first()
if not vat:
raise ObjectDoesNotExist("No active VAT rate found")
return vat.rate
def _get_item_transactions(self):
return self.model.get_itemtxs_data()[0].all()
@staticmethod
def _get_quantity(item):
return item.ce_quantity or item.quantity
def _get_nested_value(self, item, *keys):
current = item.item_model.additional_info
for key in keys:
current = current.get(key, {})
return current
def _get_car_data(self, item):
quantity = self._get_quantity(item)
car_finance = self._get_nested_value(item, self.CAR_FINANCE_KEY)
car_info = self._get_nested_value(item, self.CAR_INFO_KEY)
unit_price = Decimal(car_finance.get('selling_price', 0))
return {
"item_number": item.item_model.item_number,
"vin": car_info.get('vin'),
"make": car_info.get('make'),
"model": car_info.get('model'),
"year": car_info.get('year'),
"trim": car_info.get('mileage'), # Verify if this should actually be mileage
"cost_price": car_finance.get('cost_price'),
"selling_price": car_finance.get('selling_price'),
"discount": car_finance.get('discount_amount'),
"quantity": quantity,
"unit_price": unit_price,
"total": unit_price * Decimal(quantity),
"total_vat": car_finance.get('total_vat'),
"additional_services": self._get_nested_value(item, self.ADDITIONAL_SERVICES_KEY),
}
def _get_additional_services(self):
return [
{"name": service.name, "price": service.price}
for item in self.item_transactions
for service in self._get_nested_value(item, self.ADDITIONAL_SERVICES_KEY) or []
]
def calculate_totals(self):
total_price = sum(
Decimal(self._get_nested_value(item, self.CAR_FINANCE_KEY, 'selling_price')) *
Decimal(self._get_quantity(item))
for item in self.item_transactions
)
total_vat_amount = total_price * self.vat_rate
total_discount = sum(
Decimal(self._get_nested_value(item, self.CAR_FINANCE_KEY, 'discount_amount'))
for item in self.item_transactions
)
return {
"total_price": total_price,
"total_vat_amount": total_vat_amount,
"total_discount": total_discount,
"grand_total": (total_price + total_vat_amount) - total_discount,
}
def get_finance_data(self):
totals = self.calculate_totals()
return {
"cars": [self._get_car_data(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_vat": totals['total_vat_amount'] + totals['total_price'],
"total_discount": totals['total_discount'],
"grand_total": totals['grand_total'],
"additionals": self.additional_services,
"vat": self.vat_rate,
}

View File

@ -1,3 +1,4 @@
from rich import print
from decimal import Decimal from decimal import Decimal
from django.core.paginator import Paginator from django.core.paginator import Paginator
from django.forms import DateField, DateInput, HiddenInput, TextInput from django.forms import DateField, DateInput, HiddenInput, TextInput
@ -34,7 +35,8 @@ from django_ledger.forms.invoice import (
PaidInvoiceModelUpdateForm, PaidInvoiceModelUpdateForm,
) )
from django_ledger.forms.account import AccountModelCreateForm, AccountModelUpdateForm from django_ledger.forms.account import AccountModelCreateForm, AccountModelUpdateForm
from django_ledger.forms.estimate import EstimateModelCreateForm # from django_ledger.forms.estimate import EstimateModelCreateForm
from django_ledger.forms.invoice import InvoiceModelCreateForm from django_ledger.forms.invoice import InvoiceModelCreateForm
from django_ledger.forms.item import ( from django_ledger.forms.item import (
ServiceCreateForm, ServiceCreateForm,
@ -82,6 +84,7 @@ from django.contrib.auth.mixins import PermissionRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
from .utils import ( from .utils import (
CarFinanceCalculator,
calculate_vat_amount, calculate_vat_amount,
get_calculations, get_calculations,
get_car_finance_data, get_car_finance_data,
@ -2349,7 +2352,7 @@ def create_estimate(request):
} }
) )
form = EstimateModelCreateForm(entity_slug=entity.slug, user_model=entity.admin) form = forms.EstimateModelCreateForm(entity_slug=entity.slug, user_model=entity.admin)
form.fields["customer"].queryset = entity.get_customers().filter(active=True) form.fields["customer"].queryset = entity.get_customers().filter(active=True)
car_list = models.Car.objects.filter( car_list = models.Car.objects.filter(
dealer=dealer, finances__selling_price__gt=0 dealer=dealer, finances__selling_price__gt=0
@ -2378,14 +2381,17 @@ 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) # data = get_financial_values(estimate)
calculator = CarFinanceCalculator(estimate)
kwargs["vat_amount"] = data["vat_amount"] finance_data = calculator.get_finance_data()
kwargs["total"] = data["grand_total"] # kwargs["vat_amount"] = data["vat_amount"]
kwargs["discount_amount"] = data["discount_amount"] # kwargs["total"] = data["grand_total"]
kwargs["vat"] = data["vat"] # kwargs["discount_amount"] = data["discount_amount"]
kwargs["car_and_item_info"] = data["car_and_item_info"] # kwargs["vat"] = data["vat"]
kwargs["additional_services"] = data["additional_services"] # kwargs["car_and_item_info"] = data["car_and_item_info"]
# kwargs["additional_services"] = data["additional_services"]
kwargs['data'] = finance_data
print(finance_data)
kwargs["invoice"] = ( kwargs["invoice"] = (
InvoiceModel.objects.all().filter(ce_model=estimate).first() InvoiceModel.objects.all().filter(ce_model=estimate).first()
) )
@ -2400,8 +2406,8 @@ def create_sale_order(request, pk):
form = forms.SaleOrderForm(request.POST) form = forms.SaleOrderForm(request.POST)
if form.is_valid(): if form.is_valid():
form.save() form.save()
if not estimate.is_completed(): if not estimate.is_approved():
estimate.mark_as_completed() estimate.mark_as_approved()
estimate.save() estimate.save()
messages.success(request, "Sale Order created successfully") messages.success(request, "Sale Order created successfully")
return redirect("estimate_detail", pk=pk) return redirect("estimate_detail", pk=pk)
@ -2409,11 +2415,13 @@ def create_sale_order(request, pk):
form = forms.SaleOrderForm() form = forms.SaleOrderForm()
form.fields["estimate"].queryset = EstimateModel.objects.filter(pk=pk) form.fields["estimate"].queryset = EstimateModel.objects.filter(pk=pk)
form.initial['estimate'] = estimate form.initial['estimate'] = estimate
data = get_car_finance_data(estimate) # data = get_car_finance_data(estimate)
calculator = CarFinanceCalculator(estimate)
finance_data = calculator.get_finance_data()
return render( return render(
request, request,
"sales/estimates/sale_order_form.html", "sales/estimates/sale_order_form.html",
{"form": form, "estimate": estimate, "items": items,"data": data}, {"form": form, "estimate": estimate, "items": items,"data": finance_data},
) )
def preview_sale_order(request,pk): def preview_sale_order(request,pk):
@ -2510,14 +2518,16 @@ 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) # 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["vat_amount"] = data["vat_amount"]
kwargs["discount_amount"] = data["discount_amount"] # kwargs["total"] = data["grand_total"]
kwargs["vat"] = data["vat"] # kwargs["discount_amount"] = data["discount_amount"]
kwargs["car_and_item_info"] = data["car_and_item_info"] # kwargs["vat"] = data["vat"]
kwargs["additional_services"] = data["additional_services"] # kwargs["car_and_item_info"] = data["car_and_item_info"]
# kwargs["additional_services"] = data["additional_services"]
kwargs["data"] = finance_data
kwargs["payments"] = JournalEntryModel.objects.filter( kwargs["payments"] = JournalEntryModel.objects.filter(
ledger=invoice.ledger ledger=invoice.ledger
).all() ).all()

Binary file not shown.

View File

@ -1,70 +1,45 @@
from decimal import Decimal from decimal import Decimal
from django_ledger.models import EstimateModel from django_ledger.models import EstimateModel,EntityModel
from rich import print from rich import print
from datetime import date
from inventory.models import VatRate from inventory.models import VatRate
from inventory.utils import CarFinanceCalculator
def run(): def run():
# estimate = EstimateModel.objects.first()
# calculator = CarFinanceCalculator(estimate)
# finance_data = calculator.get_finance_data()
# print(finance_data)
# entity = EntityModel.objects.get(name="ismail")
# bs_report = entity.get_balance_sheet_statement(
# to_date=date(2025, 1, 1),
# save_pdf=False,
# filepath='./'
# )
# ic_report = entity.get_income_statement(
# from_date=date(2022, 1, 1),
# to_date=date(2022, 12, 31),
# save_pdf=False,
# filepath='./'
# )
# # print(bs_report)
# print(ic_report.get_report_data())
estimate = EstimateModel.objects.first() estimate = EstimateModel.objects.first()
vat = VatRate.objects.filter(is_active=True).first() calculator = CarFinanceCalculator(estimate)
data = estimate.get_itemtxs_data()[0].all() finance_data = calculator.get_finance_data()
total = sum(
[
Decimal(item.item_model.additional_info["car_finance"]["selling_price"]) invoice_itemtxs = {
* Decimal(item.ce_quantity or item.quantity) i.get("item_number"): {
for item in data "unit_cost": i.get("total"),
] "quantity": i.get("quantity"),
) "total_amount": i.get("total_vat"),
}
additional_services = [] for i in finance_data.get("cars")
}
for i in data:
if i.item_model.additional_info["additional_services"]: print(invoice_itemtxs)
additional_services.extend(
[
{"name": x.name, "price": x.price}
for x in i.item_model.additional_info["additional_services"]
]
)
cars_info = {
"cars": [
{
"vin": x.item_model.additional_info["car_info"]["vin"],
"make": x.item_model.additional_info["car_info"]["make"],
"model": x.item_model.additional_info["car_info"]["model"],
"year": x.item_model.additional_info["car_info"]["year"],
"trim": x.item_model.additional_info["car_info"]["mileage"],
"cost_price": x.item_model.additional_info["car_finance"]["cost_price"],
"selling_price": x.item_model.additional_info["car_finance"][
"selling_price"
],
"discount": x.item_model.additional_info["car_finance"][
"discount_amount"
],
"total": x.item_model.additional_info["car_finance"]["total"],
"additional_services": x.item_model.additional_info[
"additional_services"
],
}
for x in data
],
"quantity": data.count(),
"total_price": total,
"total__vat": (total * vat.rate) + total,
"total_discount": sum(
Decimal(x.item_model.additional_info["car_finance"]["discount_amount"])
for x in data
),
"grand_total": Decimal(total * vat.rate)
+ total
- Decimal(
sum(
Decimal(x.item_model.additional_info["car_finance"]["discount_amount"])
for x in data
)
),
"additionals": additional_services,
}
print(cars_info)

View File

@ -236,9 +236,13 @@
<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>
{% 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 %}
<a class="nav-link" href="#">
{% 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 'bills'|capfirst %}</span> <span class="nav-link-icon"><span data-feather="package"></span></span><span class="nav-link-text">{% trans 'Reports'|capfirst %}</span>
</div> </div>
</a> </a>
</li> </li>

View File

@ -21,7 +21,7 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="card shadow-sm border-0 p-6"> <div class="card shadow-sm border-0 p-6">
<div class="card-body"> <div class="card-body">
<div class="text-center mb-5"> <div class="text-center mb-5">
@ -44,6 +44,7 @@
</h2> </h2>
<p class="h5 fst-italic fw-light">As of {{ to_date | date:'m/d/Y' }}</p> <p class="h5 fst-italic fw-light">As of {{ to_date | date:'m/d/Y' }}</p>
</div> </div>
<!-- Balance Sheet Statement --> <!-- Balance Sheet Statement -->
<div class="table-responsive"> <div class="table-responsive">

View File

@ -58,14 +58,14 @@
<span class="icon is-small">{% icon 'bi:arrow-down' 24 %}</span> <span class="icon is-small">{% icon 'bi:arrow-down' 24 %}</span>
</button> </button>
</div> </div>
{% comment %} <div class="dropdown-menu" id="dropdown-menu-{{ acc.uuid }}" role="menu"> <div class="dropdown-menu" id="dropdown-menu-{{ acc.uuid }}" role="menu">
<div class="dropdown-content"> <div class="dropdown-content">
<a href="{% url 'django_ledger:account-detail' entity_slug=entity_slug coa_slug=acc.coa_slug account_pk=acc.account_uuid %}" <a href="{% url 'django_ledger:account-detail' entity_slug=entity_slug coa_slug=acc.coa_slug account_pk=acc.account_uuid %}"
class="dropdown-item has-text-success">{% trans 'Detail' %}</a> class="dropdown-item has-text-success">{% trans 'Detail' %}</a>
<a href="{% url 'django_ledger:account-update' entity_slug=entity_slug coa_slug=acc.coa_slug account_pk=acc.account_uuid %}" <a href="{% url 'django_ledger:account-update' entity_slug=entity_slug coa_slug=acc.coa_slug account_pk=acc.account_uuid %}"
class="dropdown-item has-text-warning">{% trans 'Update' %}</a> class="dropdown-item has-text-warning">{% trans 'Update' %}</a>
</div> </div>
</div> {% endcomment %} </div>
</div> </div>
</td> </td>
</tr> </tr>

View File

@ -45,8 +45,7 @@
{% 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> <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>
{% elif estimate.status == 'completed' %}
<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>
<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>
{% elif estimate.status == 'in_review' %} {% elif estimate.status == 'in_review' %}
@ -128,31 +127,31 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for item in car_and_item_info %} {% for item in data.cars %}
<tr> <tr>
<td class="">{{forloop.counter}}</td> <td class="">{{forloop.counter}}</td>
<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.unit_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 %}
<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 "Discount Amount" %}</td>
<td class="align-middle text-start fw-semibold"> <td class="align-middle text-start fw-semibold">
<span id="grand-total">- {{discount_amount}}</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">
<td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="4">{% trans "Vat" %} ({{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"></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 "Additional Services" %}</td> <td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="4">{% trans "Additional Services" %}</td>
<td class="align-middle text-start fw-semibold"> <td class="align-middle text-start fw-semibold">
{% for service in additional_services %} {% for service in data.additional_services %}
<small><span class="fw-semibold">+ {{service.name}} - {{service.price}}</span></small><br> <small><span class="fw-semibold">+ {{service.name}} - {{service.price}}</span></small><br>
{% endfor %} {% endfor %}
</td> </td>
@ -160,7 +159,7 @@
<tr class="bg-body-secondary total-sum"> <tr class="bg-body-secondary total-sum">
<td class="align-middle ps-4 fw-bolder text-body-highlight" colspan="4">{% trans "Grand Total" %}</td> <td class="align-middle ps-4 fw-bolder text-body-highlight" colspan="4">{% trans "Grand Total" %}</td>
<td class="align-middle text-start fw-bolder"> <td class="align-middle text-start fw-bolder">
<span id="grand-total">{{total}}</span> <span id="grand-total">{{data.grand_total}}</span>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View File

@ -219,23 +219,23 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for item in car_and_item_info %} {% for item in data.cars %}
<tr> <tr>
<td class="">{{forloop.counter}}</td> <td class="">{{forloop.counter}}</td>
<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 %}
<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 "Discount Amount" %}</td>
<td class="align-middle text-start fw-semibold"> <td class="align-middle text-start fw-semibold">
<span id="grand-total">- {{discount_amount}}</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">
<td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="4">{% trans "VAT" %} ({{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">+ {{vat_amount}}</span>
</td> </td>
@ -243,7 +243,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 "Additional Services" %}</td> <td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="4">{% trans "Additional Services" %}</td>
<td class="align-middle text-start fw-bold"> <td class="align-middle text-start fw-bold">
{% for service in additional_services %} {% for service in data.additional_services %}
<small><span class="fw-bold">+ {{service.name}} - {{service.price}}</span></small><br> <small><span class="fw-bold">+ {{service.name}} - {{service.price}}</span></small><br>
{% endfor %} {% endfor %}
</td> </td>
@ -251,7 +251,7 @@
<tr class="bg-body-secondary total-sum"> <tr class="bg-body-secondary total-sum">
<td class="align-middle ps-4 fw-bolder text-body-highlight" colspan="4">{% trans "Grand Total" %}</td> <td class="align-middle ps-4 fw-bolder text-body-highlight" colspan="4">{% trans "Grand Total" %}</td>
<td class="align-middle text-start fw-bolder"> <td class="align-middle text-start fw-bolder">
<span id="grand-total">{{total}}</span> <span id="grand-total">{{data.grand_total}}</span>
</td> </td>
</tr> </tr>
</tbody> </tbody>