3060 lines
111 KiB
Python
3060 lines
111 KiB
Python
# Generated by Django 5.2.1 on 2025-06-18 15:44
|
|
|
|
import datetime
|
|
import django.core.validators
|
|
import django.db.models.deletion
|
|
import django.utils.timezone
|
|
import inventory.mixins
|
|
import inventory.models
|
|
import phonenumber_field.modelfields
|
|
import uuid
|
|
from decimal import Decimal
|
|
from django.conf import settings
|
|
from django.db import migrations, models
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
initial = True
|
|
|
|
dependencies = [
|
|
("appointment", "0001_initial"),
|
|
("auth", "0012_alter_user_first_name_max_length"),
|
|
("contenttypes", "0002_remove_content_type_name"),
|
|
("django_ledger", "0022_alter_billmodel_bill_items_and_more"),
|
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
]
|
|
|
|
operations = [
|
|
migrations.CreateModel(
|
|
name="CarEquipment",
|
|
fields=[
|
|
(
|
|
"id_car_equipment",
|
|
models.AutoField(primary_key=True, serialize=False),
|
|
),
|
|
("name", models.CharField(blank=True, max_length=255, null=True)),
|
|
(
|
|
"arabic_name",
|
|
models.CharField(blank=True, max_length=255, null=True),
|
|
),
|
|
("year_begin", models.IntegerField(blank=True, null=True)),
|
|
(
|
|
"slug",
|
|
models.SlugField(
|
|
blank=True, max_length=255, null=True, unique=True
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Equipment",
|
|
},
|
|
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
|
|
),
|
|
migrations.CreateModel(
|
|
name="CarMake",
|
|
fields=[
|
|
("id_car_make", models.AutoField(primary_key=True, serialize=False)),
|
|
("name", models.CharField(blank=True, max_length=255, null=True)),
|
|
(
|
|
"slug",
|
|
models.SlugField(
|
|
blank=True, max_length=255, null=True, unique=True
|
|
),
|
|
),
|
|
(
|
|
"arabic_name",
|
|
models.CharField(blank=True, max_length=255, null=True),
|
|
),
|
|
(
|
|
"logo",
|
|
models.ImageField(
|
|
blank=True, null=True, upload_to="car_make", verbose_name="logo"
|
|
),
|
|
),
|
|
("is_sa_import", models.BooleanField(default=False)),
|
|
(
|
|
"car_type",
|
|
models.SmallIntegerField(
|
|
blank=True,
|
|
choices=[
|
|
(1, "Car"),
|
|
(2, "Light Commercial"),
|
|
(3, "Heavy-Duty Tractors"),
|
|
(4, "Trailers"),
|
|
(5, "Medium Trucks"),
|
|
(6, "Buses"),
|
|
(20, "Motorcycles"),
|
|
(21, "Buggy"),
|
|
(22, "Moto ATV"),
|
|
(23, "Scooters"),
|
|
(24, "Karting"),
|
|
(25, "ATV"),
|
|
(26, "Snowmobiles"),
|
|
],
|
|
null=True,
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Make",
|
|
},
|
|
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
|
|
),
|
|
migrations.CreateModel(
|
|
name="ExteriorColors",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("name", models.CharField(max_length=255, verbose_name="Name")),
|
|
(
|
|
"arabic_name",
|
|
models.CharField(max_length=255, verbose_name="Arabic Name"),
|
|
),
|
|
(
|
|
"rgb",
|
|
models.CharField(
|
|
blank=True, max_length=24, null=True, verbose_name="RGB"
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Exterior Colors",
|
|
"verbose_name_plural": "Exterior Colors",
|
|
},
|
|
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
|
|
),
|
|
migrations.CreateModel(
|
|
name="InteriorColors",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("name", models.CharField(max_length=255, verbose_name="Name")),
|
|
(
|
|
"arabic_name",
|
|
models.CharField(max_length=255, verbose_name="Arabic Name"),
|
|
),
|
|
(
|
|
"rgb",
|
|
models.CharField(
|
|
blank=True, max_length=24, null=True, verbose_name="RGB"
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Interior Colors",
|
|
"verbose_name_plural": "Interior Colors",
|
|
},
|
|
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
|
|
),
|
|
migrations.CreateModel(
|
|
name="Payment",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"amount",
|
|
models.DecimalField(
|
|
decimal_places=2, max_digits=10, verbose_name="amount"
|
|
),
|
|
),
|
|
(
|
|
"payment_method",
|
|
models.CharField(
|
|
choices=[
|
|
("cash", "cash"),
|
|
("credit", "credit"),
|
|
("transfer", "transfer"),
|
|
("debit", "debit"),
|
|
("sadad", "SADAD"),
|
|
],
|
|
max_length=50,
|
|
verbose_name="method",
|
|
),
|
|
),
|
|
(
|
|
"reference_number",
|
|
models.CharField(
|
|
blank=True,
|
|
max_length=100,
|
|
null=True,
|
|
verbose_name="reference number",
|
|
),
|
|
),
|
|
(
|
|
"payment_date",
|
|
models.DateField(auto_now_add=True, verbose_name="date"),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "payment",
|
|
"verbose_name_plural": "payments",
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="VatRate",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"rate",
|
|
models.DecimalField(
|
|
decimal_places=2, default=Decimal("0.15"), max_digits=5
|
|
),
|
|
),
|
|
("is_active", models.BooleanField(default=True)),
|
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
],
|
|
),
|
|
migrations.CreateModel(
|
|
name="AdditionalServices",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("name", models.CharField(max_length=255, verbose_name="Name")),
|
|
(
|
|
"arabic_name",
|
|
models.CharField(max_length=255, verbose_name="Arabic Name"),
|
|
),
|
|
("description", models.TextField(verbose_name="Description")),
|
|
(
|
|
"price",
|
|
models.DecimalField(
|
|
decimal_places=2, max_digits=14, verbose_name="Price"
|
|
),
|
|
),
|
|
("taxable", models.BooleanField(default=False, verbose_name="taxable")),
|
|
(
|
|
"uom",
|
|
models.CharField(
|
|
choices=[
|
|
("EA", "Each"),
|
|
("PR", "Pair"),
|
|
("SET", "Set"),
|
|
("GAL", "Gallon"),
|
|
("L", "Liter"),
|
|
("M", "Meter"),
|
|
("KG", "Kilogram"),
|
|
("HR", "Hour"),
|
|
("BX", "Box"),
|
|
("RL", "Roll"),
|
|
("PKG", "Package"),
|
|
("DZ", "Dozen"),
|
|
("SQ_M", "Square Meter"),
|
|
("PC", "Piece"),
|
|
("BDL", "Bundle"),
|
|
],
|
|
max_length=10,
|
|
verbose_name="Unit of Measurement",
|
|
),
|
|
),
|
|
(
|
|
"item",
|
|
models.OneToOneField(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
to="django_ledger.itemmodel",
|
|
verbose_name="Item",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Additional Services",
|
|
"verbose_name_plural": "Additional Services",
|
|
},
|
|
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
|
|
),
|
|
migrations.CreateModel(
|
|
name="Car",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.UUIDField(
|
|
default=uuid.uuid4,
|
|
editable=False,
|
|
primary_key=True,
|
|
serialize=False,
|
|
unique=True,
|
|
verbose_name="Primary Key",
|
|
),
|
|
),
|
|
(
|
|
"slug",
|
|
models.SlugField(
|
|
blank=True,
|
|
help_text="Slug for the object. If not provided, it will be generated automatically.",
|
|
null=True,
|
|
unique=True,
|
|
verbose_name="Slug",
|
|
),
|
|
),
|
|
(
|
|
"created_at",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Created At"),
|
|
),
|
|
(
|
|
"updated_at",
|
|
models.DateTimeField(auto_now=True, verbose_name="Updated At"),
|
|
),
|
|
(
|
|
"vin",
|
|
models.CharField(max_length=17, unique=True, verbose_name="VIN"),
|
|
),
|
|
("year", models.IntegerField(verbose_name="Year")),
|
|
(
|
|
"status",
|
|
models.CharField(
|
|
choices=[
|
|
("available", "Available"),
|
|
("sold", "Sold"),
|
|
("hold", "Hold"),
|
|
("damaged", "Damaged"),
|
|
("reserved", "Reserved"),
|
|
("transfer", "Transfer"),
|
|
],
|
|
default="available",
|
|
max_length=10,
|
|
verbose_name="Status",
|
|
),
|
|
),
|
|
(
|
|
"stock_type",
|
|
models.CharField(
|
|
choices=[("new", "New"), ("used", "Used")],
|
|
default="new",
|
|
max_length=10,
|
|
verbose_name="Stock Type",
|
|
),
|
|
),
|
|
(
|
|
"remarks",
|
|
models.TextField(blank=True, null=True, verbose_name="Remarks"),
|
|
),
|
|
(
|
|
"mileage",
|
|
models.IntegerField(blank=True, null=True, verbose_name="Mileage"),
|
|
),
|
|
("receiving_date", models.DateTimeField(verbose_name="Receiving Date")),
|
|
(
|
|
"hash",
|
|
models.CharField(
|
|
blank=True, max_length=64, null=True, verbose_name="Hash"
|
|
),
|
|
),
|
|
(
|
|
"item_model",
|
|
models.OneToOneField(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="django_ledger.itemmodel",
|
|
verbose_name="Item Model",
|
|
),
|
|
),
|
|
(
|
|
"id_car_make",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
db_column="id_car_make",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.carmake",
|
|
verbose_name="Make",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Car",
|
|
"verbose_name_plural": "Cars",
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="CarFinance",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"cost_price",
|
|
models.DecimalField(
|
|
decimal_places=2, max_digits=14, verbose_name="Cost Price"
|
|
),
|
|
),
|
|
(
|
|
"selling_price",
|
|
models.DecimalField(
|
|
decimal_places=2, max_digits=14, verbose_name="Selling Price"
|
|
),
|
|
),
|
|
(
|
|
"discount_amount",
|
|
models.DecimalField(
|
|
decimal_places=2,
|
|
default=Decimal("0.00"),
|
|
max_digits=14,
|
|
verbose_name="Discount Amount",
|
|
),
|
|
),
|
|
("is_sold", models.BooleanField(default=False)),
|
|
(
|
|
"additional_services",
|
|
models.ManyToManyField(
|
|
blank=True,
|
|
related_name="additional_finances",
|
|
to="inventory.additionalservices",
|
|
),
|
|
),
|
|
(
|
|
"car",
|
|
models.OneToOneField(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="finances",
|
|
to="inventory.car",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Car Financial Details",
|
|
"verbose_name_plural": "Car Financial Details",
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="CarModel",
|
|
fields=[
|
|
("id_car_model", models.AutoField(primary_key=True, serialize=False)),
|
|
("name", models.CharField(blank=True, max_length=255, null=True)),
|
|
(
|
|
"arabic_name",
|
|
models.CharField(blank=True, max_length=255, null=True),
|
|
),
|
|
(
|
|
"slug",
|
|
models.SlugField(
|
|
blank=True, max_length=255, null=True, unique=True
|
|
),
|
|
),
|
|
(
|
|
"id_car_make",
|
|
models.ForeignKey(
|
|
db_column="id_car_make",
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.carmake",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Model",
|
|
},
|
|
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
|
|
),
|
|
migrations.AddField(
|
|
model_name="car",
|
|
name="id_car_model",
|
|
field=models.ForeignKey(
|
|
blank=True,
|
|
db_column="id_car_model",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.carmodel",
|
|
verbose_name="Model",
|
|
),
|
|
),
|
|
migrations.CreateModel(
|
|
name="CarOption",
|
|
fields=[
|
|
("id_car_option", models.AutoField(primary_key=True, serialize=False)),
|
|
("name", models.CharField(blank=True, max_length=255, null=True)),
|
|
(
|
|
"arabic_name",
|
|
models.CharField(blank=True, max_length=255, null=True),
|
|
),
|
|
(
|
|
"slug",
|
|
models.SlugField(
|
|
blank=True, max_length=255, null=True, unique=True
|
|
),
|
|
),
|
|
(
|
|
"id_parent",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
db_column="id_parent",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.caroption",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Option",
|
|
},
|
|
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
|
|
),
|
|
migrations.CreateModel(
|
|
name="CarOptionValue",
|
|
fields=[
|
|
(
|
|
"id_car_option_value",
|
|
models.AutoField(primary_key=True, serialize=False),
|
|
),
|
|
("value", models.CharField(max_length=500)),
|
|
("unit", models.CharField(blank=True, max_length=255, null=True)),
|
|
("is_base", models.IntegerField()),
|
|
(
|
|
"id_car_equipment",
|
|
models.ForeignKey(
|
|
db_column="id_car_equipment",
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.carequipment",
|
|
),
|
|
),
|
|
(
|
|
"id_car_option",
|
|
models.ForeignKey(
|
|
db_column="id_car_option",
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.caroption",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Option Value",
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="CarRegistration",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("plate_number", models.IntegerField(verbose_name="Plate Number")),
|
|
("text1", models.CharField(max_length=1, verbose_name="Text 1")),
|
|
(
|
|
"text2",
|
|
models.CharField(
|
|
blank=True, max_length=1, null=True, verbose_name="Text 2"
|
|
),
|
|
),
|
|
(
|
|
"text3",
|
|
models.CharField(
|
|
blank=True, max_length=1, null=True, verbose_name="Text 3"
|
|
),
|
|
),
|
|
(
|
|
"registration_date",
|
|
models.DateTimeField(verbose_name="Registration Date"),
|
|
),
|
|
(
|
|
"car",
|
|
models.OneToOneField(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="registrations",
|
|
to="inventory.car",
|
|
verbose_name="Car",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Registration",
|
|
"verbose_name_plural": "Registrations",
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="CarSerie",
|
|
fields=[
|
|
("id_car_serie", models.AutoField(primary_key=True, serialize=False)),
|
|
("name", models.CharField(blank=True, max_length=255, null=True)),
|
|
(
|
|
"arabic_name",
|
|
models.CharField(blank=True, max_length=255, null=True),
|
|
),
|
|
("year_begin", models.IntegerField(blank=True, null=True)),
|
|
("year_end", models.IntegerField(blank=True, null=True)),
|
|
(
|
|
"generation_name",
|
|
models.CharField(blank=True, max_length=255, null=True),
|
|
),
|
|
(
|
|
"slug",
|
|
models.SlugField(
|
|
blank=True, max_length=255, null=True, unique=True
|
|
),
|
|
),
|
|
(
|
|
"id_car_model",
|
|
models.ForeignKey(
|
|
db_column="id_car_model",
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.carmodel",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Series",
|
|
},
|
|
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
|
|
),
|
|
migrations.AddField(
|
|
model_name="car",
|
|
name="id_car_serie",
|
|
field=models.ForeignKey(
|
|
blank=True,
|
|
db_column="id_car_serie",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.carserie",
|
|
verbose_name="Series",
|
|
),
|
|
),
|
|
migrations.CreateModel(
|
|
name="CarSpecification",
|
|
fields=[
|
|
(
|
|
"id_car_specification",
|
|
models.AutoField(primary_key=True, serialize=False),
|
|
),
|
|
("name", models.CharField(max_length=255)),
|
|
("arabic_name", models.CharField(max_length=255)),
|
|
(
|
|
"slug",
|
|
models.SlugField(
|
|
blank=True, max_length=255, null=True, unique=True
|
|
),
|
|
),
|
|
(
|
|
"id_parent",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
db_column="id_parent",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.carspecification",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Specification",
|
|
},
|
|
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
|
|
),
|
|
migrations.CreateModel(
|
|
name="CarTrim",
|
|
fields=[
|
|
("id_car_trim", models.AutoField(primary_key=True, serialize=False)),
|
|
("name", models.CharField(blank=True, max_length=255, null=True)),
|
|
(
|
|
"arabic_name",
|
|
models.CharField(blank=True, max_length=255, null=True),
|
|
),
|
|
("start_production_year", models.IntegerField(blank=True, null=True)),
|
|
("end_production_year", models.IntegerField(blank=True, null=True)),
|
|
(
|
|
"slug",
|
|
models.SlugField(
|
|
blank=True, max_length=255, null=True, unique=True
|
|
),
|
|
),
|
|
(
|
|
"id_car_serie",
|
|
models.ForeignKey(
|
|
db_column="id_car_serie",
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.carserie",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Trim",
|
|
},
|
|
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
|
|
),
|
|
migrations.CreateModel(
|
|
name="CarSpecificationValue",
|
|
fields=[
|
|
(
|
|
"id_car_specification_value",
|
|
models.AutoField(primary_key=True, serialize=False),
|
|
),
|
|
("value", models.CharField(max_length=500)),
|
|
("unit", models.CharField(blank=True, max_length=255, null=True)),
|
|
(
|
|
"id_car_specification",
|
|
models.ForeignKey(
|
|
db_column="id_car_specification",
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.carspecification",
|
|
),
|
|
),
|
|
(
|
|
"id_car_trim",
|
|
models.ForeignKey(
|
|
db_column="id_car_trim",
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.cartrim",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Specification Value",
|
|
},
|
|
),
|
|
migrations.AddField(
|
|
model_name="carequipment",
|
|
name="id_car_trim",
|
|
field=models.ForeignKey(
|
|
db_column="id_car_trim",
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.cartrim",
|
|
),
|
|
),
|
|
migrations.AddField(
|
|
model_name="car",
|
|
name="id_car_trim",
|
|
field=models.ForeignKey(
|
|
blank=True,
|
|
db_column="id_car_trim",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.cartrim",
|
|
verbose_name="Trim",
|
|
),
|
|
),
|
|
migrations.CreateModel(
|
|
name="CustomCard",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"custom_number",
|
|
models.CharField(max_length=255, verbose_name="Custom Number"),
|
|
),
|
|
("custom_date", models.DateField(verbose_name="Custom Date")),
|
|
(
|
|
"car",
|
|
models.OneToOneField(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="custom_cards",
|
|
to="inventory.car",
|
|
verbose_name="Car",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Custom Card",
|
|
"verbose_name_plural": "Custom Cards",
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="Dealer",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"crn",
|
|
models.CharField(
|
|
blank=True,
|
|
max_length=10,
|
|
null=True,
|
|
verbose_name="Commercial Registration Number",
|
|
),
|
|
),
|
|
(
|
|
"vrn",
|
|
models.CharField(
|
|
blank=True,
|
|
max_length=15,
|
|
null=True,
|
|
verbose_name="VAT Registration Number",
|
|
),
|
|
),
|
|
(
|
|
"arabic_name",
|
|
models.CharField(max_length=255, verbose_name="Arabic Name"),
|
|
),
|
|
("name", models.CharField(max_length=255, verbose_name="English Name")),
|
|
(
|
|
"phone_number",
|
|
phonenumber_field.modelfields.PhoneNumberField(
|
|
max_length=128, region="SA", verbose_name="Phone Number"
|
|
),
|
|
),
|
|
(
|
|
"address",
|
|
models.CharField(
|
|
blank=True, max_length=200, null=True, verbose_name="Address"
|
|
),
|
|
),
|
|
(
|
|
"logo",
|
|
models.ImageField(
|
|
blank=True,
|
|
null=True,
|
|
upload_to="logos/users",
|
|
verbose_name="Logo",
|
|
),
|
|
),
|
|
(
|
|
"joined_at",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Joined At"),
|
|
),
|
|
(
|
|
"updated_at",
|
|
models.DateTimeField(auto_now=True, verbose_name="Updated At"),
|
|
),
|
|
(
|
|
"slug",
|
|
models.SlugField(
|
|
blank=True, max_length=255, null=True, unique=True
|
|
),
|
|
),
|
|
(
|
|
"entity",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
to="django_ledger.entitymodel",
|
|
),
|
|
),
|
|
(
|
|
"user",
|
|
models.OneToOneField(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="dealer",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Dealer",
|
|
"verbose_name_plural": "Dealers",
|
|
},
|
|
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
|
|
managers=[
|
|
("objects", inventory.models.DealerUserManager()),
|
|
],
|
|
),
|
|
migrations.CreateModel(
|
|
name="CustomGroup",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("name", models.CharField(max_length=100)),
|
|
(
|
|
"group",
|
|
models.OneToOneField(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
to="auth.group",
|
|
verbose_name="Group",
|
|
),
|
|
),
|
|
(
|
|
"dealer",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="groups",
|
|
to="inventory.dealer",
|
|
),
|
|
),
|
|
],
|
|
),
|
|
migrations.CreateModel(
|
|
name="Customer",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"title",
|
|
models.CharField(
|
|
choices=[
|
|
("mr", "Mr"),
|
|
("mrs", "Mrs"),
|
|
("ms", "Ms"),
|
|
("miss", "Miss"),
|
|
("dr", "Dr"),
|
|
("prof", "Prof"),
|
|
("prince", "Prince"),
|
|
("princess", "Princess"),
|
|
("company", "Company"),
|
|
("na", "N/A"),
|
|
],
|
|
default="na",
|
|
max_length=10,
|
|
verbose_name="Title",
|
|
),
|
|
),
|
|
(
|
|
"first_name",
|
|
models.CharField(max_length=50, verbose_name="First Name"),
|
|
),
|
|
(
|
|
"last_name",
|
|
models.CharField(max_length=50, verbose_name="Last Name"),
|
|
),
|
|
(
|
|
"gender",
|
|
models.CharField(
|
|
choices=[("m", "Male"), ("f", "Female")],
|
|
max_length=1,
|
|
verbose_name="Gender",
|
|
),
|
|
),
|
|
(
|
|
"dob",
|
|
models.DateField(
|
|
blank=True, null=True, verbose_name="Date of Birth"
|
|
),
|
|
),
|
|
(
|
|
"email",
|
|
models.EmailField(
|
|
max_length=254, unique=True, verbose_name="Email"
|
|
),
|
|
),
|
|
(
|
|
"national_id",
|
|
models.CharField(
|
|
blank=True,
|
|
max_length=10,
|
|
null=True,
|
|
unique=True,
|
|
verbose_name="National ID",
|
|
),
|
|
),
|
|
(
|
|
"phone_number",
|
|
phonenumber_field.modelfields.PhoneNumberField(
|
|
max_length=128,
|
|
region="SA",
|
|
unique=True,
|
|
verbose_name="Phone Number",
|
|
),
|
|
),
|
|
(
|
|
"address",
|
|
models.CharField(
|
|
blank=True, max_length=200, null=True, verbose_name="Address"
|
|
),
|
|
),
|
|
("active", models.BooleanField(default=True, verbose_name="Active")),
|
|
(
|
|
"image",
|
|
models.ImageField(
|
|
blank=True,
|
|
null=True,
|
|
upload_to="customers/",
|
|
verbose_name="Image",
|
|
),
|
|
),
|
|
(
|
|
"created",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Created"),
|
|
),
|
|
(
|
|
"updated",
|
|
models.DateTimeField(auto_now=True, verbose_name="Updated"),
|
|
),
|
|
(
|
|
"slug",
|
|
models.SlugField(
|
|
blank=True,
|
|
editable=False,
|
|
max_length=255,
|
|
null=True,
|
|
unique=True,
|
|
),
|
|
),
|
|
(
|
|
"customer_model",
|
|
models.ForeignKey(
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
to="django_ledger.customermodel",
|
|
),
|
|
),
|
|
(
|
|
"user",
|
|
models.OneToOneField(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="customer_profile",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"dealer",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="customers",
|
|
to="inventory.dealer",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Customer",
|
|
"verbose_name_plural": "Customers",
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="CarTransfer",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"transfer_date",
|
|
models.DateTimeField(
|
|
auto_now_add=True, verbose_name="Transfer Date"
|
|
),
|
|
),
|
|
("quantity", models.IntegerField(default=1, verbose_name="Quantity")),
|
|
(
|
|
"remarks",
|
|
models.TextField(blank=True, null=True, verbose_name="Remarks"),
|
|
),
|
|
(
|
|
"status",
|
|
models.CharField(
|
|
default="draft",
|
|
max_length=10,
|
|
verbose_name=[
|
|
("draft", "Draft"),
|
|
("approved", "Approved"),
|
|
("pending", "Pending"),
|
|
("accepted", "Accepted"),
|
|
("success", "Success"),
|
|
("reject", "Reject"),
|
|
("cancelled", "Cancelled"),
|
|
],
|
|
),
|
|
),
|
|
("is_approved", models.BooleanField(default=False)),
|
|
("active", models.BooleanField(default=True)),
|
|
(
|
|
"created_at",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Created At"),
|
|
),
|
|
(
|
|
"updated_at",
|
|
models.DateTimeField(auto_now=True, verbose_name="Updated At"),
|
|
),
|
|
(
|
|
"car",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="transfer_logs",
|
|
to="inventory.car",
|
|
verbose_name="Car",
|
|
),
|
|
),
|
|
(
|
|
"from_dealer",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="transfers_out",
|
|
to="inventory.dealer",
|
|
verbose_name="From Dealer",
|
|
),
|
|
),
|
|
(
|
|
"to_dealer",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="transfers_in",
|
|
to="inventory.dealer",
|
|
verbose_name="To Dealer",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Car Transfer Log",
|
|
"verbose_name_plural": "Car Transfer Logs",
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="CarLocation",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"description",
|
|
models.TextField(
|
|
blank=True,
|
|
help_text="Optional description about the showroom placement.",
|
|
null=True,
|
|
verbose_name="Description",
|
|
),
|
|
),
|
|
(
|
|
"created_at",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Created At"),
|
|
),
|
|
(
|
|
"updated_at",
|
|
models.DateTimeField(auto_now=True, verbose_name="Last Updated"),
|
|
),
|
|
(
|
|
"car",
|
|
models.OneToOneField(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="location",
|
|
to="inventory.car",
|
|
verbose_name="Car",
|
|
),
|
|
),
|
|
(
|
|
"owner",
|
|
models.ForeignKey(
|
|
help_text="Dealer who owns the car.",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="owned_cars",
|
|
to="inventory.dealer",
|
|
verbose_name="Owner",
|
|
),
|
|
),
|
|
(
|
|
"showroom",
|
|
models.ForeignKey(
|
|
help_text="Dealer where the car is displayed (can be the owner).",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="showroom_cars",
|
|
to="inventory.dealer",
|
|
verbose_name="Showroom",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Car Location",
|
|
"verbose_name_plural": "Car Locations",
|
|
},
|
|
),
|
|
migrations.AddField(
|
|
model_name="car",
|
|
name="dealer",
|
|
field=models.ForeignKey(
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
related_name="cars",
|
|
to="inventory.dealer",
|
|
verbose_name="Dealer",
|
|
),
|
|
),
|
|
migrations.AddField(
|
|
model_name="additionalservices",
|
|
name="dealer",
|
|
field=models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
to="inventory.dealer",
|
|
verbose_name="Dealer",
|
|
),
|
|
),
|
|
migrations.CreateModel(
|
|
name="Activity",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("object_id", models.PositiveIntegerField()),
|
|
(
|
|
"activity_type",
|
|
models.CharField(
|
|
choices=[
|
|
("call", "Call"),
|
|
("sms", "SMS"),
|
|
("email", "Email"),
|
|
("meeting", "Meeting"),
|
|
("whatsapp", "WhatsApp"),
|
|
("visit", "Visit"),
|
|
("negotiation", "Negotiation"),
|
|
("follow_up", "Follow Up"),
|
|
("won", "Won"),
|
|
("lost", "Lost"),
|
|
("closed", "Closed"),
|
|
("converted", "Converted"),
|
|
("transfer", "Transfer"),
|
|
("add_car", "Add Car"),
|
|
("sale_car", "Sale Car"),
|
|
("reserve_car", "Reserve Car"),
|
|
("transfer_car", "Transfer Car"),
|
|
("remove_car", "Remove Car"),
|
|
("create_quotation", "Create Quotation"),
|
|
("cancel_quotation", "Cancel Quotation"),
|
|
("create_order", "Create Order"),
|
|
("cancel_order", "Cancel Order"),
|
|
("create_invoice", "Create Invoice"),
|
|
("cancel_invoice", "Cancel Invoice"),
|
|
],
|
|
max_length=50,
|
|
verbose_name="Activity Type",
|
|
),
|
|
),
|
|
(
|
|
"notes",
|
|
models.TextField(blank=True, null=True, verbose_name="Notes"),
|
|
),
|
|
(
|
|
"created",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Created"),
|
|
),
|
|
(
|
|
"updated",
|
|
models.DateTimeField(auto_now=True, verbose_name="Updated"),
|
|
),
|
|
(
|
|
"content_type",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="contenttypes.contenttype",
|
|
),
|
|
),
|
|
(
|
|
"created_by",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
related_name="activities_created_by",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"dealer",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="activities",
|
|
to="inventory.dealer",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Activity",
|
|
"verbose_name_plural": "Activities",
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="DealerSettings",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"additional_info",
|
|
models.JSONField(blank=True, default=dict, null=True),
|
|
),
|
|
(
|
|
"bill_cash_account",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="bill_cash",
|
|
to="django_ledger.accountmodel",
|
|
),
|
|
),
|
|
(
|
|
"bill_prepaid_account",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="bill_prepaid",
|
|
to="django_ledger.accountmodel",
|
|
),
|
|
),
|
|
(
|
|
"bill_unearned_account",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="bill_unearned",
|
|
to="django_ledger.accountmodel",
|
|
),
|
|
),
|
|
(
|
|
"dealer",
|
|
models.OneToOneField(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="settings",
|
|
to="inventory.dealer",
|
|
),
|
|
),
|
|
(
|
|
"invoice_cash_account",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="invoice_cash",
|
|
to="django_ledger.accountmodel",
|
|
),
|
|
),
|
|
(
|
|
"invoice_prepaid_account",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="invoice_prepaid",
|
|
to="django_ledger.accountmodel",
|
|
),
|
|
),
|
|
(
|
|
"invoice_unearned_account",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="invoice_unearned",
|
|
to="django_ledger.accountmodel",
|
|
),
|
|
),
|
|
],
|
|
),
|
|
migrations.CreateModel(
|
|
name="Email",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("object_id", models.UUIDField()),
|
|
(
|
|
"from_email",
|
|
models.TextField(blank=True, null=True, verbose_name="From Email"),
|
|
),
|
|
(
|
|
"to_email",
|
|
models.TextField(blank=True, null=True, verbose_name="To Email"),
|
|
),
|
|
(
|
|
"subject",
|
|
models.TextField(blank=True, null=True, verbose_name="Subject"),
|
|
),
|
|
(
|
|
"message",
|
|
models.TextField(blank=True, null=True, verbose_name="Message"),
|
|
),
|
|
(
|
|
"status",
|
|
models.CharField(
|
|
choices=[
|
|
("SENT", "Sent"),
|
|
("FAILED", "Failed"),
|
|
("DELIVERED", "Delivered"),
|
|
("OPEN", "Open"),
|
|
("DRAFT", "Draft"),
|
|
],
|
|
default="OPEN",
|
|
max_length=20,
|
|
verbose_name="Status",
|
|
),
|
|
),
|
|
(
|
|
"created",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Created"),
|
|
),
|
|
(
|
|
"updated",
|
|
models.DateTimeField(auto_now=True, verbose_name="Updated"),
|
|
),
|
|
(
|
|
"content_type",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
to="contenttypes.contenttype",
|
|
),
|
|
),
|
|
(
|
|
"created_by",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
related_name="emails_created",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Email",
|
|
"verbose_name_plural": "Emails",
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="Lead",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"first_name",
|
|
models.CharField(max_length=50, verbose_name="First Name"),
|
|
),
|
|
(
|
|
"last_name",
|
|
models.CharField(max_length=50, verbose_name="Last Name"),
|
|
),
|
|
("email", models.EmailField(max_length=254, verbose_name="Email")),
|
|
(
|
|
"phone_number",
|
|
phonenumber_field.modelfields.PhoneNumberField(
|
|
max_length=128, region="SA", verbose_name="Phone Number"
|
|
),
|
|
),
|
|
(
|
|
"address",
|
|
models.CharField(
|
|
blank=True, max_length=200, null=True, verbose_name="Address"
|
|
),
|
|
),
|
|
(
|
|
"lead_type",
|
|
models.CharField(
|
|
choices=[
|
|
("customer", "Customer"),
|
|
("organization", "Organization"),
|
|
],
|
|
default="customer",
|
|
max_length=50,
|
|
verbose_name="Lead Type",
|
|
),
|
|
),
|
|
(
|
|
"source",
|
|
models.CharField(
|
|
choices=[
|
|
("referrals", "Referrals"),
|
|
("whatsapp", "WhatsApp"),
|
|
("showroom", "Showroom"),
|
|
("tiktok", "TikTok"),
|
|
("instagram", "Instagram"),
|
|
("x", "X"),
|
|
("facebook", "Facebook"),
|
|
("motory", "Motory"),
|
|
("influencers", "Influencers"),
|
|
("youtube", "Youtube"),
|
|
("campaign", "Campaign"),
|
|
],
|
|
max_length=50,
|
|
verbose_name="Source",
|
|
),
|
|
),
|
|
(
|
|
"channel",
|
|
models.CharField(
|
|
choices=[
|
|
("walk_in", "Walk In"),
|
|
("toll_free", "Toll Free"),
|
|
("website", "Website"),
|
|
("email", "Email"),
|
|
("form", "Form"),
|
|
],
|
|
max_length=50,
|
|
verbose_name="Channel",
|
|
),
|
|
),
|
|
(
|
|
"status",
|
|
models.CharField(
|
|
choices=[
|
|
("new", "New"),
|
|
("contacted", "Contacted"),
|
|
("qualified", "Qualified"),
|
|
("unqualified", "Unqualified"),
|
|
("converted", "Converted"),
|
|
],
|
|
db_index=True,
|
|
default="new",
|
|
max_length=50,
|
|
verbose_name="Status",
|
|
),
|
|
),
|
|
(
|
|
"next_action",
|
|
models.CharField(
|
|
blank=True,
|
|
max_length=255,
|
|
null=True,
|
|
verbose_name="Next Action",
|
|
),
|
|
),
|
|
(
|
|
"next_action_date",
|
|
models.DateTimeField(
|
|
blank=True, null=True, verbose_name="Next Action Date"
|
|
),
|
|
),
|
|
("is_converted", models.BooleanField(default=False)),
|
|
("converted_at", models.DateTimeField(blank=True, null=True)),
|
|
(
|
|
"created",
|
|
models.DateTimeField(
|
|
auto_now_add=True, db_index=True, verbose_name="Created"
|
|
),
|
|
),
|
|
(
|
|
"updated",
|
|
models.DateTimeField(auto_now=True, verbose_name="Updated"),
|
|
),
|
|
("slug", models.SlugField(blank=True, null=True, unique=True)),
|
|
(
|
|
"customer",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="customer_leads",
|
|
to="inventory.customer",
|
|
),
|
|
),
|
|
(
|
|
"dealer",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="leads",
|
|
to="inventory.dealer",
|
|
),
|
|
),
|
|
(
|
|
"id_car_make",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.carmake",
|
|
verbose_name="Make",
|
|
),
|
|
),
|
|
(
|
|
"id_car_model",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="inventory.carmodel",
|
|
verbose_name="Model",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Lead",
|
|
"verbose_name_plural": "Leads",
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="Notes",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("object_id", models.UUIDField()),
|
|
("note", models.TextField(verbose_name="Note")),
|
|
(
|
|
"created",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Created"),
|
|
),
|
|
(
|
|
"updated",
|
|
models.DateTimeField(auto_now=True, verbose_name="Updated"),
|
|
),
|
|
(
|
|
"content_type",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
to="contenttypes.contenttype",
|
|
),
|
|
),
|
|
(
|
|
"created_by",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
related_name="notes_created",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"dealer",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="notes",
|
|
to="inventory.dealer",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Note",
|
|
"verbose_name_plural": "Notes",
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="Notification",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("message", models.CharField(max_length=255, verbose_name="Message")),
|
|
("is_read", models.BooleanField(default=False, verbose_name="Is Read")),
|
|
(
|
|
"created",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Created"),
|
|
),
|
|
(
|
|
"user",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="notifications",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Notification",
|
|
"verbose_name_plural": "Notifications",
|
|
"ordering": ["-created"],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="Organization",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("name", models.CharField(max_length=255, verbose_name="Name")),
|
|
(
|
|
"arabic_name",
|
|
models.CharField(max_length=255, verbose_name="Arabic Name"),
|
|
),
|
|
(
|
|
"crn",
|
|
models.CharField(
|
|
max_length=15, verbose_name="Commercial Registration Number"
|
|
),
|
|
),
|
|
(
|
|
"vrn",
|
|
models.CharField(
|
|
max_length=15, verbose_name="VAT Registration Number"
|
|
),
|
|
),
|
|
("email", models.EmailField(max_length=254, verbose_name="Email")),
|
|
(
|
|
"phone_number",
|
|
phonenumber_field.modelfields.PhoneNumberField(
|
|
max_length=128, region="SA", verbose_name="Phone Number"
|
|
),
|
|
),
|
|
(
|
|
"address",
|
|
models.CharField(
|
|
blank=True, max_length=200, null=True, verbose_name="Address"
|
|
),
|
|
),
|
|
(
|
|
"logo",
|
|
models.ImageField(
|
|
blank=True, null=True, upload_to="logos", verbose_name="Logo"
|
|
),
|
|
),
|
|
("active", models.BooleanField(default=True, verbose_name="Active")),
|
|
(
|
|
"created",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Created"),
|
|
),
|
|
(
|
|
"updated",
|
|
models.DateTimeField(auto_now=True, verbose_name="Updated"),
|
|
),
|
|
(
|
|
"slug",
|
|
models.SlugField(
|
|
blank=True,
|
|
editable=False,
|
|
max_length=255,
|
|
null=True,
|
|
unique=True,
|
|
),
|
|
),
|
|
(
|
|
"customer_model",
|
|
models.ForeignKey(
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
to="django_ledger.customermodel",
|
|
),
|
|
),
|
|
(
|
|
"dealer",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="organizations",
|
|
to="inventory.dealer",
|
|
),
|
|
),
|
|
(
|
|
"user",
|
|
models.OneToOneField(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="organization_profile",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Organization",
|
|
"verbose_name_plural": "Organizations",
|
|
},
|
|
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
|
|
),
|
|
migrations.CreateModel(
|
|
name="Opportunity",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"crn",
|
|
models.CharField(
|
|
blank=True, max_length=20, null=True, verbose_name="CRN"
|
|
),
|
|
),
|
|
(
|
|
"vrn",
|
|
models.CharField(
|
|
blank=True, max_length=20, null=True, verbose_name="VRN"
|
|
),
|
|
),
|
|
(
|
|
"salary",
|
|
models.DecimalField(
|
|
blank=True,
|
|
decimal_places=2,
|
|
max_digits=10,
|
|
null=True,
|
|
verbose_name="Salary",
|
|
),
|
|
),
|
|
(
|
|
"priority",
|
|
models.CharField(
|
|
choices=[
|
|
("high", "High"),
|
|
("medium", "Medium"),
|
|
("low", "Low"),
|
|
],
|
|
default="medium",
|
|
max_length=20,
|
|
verbose_name="Priority",
|
|
),
|
|
),
|
|
(
|
|
"stage",
|
|
models.CharField(
|
|
choices=[
|
|
("qualification", "Qualification"),
|
|
("test_drive", "Test Drive"),
|
|
("quotation", "Quotation"),
|
|
("negotiation", "Negotiation"),
|
|
("financing", "Financing"),
|
|
("closed_won", "Closed Won"),
|
|
("closed_lost", "Closed Lost"),
|
|
("on_hold", "On Hold"),
|
|
],
|
|
max_length=20,
|
|
verbose_name="Stage",
|
|
),
|
|
),
|
|
(
|
|
"probability",
|
|
models.PositiveIntegerField(
|
|
validators=[inventory.models.validate_probability]
|
|
),
|
|
),
|
|
(
|
|
"amount",
|
|
models.DecimalField(
|
|
decimal_places=2, max_digits=10, verbose_name="Amount"
|
|
),
|
|
),
|
|
(
|
|
"expected_revenue",
|
|
models.DecimalField(
|
|
blank=True,
|
|
decimal_places=2,
|
|
max_digits=10,
|
|
null=True,
|
|
verbose_name="Expected Revenue",
|
|
),
|
|
),
|
|
(
|
|
"vehicle_of_interest_make",
|
|
models.CharField(blank=True, max_length=50, null=True),
|
|
),
|
|
(
|
|
"vehicle_of_interest_model",
|
|
models.CharField(blank=True, max_length=100, null=True),
|
|
),
|
|
("expected_close_date", models.DateField(blank=True, null=True)),
|
|
(
|
|
"created",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Created"),
|
|
),
|
|
(
|
|
"updated",
|
|
models.DateTimeField(auto_now=True, verbose_name="Updated"),
|
|
),
|
|
(
|
|
"slug",
|
|
models.SlugField(
|
|
blank=True,
|
|
help_text="Unique slug for the opportunity.",
|
|
null=True,
|
|
unique=True,
|
|
verbose_name="Slug",
|
|
),
|
|
),
|
|
(
|
|
"loss_reason",
|
|
models.CharField(blank=True, max_length=255, null=True),
|
|
),
|
|
(
|
|
"car",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
to="inventory.car",
|
|
verbose_name="Car",
|
|
),
|
|
),
|
|
(
|
|
"customer",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="opportunities",
|
|
to="inventory.customer",
|
|
),
|
|
),
|
|
(
|
|
"dealer",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="opportunities",
|
|
to="inventory.dealer",
|
|
),
|
|
),
|
|
(
|
|
"estimate",
|
|
models.OneToOneField(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="opportunity",
|
|
to="django_ledger.estimatemodel",
|
|
),
|
|
),
|
|
(
|
|
"lead",
|
|
models.OneToOneField(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="opportunity",
|
|
to="inventory.lead",
|
|
),
|
|
),
|
|
(
|
|
"organization",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
to="inventory.organization",
|
|
verbose_name="Organization",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Opportunity",
|
|
"verbose_name_plural": "Opportunities",
|
|
},
|
|
),
|
|
migrations.AddField(
|
|
model_name="lead",
|
|
name="organization",
|
|
field=models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="organization_leads",
|
|
to="inventory.organization",
|
|
),
|
|
),
|
|
migrations.CreateModel(
|
|
name="Refund",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"amount",
|
|
models.DecimalField(
|
|
decimal_places=2, max_digits=10, verbose_name="amount"
|
|
),
|
|
),
|
|
("reason", models.TextField(blank=True, verbose_name="reason")),
|
|
(
|
|
"refund_date",
|
|
models.DateField(auto_now_add=True, verbose_name="refund date"),
|
|
),
|
|
(
|
|
"payment",
|
|
models.OneToOneField(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="refund",
|
|
to="inventory.payment",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "refund",
|
|
"verbose_name_plural": "refunds",
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="Representative",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("name", models.CharField(max_length=255, verbose_name="Name")),
|
|
(
|
|
"arabic_name",
|
|
models.CharField(max_length=255, verbose_name="Arabic Name"),
|
|
),
|
|
(
|
|
"id_number",
|
|
models.CharField(
|
|
max_length=10, unique=True, verbose_name="ID Number"
|
|
),
|
|
),
|
|
(
|
|
"phone_number",
|
|
phonenumber_field.modelfields.PhoneNumberField(
|
|
max_length=128, region="SA", verbose_name="Phone Number"
|
|
),
|
|
),
|
|
(
|
|
"email",
|
|
models.EmailField(max_length=255, verbose_name="Email Address"),
|
|
),
|
|
(
|
|
"address",
|
|
models.CharField(
|
|
blank=True, max_length=200, null=True, verbose_name="Address"
|
|
),
|
|
),
|
|
(
|
|
"dealer",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="representatives",
|
|
to="inventory.dealer",
|
|
),
|
|
),
|
|
(
|
|
"organization",
|
|
models.ManyToManyField(
|
|
related_name="representatives", to="inventory.organization"
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Representative",
|
|
"verbose_name_plural": "Representatives",
|
|
},
|
|
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
|
|
),
|
|
migrations.CreateModel(
|
|
name="SaleOrder",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"payment_method",
|
|
models.CharField(
|
|
choices=[
|
|
("cash", "Cash"),
|
|
("finance", "Finance"),
|
|
("lease", "Lease"),
|
|
("credit_card", "Credit Card"),
|
|
("bank_transfer", "Bank Transfer"),
|
|
("sadad", "SADAD"),
|
|
],
|
|
max_length=20,
|
|
),
|
|
),
|
|
("comments", models.TextField(blank=True, null=True)),
|
|
(
|
|
"formatted_order_id",
|
|
models.CharField(editable=False, max_length=10, unique=True),
|
|
),
|
|
(
|
|
"agreed_price",
|
|
models.DecimalField(
|
|
decimal_places=2,
|
|
help_text="The final agreed-upon selling price of the vehicle.",
|
|
max_digits=12,
|
|
),
|
|
),
|
|
(
|
|
"down_payment_amount",
|
|
models.DecimalField(
|
|
decimal_places=2,
|
|
default=0.0,
|
|
help_text="The initial payment made by the customer.",
|
|
max_digits=12,
|
|
),
|
|
),
|
|
(
|
|
"trade_in_value",
|
|
models.DecimalField(
|
|
decimal_places=2,
|
|
default=0.0,
|
|
help_text="The value of any vehicle traded in by the customer.",
|
|
max_digits=12,
|
|
),
|
|
),
|
|
(
|
|
"loan_amount",
|
|
models.DecimalField(
|
|
decimal_places=2,
|
|
default=0.0,
|
|
help_text="The amount financed by a bank or third-party lender.",
|
|
max_digits=12,
|
|
),
|
|
),
|
|
(
|
|
"total_paid_amount",
|
|
models.DecimalField(
|
|
decimal_places=2,
|
|
default=0.0,
|
|
help_text="Sum of down payment, trade-in value, and loan amount received so far.",
|
|
max_digits=12,
|
|
),
|
|
),
|
|
(
|
|
"remaining_balance",
|
|
models.DecimalField(
|
|
decimal_places=2,
|
|
default=0.0,
|
|
help_text="The remaining amount due from the customer or financing.",
|
|
max_digits=12,
|
|
),
|
|
),
|
|
(
|
|
"status",
|
|
models.CharField(
|
|
choices=[
|
|
("PENDING_APPROVAL", "Pending Approval"),
|
|
("APPROVED", "Approved"),
|
|
("IN_FINANCING", "In Financing"),
|
|
("PARTIALLY_PAID", "Partially Paid"),
|
|
("FULLY_PAID", "Fully Paid"),
|
|
("PENDING_DELIVERY", "Pending Delivery"),
|
|
("DELIVERED", "Delivered"),
|
|
("CANCELLED", "Cancelled"),
|
|
],
|
|
default="PENDING_APPROVAL",
|
|
help_text="Current status of the sales order.",
|
|
max_length=20,
|
|
),
|
|
),
|
|
(
|
|
"order_date",
|
|
models.DateTimeField(
|
|
default=django.utils.timezone.now,
|
|
help_text="The date and time the sales order was created.",
|
|
),
|
|
),
|
|
(
|
|
"expected_delivery_date",
|
|
models.DateField(
|
|
blank=True,
|
|
help_text="The planned date for vehicle delivery.",
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"actual_delivery_date",
|
|
models.DateTimeField(
|
|
blank=True,
|
|
help_text="The actual date and time the vehicle was delivered.",
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"cancelled_date",
|
|
models.DateTimeField(
|
|
blank=True,
|
|
help_text="The date and time the order was cancelled, if applicable.",
|
|
null=True,
|
|
),
|
|
),
|
|
(
|
|
"cancellation_reason",
|
|
models.TextField(
|
|
blank=True,
|
|
help_text="Reason for cancellation, if applicable.",
|
|
null=True,
|
|
),
|
|
),
|
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
("updated_at", models.DateTimeField(auto_now=True)),
|
|
(
|
|
"car",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
help_text="The specific vehicle (VIN) being sold.",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.PROTECT,
|
|
related_name="sales_orders",
|
|
to="inventory.car",
|
|
),
|
|
),
|
|
(
|
|
"created_by",
|
|
models.ForeignKey(
|
|
help_text="The user who created this sales order.",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="created_sales_orders",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"customer",
|
|
models.ForeignKey(
|
|
help_text="The customer making the purchase.",
|
|
on_delete=django.db.models.deletion.PROTECT,
|
|
related_name="sales_orders",
|
|
to="inventory.customer",
|
|
),
|
|
),
|
|
(
|
|
"estimate",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="sale_orders",
|
|
to="django_ledger.estimatemodel",
|
|
verbose_name="Estimate",
|
|
),
|
|
),
|
|
(
|
|
"invoice",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="sale_orders",
|
|
to="django_ledger.invoicemodel",
|
|
verbose_name="Invoice",
|
|
),
|
|
),
|
|
(
|
|
"journal_entry",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
to="django_ledger.journalentrymodel",
|
|
),
|
|
),
|
|
(
|
|
"last_modified_by",
|
|
models.ForeignKey(
|
|
help_text="The user who last modified this sales order.",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="modified_sales_orders",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"opportunity",
|
|
models.OneToOneField(
|
|
help_text="The associated sales opportunity for this order.",
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="sales_order",
|
|
to="inventory.opportunity",
|
|
),
|
|
),
|
|
(
|
|
"trade_in_vehicle",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
help_text="The vehicle traded in by the customer, if any.",
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="traded_in_on_orders",
|
|
to="inventory.car",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Sales Order",
|
|
"verbose_name_plural": "Sales Orders",
|
|
"ordering": ["-order_date"],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="Schedule",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"purpose",
|
|
models.CharField(
|
|
choices=[
|
|
("product_demo", "Product Demo"),
|
|
("follow_up_call", "Follow-Up Call"),
|
|
("contract_discussion", "Contract Discussion"),
|
|
("sales_meeting", "Sales Meeting"),
|
|
("support_call", "Support Call"),
|
|
("other", "Other"),
|
|
],
|
|
max_length=200,
|
|
),
|
|
),
|
|
("scheduled_at", models.DateTimeField()),
|
|
(
|
|
"scheduled_type",
|
|
models.CharField(
|
|
choices=[
|
|
("call", "Call"),
|
|
("meeting", "Meeting"),
|
|
("email", "Email"),
|
|
],
|
|
default="Call",
|
|
max_length=200,
|
|
),
|
|
),
|
|
(
|
|
"duration",
|
|
models.DurationField(default=datetime.timedelta(seconds=300)),
|
|
),
|
|
("notes", models.TextField(blank=True, null=True)),
|
|
(
|
|
"status",
|
|
models.CharField(
|
|
choices=[
|
|
("scheduled", "Scheduled"),
|
|
("completed", "Completed"),
|
|
("canceled", "Canceled"),
|
|
],
|
|
default="Scheduled",
|
|
max_length=200,
|
|
),
|
|
),
|
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
("updated_at", models.DateTimeField(auto_now=True)),
|
|
(
|
|
"customer",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="schedules",
|
|
to="django_ledger.customermodel",
|
|
),
|
|
),
|
|
(
|
|
"lead",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="schedules",
|
|
to="inventory.lead",
|
|
),
|
|
),
|
|
(
|
|
"scheduled_by",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"ordering": ["-scheduled_at"],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="Staff",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("name", models.CharField(max_length=255, verbose_name="Name")),
|
|
(
|
|
"arabic_name",
|
|
models.CharField(max_length=255, verbose_name="Arabic Name"),
|
|
),
|
|
(
|
|
"phone_number",
|
|
phonenumber_field.modelfields.PhoneNumberField(
|
|
max_length=128, region="SA", verbose_name="Phone Number"
|
|
),
|
|
),
|
|
(
|
|
"staff_type",
|
|
models.CharField(
|
|
choices=[
|
|
("inventory", "Inventory"),
|
|
("accountant", "Accountant"),
|
|
("sales", "Sales"),
|
|
],
|
|
max_length=255,
|
|
verbose_name="Staff Type",
|
|
),
|
|
),
|
|
("active", models.BooleanField(default=True, verbose_name="Active")),
|
|
(
|
|
"created",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Created"),
|
|
),
|
|
(
|
|
"updated",
|
|
models.DateTimeField(auto_now=True, verbose_name="Updated"),
|
|
),
|
|
(
|
|
"slug",
|
|
models.SlugField(
|
|
blank=True,
|
|
editable=False,
|
|
max_length=255,
|
|
null=True,
|
|
unique=True,
|
|
),
|
|
),
|
|
(
|
|
"dealer",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="staff",
|
|
to="inventory.dealer",
|
|
),
|
|
),
|
|
(
|
|
"staff_member",
|
|
models.OneToOneField(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="staff",
|
|
to="appointment.staffmember",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Staff",
|
|
"verbose_name_plural": "Staff",
|
|
"permissions": [],
|
|
},
|
|
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
|
|
managers=[
|
|
("objects", inventory.models.StaffUserManager()),
|
|
],
|
|
),
|
|
migrations.AddField(
|
|
model_name="opportunity",
|
|
name="staff",
|
|
field=models.ForeignKey(
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="owner",
|
|
to="inventory.staff",
|
|
verbose_name="Owner",
|
|
),
|
|
),
|
|
migrations.CreateModel(
|
|
name="LeadStatusHistory",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"old_status",
|
|
models.CharField(
|
|
choices=[
|
|
("new", "New"),
|
|
("contacted", "Contacted"),
|
|
("qualified", "Qualified"),
|
|
("unqualified", "Unqualified"),
|
|
("converted", "Converted"),
|
|
],
|
|
max_length=50,
|
|
verbose_name="Old Status",
|
|
),
|
|
),
|
|
(
|
|
"new_status",
|
|
models.CharField(
|
|
choices=[
|
|
("new", "New"),
|
|
("contacted", "Contacted"),
|
|
("qualified", "Qualified"),
|
|
("unqualified", "Unqualified"),
|
|
("converted", "Converted"),
|
|
],
|
|
max_length=50,
|
|
verbose_name="New Status",
|
|
),
|
|
),
|
|
(
|
|
"changed_at",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Changed At"),
|
|
),
|
|
(
|
|
"lead",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="status_history",
|
|
to="inventory.lead",
|
|
),
|
|
),
|
|
(
|
|
"changed_by",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
related_name="status_changes",
|
|
to="inventory.staff",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Lead Status History",
|
|
"verbose_name_plural": "Lead Status Histories",
|
|
},
|
|
),
|
|
migrations.AddField(
|
|
model_name="lead",
|
|
name="staff",
|
|
field=models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.SET_NULL,
|
|
related_name="assigned",
|
|
to="inventory.staff",
|
|
verbose_name="Assigned",
|
|
),
|
|
),
|
|
migrations.CreateModel(
|
|
name="Tasks",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("object_id", models.UUIDField()),
|
|
("title", models.CharField(max_length=255, verbose_name="Title")),
|
|
(
|
|
"description",
|
|
models.TextField(blank=True, null=True, verbose_name="Description"),
|
|
),
|
|
("due_date", models.DateField(verbose_name="Due Date")),
|
|
(
|
|
"completed",
|
|
models.BooleanField(default=False, verbose_name="Completed"),
|
|
),
|
|
(
|
|
"created",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Created"),
|
|
),
|
|
(
|
|
"updated",
|
|
models.DateTimeField(auto_now=True, verbose_name="Updated"),
|
|
),
|
|
(
|
|
"assigned_to",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
related_name="tasks_assigned",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"content_type",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
to="contenttypes.contenttype",
|
|
),
|
|
),
|
|
(
|
|
"created_by",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
related_name="tasks_created",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
(
|
|
"dealer",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="tasks",
|
|
to="inventory.dealer",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Task",
|
|
"verbose_name_plural": "Tasks",
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="UserActivityLog",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("action", models.TextField()),
|
|
("timestamp", models.DateTimeField(auto_now_add=True)),
|
|
(
|
|
"user",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "User Activity Log",
|
|
"verbose_name_plural": "User Activity Logs",
|
|
"ordering": ["-timestamp"],
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="Vendor",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"crn",
|
|
models.CharField(
|
|
max_length=10,
|
|
unique=True,
|
|
verbose_name="Commercial Registration Number",
|
|
),
|
|
),
|
|
(
|
|
"vrn",
|
|
models.CharField(
|
|
max_length=15,
|
|
unique=True,
|
|
verbose_name="VAT Registration Number",
|
|
),
|
|
),
|
|
(
|
|
"arabic_name",
|
|
models.CharField(max_length=255, verbose_name="Arabic Name"),
|
|
),
|
|
("name", models.CharField(max_length=255, verbose_name="English Name")),
|
|
(
|
|
"contact_person",
|
|
models.CharField(max_length=100, verbose_name="Contact Person"),
|
|
),
|
|
(
|
|
"phone_number",
|
|
phonenumber_field.modelfields.PhoneNumberField(
|
|
max_length=128, region="SA", verbose_name="Phone Number"
|
|
),
|
|
),
|
|
(
|
|
"email",
|
|
models.EmailField(max_length=255, verbose_name="Email Address"),
|
|
),
|
|
("address", models.CharField(max_length=200, verbose_name="Address")),
|
|
(
|
|
"logo",
|
|
models.ImageField(
|
|
blank=True,
|
|
null=True,
|
|
upload_to="logos/vendors",
|
|
verbose_name="Logo",
|
|
),
|
|
),
|
|
("active", models.BooleanField(default=True, verbose_name="Active")),
|
|
(
|
|
"created_at",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Created At"),
|
|
),
|
|
(
|
|
"slug",
|
|
models.SlugField(
|
|
blank=True,
|
|
max_length=255,
|
|
null=True,
|
|
unique=True,
|
|
verbose_name="Slug",
|
|
),
|
|
),
|
|
(
|
|
"dealer",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="vendors",
|
|
to="inventory.dealer",
|
|
),
|
|
),
|
|
(
|
|
"vendor_model",
|
|
models.ForeignKey(
|
|
blank=True,
|
|
null=True,
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
to="django_ledger.vendormodel",
|
|
verbose_name="Vendor Model",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Vendor",
|
|
"verbose_name_plural": "Vendors",
|
|
},
|
|
bases=(models.Model, inventory.mixins.LocalizedNameMixin),
|
|
),
|
|
migrations.AddField(
|
|
model_name="car",
|
|
name="vendor",
|
|
field=models.ForeignKey(
|
|
on_delete=django.db.models.deletion.DO_NOTHING,
|
|
related_name="cars",
|
|
to="inventory.vendor",
|
|
verbose_name="Vendor",
|
|
),
|
|
),
|
|
migrations.CreateModel(
|
|
name="CarReservation",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"reserved_at",
|
|
models.DateTimeField(auto_now_add=True, verbose_name="Reserved At"),
|
|
),
|
|
("reserved_until", models.DateTimeField(verbose_name="Reserved Until")),
|
|
(
|
|
"car",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="reservations",
|
|
to="inventory.car",
|
|
verbose_name="Car",
|
|
),
|
|
),
|
|
(
|
|
"reserved_by",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="reservations",
|
|
to=settings.AUTH_USER_MODEL,
|
|
verbose_name="Reserved By",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Car Reservation",
|
|
"verbose_name_plural": "Car Reservations",
|
|
"ordering": ["-reserved_at"],
|
|
"unique_together": {("car", "reserved_until")},
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="DealersMake",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("added_at", models.DateTimeField(auto_now_add=True)),
|
|
(
|
|
"car_make",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="car_dealers",
|
|
to="inventory.carmake",
|
|
),
|
|
),
|
|
(
|
|
"dealer",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="dealer_makes",
|
|
to="inventory.dealer",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"unique_together": {("dealer", "car_make")},
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="CarColors",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
(
|
|
"car",
|
|
models.OneToOneField(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="colors",
|
|
to="inventory.car",
|
|
),
|
|
),
|
|
(
|
|
"exterior",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="colors",
|
|
to="inventory.exteriorcolors",
|
|
),
|
|
),
|
|
(
|
|
"interior",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="colors",
|
|
to="inventory.interiorcolors",
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Color",
|
|
"verbose_name_plural": "Colors",
|
|
"unique_together": {("car", "exterior", "interior")},
|
|
},
|
|
),
|
|
migrations.CreateModel(
|
|
name="PaymentHistory",
|
|
fields=[
|
|
(
|
|
"id",
|
|
models.BigAutoField(
|
|
auto_created=True,
|
|
primary_key=True,
|
|
serialize=False,
|
|
verbose_name="ID",
|
|
),
|
|
),
|
|
("user_data", models.JSONField(blank=True, null=True)),
|
|
(
|
|
"amount",
|
|
models.DecimalField(
|
|
decimal_places=2,
|
|
max_digits=10,
|
|
validators=[django.core.validators.MinValueValidator(0.01)],
|
|
),
|
|
),
|
|
("currency", models.CharField(default="SAR", max_length=3)),
|
|
(
|
|
"payment_date",
|
|
models.DateTimeField(default=django.utils.timezone.now),
|
|
),
|
|
(
|
|
"status",
|
|
models.CharField(
|
|
choices=[
|
|
("initiated", "initiated"),
|
|
("pending", "Pending"),
|
|
("completed", "Completed"),
|
|
("paid", "Paid"),
|
|
("failed", "Failed"),
|
|
("refunded", "Refunded"),
|
|
("cancelled", "Cancelled"),
|
|
],
|
|
default="pending",
|
|
max_length=10,
|
|
),
|
|
),
|
|
(
|
|
"payment_method",
|
|
models.CharField(
|
|
choices=[
|
|
("credit_card", "Credit Card"),
|
|
("debit_card", "Debit Card"),
|
|
("paypal", "PayPal"),
|
|
("bank_transfer", "Bank Transfer"),
|
|
("crypto", "Cryptocurrency"),
|
|
("other", "Other"),
|
|
],
|
|
max_length=20,
|
|
),
|
|
),
|
|
(
|
|
"transaction_id",
|
|
models.CharField(
|
|
blank=True, max_length=100, null=True, unique=True
|
|
),
|
|
),
|
|
(
|
|
"invoice_number",
|
|
models.CharField(blank=True, max_length=50, null=True),
|
|
),
|
|
(
|
|
"order_reference",
|
|
models.CharField(blank=True, max_length=100, null=True),
|
|
),
|
|
("gateway_response", models.JSONField(blank=True, null=True)),
|
|
(
|
|
"gateway_name",
|
|
models.CharField(blank=True, max_length=50, null=True),
|
|
),
|
|
("description", models.TextField(blank=True, null=True)),
|
|
("is_recurring", models.BooleanField(default=False)),
|
|
(
|
|
"billing_email",
|
|
models.EmailField(blank=True, max_length=254, null=True),
|
|
),
|
|
("billing_address", models.TextField(blank=True, null=True)),
|
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
("updated_at", models.DateTimeField(auto_now=True)),
|
|
(
|
|
"user",
|
|
models.ForeignKey(
|
|
on_delete=django.db.models.deletion.CASCADE,
|
|
related_name="payments",
|
|
to=settings.AUTH_USER_MODEL,
|
|
),
|
|
),
|
|
],
|
|
options={
|
|
"verbose_name": "Payment History",
|
|
"verbose_name_plural": "Payment Histories",
|
|
"ordering": ["-payment_date"],
|
|
"indexes": [
|
|
models.Index(
|
|
fields=["transaction_id"], name="inventory_p_transac_9469f3_idx"
|
|
),
|
|
models.Index(
|
|
fields=["user"], name="inventory_p_user_id_c31626_idx"
|
|
),
|
|
models.Index(
|
|
fields=["status"], name="inventory_p_status_abcb77_idx"
|
|
),
|
|
models.Index(
|
|
fields=["payment_date"], name="inventory_p_payment_b3068c_idx"
|
|
),
|
|
],
|
|
},
|
|
),
|
|
]
|