update
This commit is contained in:
parent
3e2af239e4
commit
9b282154b0
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,7 +1,9 @@
|
||||
from appointment.models import Appointment
|
||||
from django.contrib import admin
|
||||
from . import models
|
||||
from django_ledger import models as ledger_models
|
||||
from django_pdf_actions.actions import export_to_pdf_landscape, export_to_pdf_portrait
|
||||
from appointment import models as appointment_models
|
||||
|
||||
|
||||
admin.site.register(models.Dealer)
|
||||
@ -32,12 +34,15 @@ admin.site.register(models.AdditionalServices)
|
||||
admin.site.register(models.Payment)
|
||||
admin.site.register(models.VatRate)
|
||||
admin.site.register(ledger_models.CustomerModel)
|
||||
admin.site.register(ledger_models.VendorModel)
|
||||
admin.site.register(ledger_models.ItemModel)
|
||||
admin.site.register(models.Opportunity)
|
||||
admin.site.register(models.Notification)
|
||||
admin.site.register(models.Lead)
|
||||
admin.site.register(models.Activity)
|
||||
admin.site.register(models.Schedule)
|
||||
admin.site.register(models.Notes)
|
||||
# admin.site.register(appointment_models.Client)
|
||||
|
||||
|
||||
@admin.register(models.Car)
|
||||
@ -126,4 +131,5 @@ class CarOptionAdmin(admin.ModelAdmin):
|
||||
@admin.register(ledger_models.ItemTransactionModel)
|
||||
class ItemTransactionModelAdmin(admin.ModelAdmin):
|
||||
|
||||
actions = [export_to_pdf_landscape, export_to_pdf_portrait]
|
||||
actions = [export_to_pdf_landscape, export_to_pdf_portrait]
|
||||
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
# Generated by Django 5.1.5 on 2025-02-17 14:05
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contenttypes', '0002_remove_content_type_name'),
|
||||
('inventory', '0030_alter_activity_activity_type_delete_carhistory'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='activity',
|
||||
name='dealer',
|
||||
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='inventory.dealer'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='content_type',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='contenttypes.contenttype'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='created_by',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='activities_created_by', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
19
inventory/migrations/0032_alter_carcolors_car.py
Normal file
19
inventory/migrations/0032_alter_carcolors_car.py
Normal file
@ -0,0 +1,19 @@
|
||||
# Generated by Django 5.1.6 on 2025-02-17 17:40
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0031_activity_dealer_alter_activity_content_type_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='carcolors',
|
||||
name='car',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='colors', to='inventory.car'),
|
||||
),
|
||||
]
|
||||
@ -644,7 +644,7 @@ class InteriorColors(models.Model, LocalizedNameMixin):
|
||||
|
||||
|
||||
class CarColors(models.Model):
|
||||
car = models.ForeignKey("Car", on_delete=models.CASCADE, related_name="colors")
|
||||
car = models.OneToOneField("Car", on_delete=models.CASCADE, related_name="colors")
|
||||
exterior = models.ForeignKey(
|
||||
"ExteriorColors", on_delete=models.CASCADE, related_name="colors"
|
||||
)
|
||||
@ -1386,7 +1386,8 @@ class Email(models.Model):
|
||||
|
||||
|
||||
class Activity(models.Model):
|
||||
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
|
||||
dealer = models.ForeignKey(Dealer, on_delete=models.CASCADE, related_name="activities")
|
||||
content_type = models.ForeignKey(ContentType, on_delete=models.DO_NOTHING)
|
||||
object_id = models.PositiveIntegerField()
|
||||
content_object = GenericForeignKey("content_type", "object_id")
|
||||
activity_type = models.CharField(
|
||||
@ -1394,7 +1395,7 @@ class Activity(models.Model):
|
||||
)
|
||||
notes = models.TextField(blank=True, null=True, verbose_name=_("Notes"))
|
||||
created_by = models.ForeignKey(
|
||||
User, on_delete=models.DO_NOTHING, related_name="activities_created"
|
||||
User, on_delete=models.DO_NOTHING, related_name="activities_created_by"
|
||||
)
|
||||
created = models.DateTimeField(auto_now_add=True, verbose_name=_("Created"))
|
||||
updated = models.DateTimeField(auto_now=True, verbose_name=_("Updated"))
|
||||
|
||||
@ -5,7 +5,7 @@ from . import models
|
||||
from django_tables2.utils import A
|
||||
import django_tables2 as tables
|
||||
from django import forms
|
||||
from inventory.models import Car, SaleQuotation, SaleQuotationCar
|
||||
|
||||
|
||||
|
||||
class ImageColumn(tables.Column):
|
||||
@ -19,3 +19,88 @@ class CustomerTable(tables.Table):
|
||||
first_name = tables.Column()
|
||||
|
||||
|
||||
import django_tables2 as tables
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from .models import Car, CarFinance, ExteriorColors, InteriorColors, CarColors
|
||||
|
||||
class CarTable(tables.Table):
|
||||
# Car fields
|
||||
vin = tables.Column(verbose_name=_("VIN"))
|
||||
dealer = tables.Column(verbose_name=_("Dealer"))
|
||||
vendor = tables.Column(verbose_name=_("Vendor"))
|
||||
id_car_make = tables.Column(verbose_name=_("Make"))
|
||||
id_car_model = tables.Column(verbose_name=_("Model"))
|
||||
year = tables.Column(verbose_name=_("Year"))
|
||||
id_car_serie = tables.Column(verbose_name=_("Series"))
|
||||
id_car_trim = tables.Column(verbose_name=_("Trim"))
|
||||
status = tables.Column(verbose_name=_("Status"))
|
||||
stock_type = tables.Column(verbose_name=_("Stock Type"))
|
||||
remarks = tables.Column(verbose_name=_("Remarks"))
|
||||
mileage = tables.Column(verbose_name=_("Mileage"))
|
||||
receiving_date = tables.Column(verbose_name=_("Receiving Date"))
|
||||
hash = tables.Column(verbose_name=_("Hash"))
|
||||
|
||||
# CarFinance fields
|
||||
cost_price = tables.Column(accessor="finances.cost_price", verbose_name=_("Cost Price"))
|
||||
selling_price = tables.Column(accessor="finances.selling_price", verbose_name=_("Selling Price"))
|
||||
discount_amount = tables.Column(accessor="finances.discount_amount", verbose_name=_("Discount Amount"))
|
||||
|
||||
# ExteriorColors fields (accessed through CarColors)
|
||||
exterior_color = tables.Column(accessor="colors.exterior.name", verbose_name=_("Exterior Color"))
|
||||
exterior_color_rgb = tables.Column(accessor="colors.exterior.rgb", verbose_name=_("Exterior Color RGB"))
|
||||
|
||||
# InteriorColors fields (accessed through CarColors)
|
||||
interior_color = tables.Column(accessor="colors.interior.name", verbose_name=_("Interior Color"))
|
||||
interior_color_rgb = tables.Column(accessor="colors.interior.rgb", verbose_name=_("Interior Color RGB"))
|
||||
|
||||
class Meta:
|
||||
model = Car
|
||||
template_name = "django_tables2/bootstrap.html"
|
||||
fields = (
|
||||
"vin",
|
||||
"dealer",
|
||||
"vendor",
|
||||
"id_car_make",
|
||||
"id_car_model",
|
||||
"year",
|
||||
"id_car_serie",
|
||||
"id_car_trim",
|
||||
"status",
|
||||
"stock_type",
|
||||
"remarks",
|
||||
"mileage",
|
||||
"receiving_date",
|
||||
"hash",
|
||||
"cost_price",
|
||||
"selling_price",
|
||||
"discount_amount",
|
||||
"exterior_color",
|
||||
"exterior_color_rgb",
|
||||
"interior_color",
|
||||
"interior_color_rgb",
|
||||
)
|
||||
attrs = {"class": "table table-striped table-bordered"}
|
||||
|
||||
def render_dealer(self, value):
|
||||
return str(value)
|
||||
|
||||
def render_vendor(self, value):
|
||||
return str(value)
|
||||
|
||||
def render_id_car_make(self, value):
|
||||
return str(value)
|
||||
|
||||
def render_id_car_model(self, value):
|
||||
return str(value)
|
||||
|
||||
def render_id_car_serie(self, value):
|
||||
return str(value)
|
||||
|
||||
def render_id_car_trim(self, value):
|
||||
return str(value)
|
||||
|
||||
def render_exterior_color(self, value):
|
||||
return str(value)
|
||||
|
||||
def render_interior_color(self, value):
|
||||
return str(value)
|
||||
@ -1,6 +1,7 @@
|
||||
from django.urls import path
|
||||
from . import views
|
||||
from allauth.account import views as allauth_views
|
||||
from django_tables2.export.views import TableExport
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
@ -45,6 +46,8 @@ urlpatterns = [
|
||||
"dashboards/accounting/", views.AccountingDashboard.as_view(), name="accounting"
|
||||
),
|
||||
path("test/", views.TestView.as_view(), name="test"),
|
||||
path('cars/inventory/table/', views.car_list, name="car_table"),
|
||||
path('export/<str:format>/', TableExport, name='export'),
|
||||
# Dealer URLs
|
||||
path("dealers/<int:pk>/", views.DealerDetailView.as_view(), name="dealer_detail"),
|
||||
path(
|
||||
|
||||
@ -3,7 +3,7 @@ from appointment.models import Appointment,AppointmentRequest,Service,StaffMembe
|
||||
from datetime import timedelta
|
||||
from calendar import month_name
|
||||
from random import randint
|
||||
|
||||
from django_tables2 import RequestConfig
|
||||
from django_pdf_actions.actions import export_to_pdf_landscape
|
||||
from reportlab.lib.pagesizes import landscape, A4
|
||||
from rich import print
|
||||
@ -90,7 +90,7 @@ from .services import (
|
||||
get_make,
|
||||
get_model,
|
||||
)
|
||||
from . import models, forms
|
||||
from . import models, forms, tables
|
||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
from django.contrib.auth.models import Group
|
||||
@ -145,6 +145,7 @@ from django_ledger.views.mixins import (
|
||||
from django_pdf_actions import actions
|
||||
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
@ -4386,3 +4387,11 @@ def apply_search_filters(queryset, query):
|
||||
return queryset.filter(search_filters).distinct()
|
||||
|
||||
|
||||
def car_list(request):
|
||||
dealer = get_user_type(request)
|
||||
queryset = models.Car.objects.select_related(
|
||||
"finances", "colors__exterior", "colors__interior"
|
||||
).filter(dealer=dealer)
|
||||
table = tables.CarTable(queryset)
|
||||
RequestConfig(request).configure(table)
|
||||
return render(request, 'inventory/car_list_table.html', {'table': table})
|
||||
@ -1,24 +1,24 @@
|
||||
aiohappyeyeballs==2.4.4
|
||||
aiohttp==3.11.11
|
||||
aiohappyeyeballs==2.4.6
|
||||
aiohttp==3.11.12
|
||||
aiohttp-retry==2.9.1
|
||||
aiosignal==1.3.2
|
||||
alabaster==1.0.0
|
||||
albucore==0.0.23
|
||||
albumentations==2.0.2
|
||||
albumentations==2.0.4
|
||||
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
|
||||
attrs==25.1.0
|
||||
autopep8==2.3.2
|
||||
Babel==2.15.0
|
||||
beautifulsoup4==4.12.3
|
||||
beautifulsoup4==4.13.3
|
||||
bleach==6.2.0
|
||||
blinker==1.9.0
|
||||
Brotli==1.1.0
|
||||
certifi==2024.12.14
|
||||
certifi==2025.1.31
|
||||
cffi==1.17.1
|
||||
chardet==5.2.0
|
||||
charset-normalizer==3.4.1
|
||||
@ -27,7 +27,7 @@ colorama==0.4.6
|
||||
commonmark==0.9.1
|
||||
contourpy==1.3.1
|
||||
crispy-bootstrap5==2024.10
|
||||
cryptography==44.0.0
|
||||
cryptography==44.0.1
|
||||
cssselect2==0.7.0
|
||||
ctranslate2==4.5.0
|
||||
cycler==0.12.1
|
||||
@ -39,18 +39,18 @@ dill==0.3.9
|
||||
distro==1.9.0
|
||||
dj-rest-auth==7.0.1
|
||||
dj-shop-cart==8.0.0a2
|
||||
Django==5.1.5
|
||||
django-allauth==65.3.1
|
||||
Django==5.1.6
|
||||
django-allauth==65.4.1
|
||||
django-appointment==3.8.0
|
||||
django-autoslug==1.9.9
|
||||
django-bootstrap5==24.3
|
||||
django-classy-tags==4.1.0
|
||||
django-cors-headers==4.6.0
|
||||
django-cors-headers==4.7.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-filter==25.1
|
||||
django-formtools==2.5.1
|
||||
django-ledger==0.7.4.1
|
||||
django-model-utils==5.0.0
|
||||
@ -59,7 +59,7 @@ django-next-url-mixin==0.4.0
|
||||
django-nine==0.2.7
|
||||
django-nonefield==0.4
|
||||
django-ordered-model==3.7.4
|
||||
django-pdf-actions==0.1.38
|
||||
django-pdf-actions==0.1.39
|
||||
django-phonenumber-field==8.0.0
|
||||
django-picklefield==3.2
|
||||
django-plans==1.2.0
|
||||
@ -82,19 +82,19 @@ docutils==0.21.2
|
||||
easy-thumbnails==2.10
|
||||
emoji==2.14.1
|
||||
et_xmlfile==2.0.0
|
||||
Faker==35.0.0
|
||||
Faker==36.1.1
|
||||
filelock==3.17.0
|
||||
fire==0.7.0
|
||||
Flask==3.1.0
|
||||
fonttools==4.55.7
|
||||
fonttools==4.56.0
|
||||
fpdf2==2.8.2
|
||||
frozenlist==1.5.0
|
||||
fsspec==2024.12.0
|
||||
fsspec==2025.2.0
|
||||
gprof2dot==2024.6.6
|
||||
graphqlclient==0.2.4
|
||||
greenlet==3.1.1
|
||||
h11==0.14.0
|
||||
h2==4.1.0
|
||||
h2==4.2.0
|
||||
hpack==4.1.0
|
||||
hstspreload==2025.1.1
|
||||
httpcore==1.0.7
|
||||
@ -117,11 +117,11 @@ lazy_loader==0.4
|
||||
ledger==1.0.1
|
||||
libretranslatepy==2.1.4
|
||||
lmdb==1.6.2
|
||||
lxml==5.3.0
|
||||
lxml==5.3.1
|
||||
Markdown==3.7
|
||||
markdown-it-py==3.0.0
|
||||
MarkupSafe==3.0.2
|
||||
marshmallow==3.26.0
|
||||
marshmallow==3.26.1
|
||||
matplotlib==3.10.0
|
||||
mccabe==0.7.0
|
||||
mdurl==0.1.2
|
||||
@ -130,13 +130,13 @@ mpmath==1.3.0
|
||||
multidict==6.1.0
|
||||
mypy-extensions==1.0.0
|
||||
networkx==3.4.2
|
||||
newrelic==10.4.0
|
||||
newrelic==10.6.0
|
||||
nltk==3.9.1
|
||||
num2words==0.5.14
|
||||
numpy==2.2.2
|
||||
libquadmath==2.2.3
|
||||
oauthlib==3.2.2
|
||||
ofxtools==0.9.5
|
||||
openai==1.60.2
|
||||
openai==1.63.1
|
||||
opencv-contrib-python==4.11.0.86
|
||||
opencv-python==4.11.0.86
|
||||
opencv-python-headless==4.11.0.86
|
||||
@ -147,8 +147,8 @@ packaging==24.2
|
||||
pandas==2.2.3
|
||||
pango==0.0.1
|
||||
pdfkit==1.0.0
|
||||
phonenumbers==8.13.42
|
||||
pillow==10.4.0
|
||||
phonenumbers==8.13.55
|
||||
pillow==11.1.0
|
||||
platformdirs==4.3.6
|
||||
prometheus_client==0.21.1
|
||||
propcache==0.2.1
|
||||
@ -162,7 +162,7 @@ pyclipper==1.3.0.post6
|
||||
pycodestyle==2.12.1
|
||||
pycparser==2.22
|
||||
pydantic==2.10.6
|
||||
pydantic_core==2.27.2
|
||||
pydantic_core==2.29.0
|
||||
pydotplus==2.0.2
|
||||
pydyf==0.11.0
|
||||
PyGetWindow==0.0.9
|
||||
@ -190,41 +190,41 @@ python-openid==2.2.5
|
||||
python-stdnum==1.20
|
||||
python3-saml==1.16.0
|
||||
pytweening==1.2.0
|
||||
pytz==2024.2
|
||||
pytz==2025.1
|
||||
pyvin==0.0.2
|
||||
pywa==2.7.0
|
||||
pywhat==5.1.0
|
||||
pywhatkit==5.4
|
||||
PyYAML==6.0.2
|
||||
pyzbar==0.1.9
|
||||
qrcode==7.4.2
|
||||
RapidFuzz==3.11.0
|
||||
qrcode==8.0
|
||||
RapidFuzz==3.12.1
|
||||
regex==2024.11.6
|
||||
reportlab==4.2.5
|
||||
reportlab==4.3.1
|
||||
requests==2.32.3
|
||||
requests-oauthlib==2.0.0
|
||||
rfc3986==2.0.0
|
||||
rich==10.16.2
|
||||
rich==13.9.4
|
||||
rubicon-objc==0.5.0
|
||||
sacremoses==0.1.1
|
||||
scikit-image==0.25.1
|
||||
scikit-learn==1.6.1
|
||||
scipy==1.15.1
|
||||
libomp runtime library==1.6.1
|
||||
libquadmath==1.15.2
|
||||
selenium==4.28.1
|
||||
sentencepiece==0.2.0
|
||||
shapely==2.0.6
|
||||
shapely==2.0.7
|
||||
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
|
||||
SQLAlchemy==2.0.38
|
||||
sqlparse==0.5.3
|
||||
stanza==1.10.1
|
||||
stringzilla==3.11.3
|
||||
suds==1.2.0
|
||||
swapper==1.3.0
|
||||
swapper==1.4.0
|
||||
sympy==1.13.1
|
||||
tablib==3.8.0
|
||||
termcolor==2.5.0
|
||||
@ -234,11 +234,11 @@ tinycss2==1.4.0
|
||||
tinyhtml5==2.0.0
|
||||
tomli==2.2.1
|
||||
tomlkit==0.13.2
|
||||
torch==2.5.1
|
||||
torch==2.6.0
|
||||
tqdm==4.67.1
|
||||
trio==0.28.0
|
||||
trio-websocket==0.11.1
|
||||
twilio==9.4.4
|
||||
trio==0.29.0
|
||||
trio-websocket==0.12.0
|
||||
twilio==9.4.5
|
||||
typing-inspect==0.9.0
|
||||
typing_extensions==4.12.2
|
||||
tzdata==2025.1
|
||||
@ -249,7 +249,7 @@ vin==0.6.2
|
||||
vininfo==1.8.0
|
||||
vishap==0.1.5
|
||||
vpic-api==0.7.4
|
||||
weasyprint==63.1
|
||||
weasyprint==64.0
|
||||
webencodings==0.5.1
|
||||
websocket-client==1.8.0
|
||||
Werkzeug==3.1.3
|
||||
|
||||
15
templates/inventory/car_list_table.html
Normal file
15
templates/inventory/car_list_table.html
Normal file
@ -0,0 +1,15 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static i18n django_tables2%}
|
||||
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% load export_url from django_tables2 %}
|
||||
|
||||
<!-- Render the table -->
|
||||
{% render_table table %}
|
||||
|
||||
<!-- Add export buttons -->
|
||||
<a href="{% export_url 'xlsx' %}" class="btn btn-primary">Export to Excel</a>
|
||||
<a href="{% export_url 'pdf' %}" class="btn btn-primary">Export to PDF</a>
|
||||
{% endblock %}
|
||||
@ -115,8 +115,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="email align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent">{{ org.additional_info.organization_info.crn }}</td>
|
||||
<td class="phone align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent">{{ org.additional_info.organization_info.vrn }}</td>
|
||||
<td class="email align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent">{{ org.additional_info.info.crn }}</td>
|
||||
<td class="phone align-middle white-space-nowrap fw-semibold ps-4 border-end border-translucent">{{ org.additional_info.info.vrn }}</td>
|
||||
<td class="phone align-middle white-space-nowrap ps-4 border-end border-translucent fw-semibold text-body-highlight"><a class="text-body-highlight" href="tel:{{ org.phone }}">{{ org.phone }}</a></td>
|
||||
<td class="company align-middle white-space-nowrap text-body-tertiary text-opacity-85 ps-4 border-end border-translucent fw-semibold text-body-highlight">
|
||||
{{ org.address_1 }}</td>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user