latest update

This commit is contained in:
gitea 2025-01-30 09:56:33 +00:00
parent 5ef0d68f7c
commit ecf1c375c1
16 changed files with 563 additions and 347 deletions

View 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,
),
]

View 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']},
),
]

View File

@ -1562,6 +1562,10 @@ class SaleOrder(models.Model):
])
comments = models.TextField(blank=True, null=True)
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):
if not self.formatted_order_id:

View File

@ -1,7 +1,7 @@
from django import template
from calendar import month_abbr
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()
@ -146,3 +146,35 @@ def balance_sheet_statement(context, io_model, to_date=None):
'user_model': user_model,
'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()
}

View File

@ -546,7 +546,23 @@ urlpatterns = [
path('entity/<slug:entity_slug>/balance-sheet/date/<int:year>/<int:month>/<int:day>/',
views.DateBalanceSheetView.as_view(),
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'),
]

View File

@ -284,15 +284,11 @@ def set_invoice_payment(dealer, entity, invoice, amount, payment_method):
vat_amount = 0
total_amount = 0
if invoice.terms == "on_receipt":
for x in invoice.get_itemtxs_data()[0].all():
# vat_amount += models.Car.objects.get(
# vin=x.item_model.name
# ).finances.vat_amount * Decimal(x.quantity)
total_amount += Decimal(x.unit_cost) * Decimal(x.quantity)
# grand_total = total_amount - Decimal(vat_amount)
total_amount
calculator = CarFinanceCalculator(invoice)
finance_data = calculator.get_finance_data()
# if invoice.terms == "on_receipt":
# for x in invoice.get_itemtxs_data()[0].all():
# total_amount += Decimal(x.unit_cost) * Decimal(x.quantity)
ledger = LedgerModel.objects.filter(
name__icontains=str(invoice.pk), entity=entity
@ -323,28 +319,26 @@ def set_invoice_payment(dealer, entity, invoice, amount, payment_method):
TransactionModel.objects.create(
journal_entry=journal,
account=debit_account, # Debit Cash
amount=amount, # Payment amount
amount=finance_data["grand_total"], # Payment amount
tx_type="debit",
description="Payment Received",
)
# if total_amount + invoice.
TransactionModel.objects.create(
journal_entry=journal,
account=credit_account, # Credit Accounts Receivable
amount=total_amount, # Payment amount
amount=finance_data["total_price"], # Payment amount
tx_type="credit",
description="Payment Received",
)
if vat_amount > 0:
TransactionModel.objects.create(
journal_entry=journal,
account=vat_payable_account, # Credit VAT Payable
amount=vat_amount,
tx_type="credit",
description="VAT Payable on Invoice",
TransactionModel.objects.create(
journal_entry=journal,
account=vat_payable_account, # Credit VAT Payable
amount=finance_data["total_vat_amount"],
tx_type="credit",
description="VAT Payable on Invoice",
)
invoice.make_payment(amount)
@ -622,7 +616,8 @@ class CarFinanceCalculator:
"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
"trim": car_info.get('trim'),
"mileage": car_info.get('mileage'),
"cost_price": car_finance.get('cost_price'),
"selling_price": car_finance.get('selling_price'),
"discount": car_finance.get('discount_amount'),
@ -657,7 +652,7 @@ class CarFinanceCalculator:
"total_price": total_price,
"total_vat_amount": total_vat_amount,
"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):
@ -668,6 +663,7 @@ class CarFinanceCalculator:
"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_vat_amount": totals['total_vat_amount'],
"total_discount": totals['total_discount'],
"grand_total": totals['grand_total'],
"additionals": self.additional_services,

View File

@ -2380,16 +2380,9 @@ class EstimateDetailView(LoginRequiredMixin, DetailView):
def get_context_data(self, **kwargs):
estimate = kwargs.get("object")
if estimate.get_itemtxs_data():
# data = get_financial_values(estimate)
if estimate.get_itemtxs_data():
calculator = CarFinanceCalculator(estimate)
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"]
finance_data = calculator.get_finance_data()
kwargs['data'] = finance_data
print(finance_data)
kwargs["invoice"] = (
@ -2517,16 +2510,10 @@ class InvoiceDetailView(LoginRequiredMixin, DetailView):
def get_context_data(self, **kwargs):
invoice = kwargs.get("object")
if invoice.get_itemtxs_data():
# data = get_financial_values(invoice)
if invoice.get_itemtxs_data():
calculator = CarFinanceCalculator(invoice)
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"]
print((finance_data["total_vat_amount"]+finance_data["total_price"]) == finance_data["grand_total"])
kwargs["data"] = finance_data
kwargs["payments"] = JournalEntryModel.objects.filter(
ledger=invoice.ledger
@ -2627,38 +2614,41 @@ def invoice_create(request, pk):
ledger.save()
invoice.save()
unit_items = estimate.get_itemtxs_data()[0]
vat = models.VatRate.objects.filter(is_active=True).first()
total = 0
discount_amount = 0
# unit_items = estimate.get_itemtxs_data()[0]
# vat = models.VatRate.objects.filter(is_active=True).first()
calculator = CarFinanceCalculator(estimate)
finance_data = calculator.get_finance_data()
# total = 0
# discount_amount = 0
itemtxs = []
for item in unit_items:
car = models.Car.objects.get(vin=item.item_model.name)
# 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
# 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": unit_cost,
"unit_revenue": unit_cost,
"quantity": item.ce_quantity,
"total_amount": grand_total,
}
)
# 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": unit_cost,
# "unit_revenue": unit_cost,
# "quantity": item.ce_quantity,
# "total_amount": grand_total,
# }
# )
invoice_itemtxs = {
i.get("item_number"): {
"unit_cost": i.get("unit_cost"),
"unit_cost": i.get("total_vat"),
"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(
@ -2705,14 +2695,16 @@ class InvoicePreviewView(LoginRequiredMixin, DetailView):
def get_context_data(self, **kwargs):
invoice = kwargs.get("object")
if invoice.get_itemtxs_data():
data = get_financial_values(invoice)
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"]
# data = get_financial_values(invoice)
calculator = CarFinanceCalculator(invoice)
finance_data = calculator.get_finance_data()
kwargs["data"] = 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"]
return super().get_context_data(**kwargs)
@ -3433,7 +3425,8 @@ class SubscriptionPlans(ListView):
class OrderListView(ListView):
model = models.SaleOrder
template_name = "sales/orders/order_list.html"
context_object_name = "orders"
context_object_name = "orders"
# email
def send_email_view(request, 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.views.mixins import (DjangoLedgerSecurityMixIn)
# 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_ledger.io.io_core import get_localdate
@ -3548,3 +3541,34 @@ class DateBalanceSheetView(FiscalYearBalanceSheetViewBase, DateReportMixIn):
"""
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.
"""

View File

@ -1,252 +1,252 @@
aiohappyeyeballs==2.4.4
aiohttp==3.11.11
aiohttp-retry==2.9.1
aiosignal==1.3.2
alabaster==1.0.0
albucore==0.0.23
albumentations==2.0.1
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==2022.9.22
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-next-url-mixin==0.4.0
django-nine==0.2.7
django-nonefield==0.4
django-ordered-model==3.7.4
django-phonenumber-field==8.0.0
django-picklefield==3.2
django-plans==1.2.0
django-prometheus==2.3.1
django-q2==1.7.6
django-sekizai==4.1.0
django-sequences==3.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
emoji==2.14.1
et_xmlfile==2.0.0
Faker==35.0.0
filelock==3.17.0
fire==0.7.0
Flask==3.1.0
fonttools==4.55.6
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.1.0
hstspreload==2025.1.1
httpcore==1.0.7
httpx==0.28.1
hyperframe==6.1.0
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.26.0
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
numpy==2.2.2
oauthlib==3.2.2
ofxtools==0.9.5
openai==1.60.0
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.42
pillow==10.4.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.2
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
python-stdnum==1.20
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==1.6.1
scipy==1.15.1
selenium==4.28.1
sentencepiece==0.2.0
shapely==2.0.6
simsimd==6.2.1
six==1.17.0
sniffio==1.3.1
snowballstemmer==2.2.0
sortedcontainers==2.4.0
soupsieve==2.6
SQLAlchemy==2.0.37
sqlparse==0.5.3
stanza==1.10.1
stringzilla==3.11.3
suds==1.2.0
swapper==1.3.0
sympy==1.13.1
tablib==3.8.0
termcolor==2.5.0
threadpoolctl==3.5.0
tifffile==2025.1.10
tinycss2==1.4.0
tinyhtml5==2.0.0
tomli==2.2.1
tomlkit==0.13.2
torch==2.5.1
tqdm==4.67.1
trio==0.28.0
trio-websocket==0.11.1
twilio==9.4.3
typing-inspect==0.9.0
typing_extensions==4.12.2
tzdata==2025.1
Unidecode==1.3.8
upgrade-requirements==1.7.0
urllib3==2.3.0
vin==0.6.2
vininfo==1.8.0
vishap==0.1.5
vpic-api==0.7.4
weasyprint==63.1
webencodings==0.5.1
websocket-client==1.8.0
Werkzeug==3.1.3
wikipedia==1.4.0
wsproto==1.2.0
xmlsec==1.3.14
yarl==1.18.3
zopfli==0.2.3.post1
aiohappyeyeballs
aiohttp
aiohttp-retry
aiosignal
alabaster
albucore
albumentations
annotated-types
anyio
arabic-reshaper
asgiref
astor
astroid
attrs
autopep8
Babel
beautifulsoup4
bleach
blinker
Brotli
certifi
cffi
chardet
charset-normalizer
click
colorama
commonmark
contourpy
crispy-bootstrap5
cryptography
cssselect2
ctranslate2
cycler
Cython
decorator
desert
dill
distro
dj-rest-auth
dj-shop-cart
Django
django-allauth
django-appointment
django-autoslug
django-bootstrap5
django-classy-tags
django-cors-headers
django-countries
django-crispy-forms
django-debug-toolbar
django-extensions
django-filter
django-formtools
django-ledger
django-money
django-next-url-mixin
django-nine
django-nonefield
django-ordered-model
django-phonenumber-field
django-picklefield
django-plans
django-prometheus
django-q2
django-sekizai
django-sequences
django-silk
django-sms
django-sslserver
django-tables2
django-treebeard
django-view-breadcrumbs
djangocms-admin-style
djangorestframework
djangorestframework_simplejwt
djangoviz
docutils
easy-thumbnails
emoji
et_xmlfile
Faker
filelock
fire
Flask
fonttools
frozenlist
fsspec
gprof2dot
graphqlclient
greenlet
h11
h2
hpack
hstspreload
httpcore
httpx
hyperframe
idna
imageio
imagesize
imgaug
iso4217
isodate
isort
itsdangerous
Jinja2
jiter
joblib
kiwisolver
lazy_loader
ledger
libretranslatepy
lmdb
lxml
Markdown
markdown-it-py
MarkupSafe
marshmallow
matplotlib
mccabe
mdurl
MouseInfo
mpmath
multidict
mypy-extensions
networkx
newrelic
nltk
numpy
oauthlib
ofxtools
openai
opencv-contrib-python
opencv-python
opencv-python-headless
openpyxl
opt_einsum
outcome
packaging
pandas
pango
pdfkit
phonenumbers
pillow
platformdirs
prometheus_client
propcache
protobuf
psycopg
psycopg-binary
psycopg-c
py-moneyed
PyAutoGUI
pyclipper
pycodestyle
pycparser
pydantic
pydantic_core
pydotplus
pydyf
PyGetWindow
Pygments
PyJWT
pylint
PyMsgBox
PyMySQL
pyobjc-core
pyobjc-framework-Cocoa
pyobjc-framework-Quartz
pyparsing
pyperclip
pyphen
pypng
PyRect
PyScreeze
pyserial
PySocks
python-bidi
python-dateutil
python-docx
python-openid
python-stdnum
python3-saml
pytweening
pytz
pyvin
pywa
pywhat
pywhatkit
PyYAML
pyzbar
qrcode
RapidFuzz
regex
reportlab
requests
requests-oauthlib
rfc3986
rich
rubicon-objc
sacremoses
scikit-image
scikit-learn
scipy
selenium
sentencepiece
shapely
simsimd
six
sniffio
snowballstemmer
sortedcontainers
soupsieve
SQLAlchemy
sqlparse
stanza
stringzilla
suds
swapper
sympy
tablib
termcolor
threadpoolctl
tifffile
tinycss2
tinyhtml5
tomli
tomlkit
torch
tqdm
trio
trio-websocket
twilio
typing-inspect
typing_extensions
tzdata
Unidecode
upgrade-requirements
urllib3
vin
vininfo
vishap
vpic-api
weasyprint
webencodings
websocket-client
Werkzeug
wikipedia
wsproto
xmlsec
yarl
zopfli

View File

@ -35,11 +35,11 @@ def run():
invoice_itemtxs = {
i.get("item_number"): {
"unit_cost": i.get("total"),
"unit_cost": i.get("total_price"),
"quantity": i.get("quantity"),
"total_amount": i.get("total_vat"),
}
for i in finance_data.get("cars")
}
print(invoice_itemtxs)
print(finance_data)

View File

@ -235,6 +235,29 @@
<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>
</div>
</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 %}
<a class="nav-link" href="{% url 'entity-bs' request.user.dealer.entity.slug %}">
@ -242,7 +265,7 @@
<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 '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>
</a>
</li>

View File

@ -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 %}

View File

@ -45,9 +45,12 @@
{% 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>
{% 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>
{% 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>
{% endif %}
{% 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>
{% endif %}
@ -137,15 +140,15 @@
</tr>
{% endfor %}
<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">
<span id="grand-total">- {{data.total_discount}}</span>
<span id="grand-total">+ {{data.total_vat_amount}}</span>
</td>
</tr>
<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 text-start fw-semibold">
<span id="grand-total"></span>
<td class="align-middle ps-4 fw-semibold text-body-highlight" colspan="4">{% trans "Discount Amount" %}</td>
<td class="align-middle text-start text-danger fw-semibold ">
<span id="grand-total">- {{data.total_discount}}</span>
</td>
</tr>
<tr class="bg-body-secondary total-sum">

View File

@ -84,6 +84,20 @@
<p class="ps-6 ps-sm-0 fw-semibold mb-0">{{ estimate.customer.address_1 }}</p>
</td>
</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>
<td class="py-2">
<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>
</td>
</tr>
</table>
</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="last_activity align-middle text-center py-2">
<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>
</td>
</tr>

View File

@ -237,7 +237,7 @@
<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 text-start fw-semibold">
<span id="grand-total">+ {{vat_amount}}</span>
<span id="grand-total">+ {{data.total_vat_amount}}</span>
</td>
</tr>
<tr class="bg-body-secondary total-sum">

View File

@ -208,11 +208,11 @@
</tr>
</thead>
<tbody>
{% for item in car_and_item_info %}
{% for item in data.cars %}
<tr>
<td class="">{{item.info.make}}</td>
<td class="">{{item.make}}</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>
</tr>
{% endfor %}
@ -222,10 +222,10 @@
<!-- Additional Charges (VAT and Services) -->
<div class="additional-charges">
<p><strong>VAT/ضريبة القيمة المضافة ({{vat}}%):</strong> <span class="highlight">{{vat_amount}}&nbsp;{{ _("SAR") }}</span></p>
<p><strong>VAT/ضريبة القيمة المضافة ({{vat}}%):</strong> <span class="highlight">{{data.vat}}&nbsp;{{ _("SAR") }}</span></p>
<p><strong>Additional Services/ الخدمات الإضافية</strong>
<br>
{% for service in additional_services %}
{% for service in data.additional_services %}
<span class="highlight">{{service.name}} - {{service.price}}&nbsp;{{ _("SAR") }}</span><br>
{% endfor %}
</p>
@ -233,7 +233,7 @@
<!-- Total -->
<div class="invoice-total">
<p><strong>Total/الإجمالي</strong> <span class="highlight">{{total}}&nbsp;{{ _("SAR") }}</span></p>
<p><strong>Total/الإجمالي</strong> <span class="highlight">{{data.grand_total}}&nbsp;{{ _("SAR") }}</span></p>
</div>
<!-- Footer Note -->

View File

@ -21,8 +21,11 @@
<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.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">
{% comment %} <a href="{% url 'estimate_detail' estimate.pk %}"
class="btn btn-sm btn-phoenix-success">