From 7b3fc15efdbd9802460505714115d2a1cd7bd623 Mon Sep 17 00:00:00 2001 From: ismail Date: Sun, 22 Jun 2025 20:06:26 +0300 Subject: [PATCH 1/2] update on the po and bill --- inventory/templatetags/custom_filters.py | 4 ++ inventory/views.py | 47 ++++++++++++++----- .../includes/po_item_formset.html | 4 +- templates/purchase_orders/po_update.html | 2 +- 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/inventory/templatetags/custom_filters.py b/inventory/templatetags/custom_filters.py index a0377f2f..e10334a9 100644 --- a/inventory/templatetags/custom_filters.py +++ b/inventory/templatetags/custom_filters.py @@ -449,6 +449,10 @@ def po_item_table1(context, queryset): "purchase_orders/includes/po_item_formset.html", takes_context=True ) def po_item_formset_table(context, po_model, itemtxs_formset): + # print(len(itemtxs_formset.forms)) + + for form in itemtxs_formset.forms: + form.fields['item_model'].queryset = form.fields['item_model'].queryset.filter(item_role="inventory") return { "entity_slug": context["view"].kwargs["entity_slug"], "po_model": po_model, diff --git a/inventory/views.py b/inventory/views.py index fd027787..e87d8b7d 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -9100,14 +9100,31 @@ class PurchaseOrderUpdateView(PurchaseOrderModelUpdateViewBase): template_name = "purchase_orders/po_update.html" context_object_name = "po_model" - def get_context_data(self, **kwargs): + def get_context_data(self, itemtxs_formset=None, **kwargs): dealer = get_user_type(self.request) context = super().get_context_data(**kwargs) context["entity_slug"] = dealer.entity.slug - context["make_data"] = models.CarMake.objects.all() - context["model_data"] = models.CarModel.objects.none() - context["serie_data"] = models.CarSerie.objects.none() - context["trim_data"] = models.CarTrim.objects.none() + po_model: PurchaseOrderModel = self.object + # context["make_data"] = models.CarMake.objects.all() + # context["model_data"] = models.CarModel.objects.none() + # context["serie_data"] = models.CarSerie.objects.none() + # context["trim_data"] = models.CarTrim.objects.none() + # itemtxs_qs = dealer.entity.get_items_inventory().filter(item_role="inventory") + if not itemtxs_formset: + itemtxs_qs = self.get_po_itemtxs_qs(po_model) + itemtxs_qs, itemtxs_agg = po_model.get_itemtxs_data(queryset=itemtxs_qs) + po_itemtxs_formset_class = get_po_itemtxs_formset_class(po_model) + itemtxs_formset = po_itemtxs_formset_class( + entity_slug=dealer.entity.slug, + user_model=dealer.entity.admin, + po_model=po_model, + queryset=itemtxs_qs, + ) + else: + itemtxs_qs, itemtxs_agg = po_model.get_itemtxs_data() + + context['itemtxs_qs'] = itemtxs_qs + context['itemtxs_formset'] = itemtxs_formset return context def get_success_url(self): @@ -9127,7 +9144,7 @@ class PurchaseOrderUpdateView(PurchaseOrderModelUpdateViewBase): kwargs={"entity_slug": entity_slug, "po_pk": po_pk}, ) ) - return super(PurchaseOrderModelUpdateViewBase, self).get( + return super(PurchaseOrderUpdateView, self).get( request, entity_slug, po_pk, *args, **kwargs ) @@ -9227,7 +9244,9 @@ class BasePurchaseOrderActionActionView(BasePurchaseOrderActionActionViewBase): ) def get(self, request, *args, **kwargs): - kwargs["user_model"] = self.request.user + # kwargs["user_model"] = self.request.user + dealer = get_user_type(request) + kwargs["user_model"] = dealer.entity.admin if not self.action_name: raise ImproperlyConfigured("View attribute action_name is required.") response = super(BasePurchaseOrderActionActionView, self).get( @@ -9236,13 +9255,19 @@ class BasePurchaseOrderActionActionView(BasePurchaseOrderActionActionViewBase): po_model: PurchaseOrderModel = self.get_object() try: - getattr(po_model, self.action_name)(commit=self.commit, **kwargs) - except ValidationError as e: + getattr(po_model, self.action_name)(commit=self.commit,**kwargs) messages.add_message( request, - message=e.message, - level=messages.ERROR, + message="PO updated successfully.", + level=messages.SUCCESS, ) + except ValidationError as e: + print(e) + # messages.add_message( + # request, + # message=e.message, + # level=messages.ERROR, + # ) return response diff --git a/templates/purchase_orders/includes/po_item_formset.html b/templates/purchase_orders/includes/po_item_formset.html index 23e9218f..32c3ffbd 100644 --- a/templates/purchase_orders/includes/po_item_formset.html +++ b/templates/purchase_orders/includes/po_item_formset.html @@ -1,5 +1,7 @@ {% load trans from i18n %} -{% load django_ledger %} +{% load currency_symbol from django_ledger %} +{% load icon from django_ledger %} +{% load custom_filters %} {% load widget_tweaks %}
Date: Sun, 22 Jun 2025 20:07:52 +0300 Subject: [PATCH 2/2] formating and lintitng --- inventory/forms.py | 24 +- inventory/migrations/0001_initial.py | 3297 ++++++++++++++--- .../0002_remove_saleorder_journal_entry.py | 7 +- .../0003_saleorder_journal_entry.py | 16 +- ..._remove_saleorder_agreed_price_and_more.py | 51 +- .../migrations/0005_remove_saleorder_car.py | 7 +- inventory/migrations/0006_saleorder_dealer.py | 14 +- .../migrations/0007_saleorder_estimate.py | 18 +- .../migrations/0008_saleorder_opportunity.py | 16 +- .../migrations/0009_saleorder_customer.py | 16 +- ...010_alter_saleorder_created_by_and_more.py | 29 +- inventory/models.py | 2 +- inventory/signals.py | 4 +- inventory/templatetags/custom_filters.py | 34 +- inventory/urls.py | 13 +- inventory/views.py | 35 +- templates/inventory/car_list_view.html | 526 +-- templates/inventory/list.html | 124 +- .../sales/estimates/sale_order_form1.html | 76 +- templates/sales/saleorder_detail.html | 492 +-- 20 files changed, 3523 insertions(+), 1278 deletions(-) diff --git a/inventory/forms.py b/inventory/forms.py index af6d0a24..3debc3bf 100644 --- a/inventory/forms.py +++ b/inventory/forms.py @@ -1355,11 +1355,27 @@ class SaleOrderForm(forms.ModelForm): class Meta: model = SaleOrder fields = [ - "customer","expected_delivery_date","estimate","opportunity","comments","order_date","status"] + "customer", + "expected_delivery_date", + "estimate", + "opportunity", + "comments", + "order_date", + "status", + ] widgets = { - "expected_delivery_date": forms.DateInput(attrs={"type": "date", "label": _("Expected Delivery Date")}), - "order_date": forms.DateInput(attrs={"type": "date", "label": _("Order Date")}), - "customer": forms.Select(attrs={"class": "form-control","label": _("Customer"),}), + "expected_delivery_date": forms.DateInput( + attrs={"type": "date", "label": _("Expected Delivery Date")} + ), + "order_date": forms.DateInput( + attrs={"type": "date", "label": _("Order Date")} + ), + "customer": forms.Select( + attrs={ + "class": "form-control", + "label": _("Customer"), + } + ), } diff --git a/inventory/migrations/0001_initial.py b/inventory/migrations/0001_initial.py index a629e2f3..eecd0e39 100644 --- a/inventory/migrations/0001_initial.py +++ b/inventory/migrations/0001_initial.py @@ -14,867 +14,3046 @@ 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'), + ("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', + 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)), + ( + "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', + "verbose_name": "Equipment", }, bases=(models.Model, inventory.mixins.LocalizedNameMixin), ), migrations.CreateModel( - name='CarMake', + 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)), + ("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', + "verbose_name": "Make", }, bases=(models.Model, inventory.mixins.LocalizedNameMixin), ), migrations.CreateModel( - name='ExteriorColors', + 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')), + ( + "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', + "verbose_name": "Exterior Colors", + "verbose_name_plural": "Exterior Colors", }, bases=(models.Model, inventory.mixins.LocalizedNameMixin), ), migrations.CreateModel( - name='InteriorColors', + 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')), + ( + "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', + "verbose_name": "Interior Colors", + "verbose_name_plural": "Interior Colors", }, bases=(models.Model, inventory.mixins.LocalizedNameMixin), ), migrations.CreateModel( - name='Payment', + 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')), + ( + "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', + "verbose_name": "payment", + "verbose_name_plural": "payments", }, ), migrations.CreateModel( - name='VatRate', + 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)), + ( + "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', + 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')), + ( + "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', + "verbose_name": "Additional Services", + "verbose_name_plural": "Additional Services", }, bases=(models.Model, inventory.mixins.LocalizedNameMixin), ), migrations.CreateModel( - name='Car', + 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')), + ( + "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', + "verbose_name": "Car", + "verbose_name_plural": "Cars", }, ), migrations.CreateModel( - name='CarFinance', + 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')), + ( + "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', + "verbose_name": "Car Financial Details", + "verbose_name_plural": "Car Financial Details", }, ), migrations.CreateModel( - name='CarModel', + 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')), + ("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', + "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'), + 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', + 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')), + ("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', + "verbose_name": "Option", }, bases=(models.Model, inventory.mixins.LocalizedNameMixin), ), migrations.CreateModel( - name='CarOptionValue', + 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')), + ( + "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', + "verbose_name": "Option Value", }, ), migrations.CreateModel( - name='CarRegistration', + 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')), + ( + "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', + "verbose_name": "Registration", + "verbose_name_plural": "Registrations", }, ), migrations.CreateModel( - name='CarSerie', + 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')), + ("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', + "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'), + 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', + 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')), + ( + "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', + "verbose_name": "Specification", }, bases=(models.Model, inventory.mixins.LocalizedNameMixin), ), migrations.CreateModel( - name='CarTrim', + 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')), + ("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', + "verbose_name": "Trim", }, bases=(models.Model, inventory.mixins.LocalizedNameMixin), ), migrations.CreateModel( - name='CarSpecificationValue', + 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')), + ( + "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', + "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'), + 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'), + 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', + 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')), + ( + "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', + "verbose_name": "Custom Card", + "verbose_name_plural": "Custom Cards", }, ), migrations.CreateModel( - name='Dealer', + 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)), + ( + "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', + "verbose_name": "Dealer", + "verbose_name_plural": "Dealers", }, bases=(models.Model, inventory.mixins.LocalizedNameMixin), managers=[ - ('objects', inventory.models.DealerUserManager()), + ("objects", inventory.models.DealerUserManager()), ], ), migrations.CreateModel( - name='CustomGroup', + 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')), + ( + "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', + 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')), + ( + "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', + "verbose_name": "Customer", + "verbose_name_plural": "Customers", }, ), migrations.CreateModel( - name='CarTransfer', + 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')), + ( + "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', + "verbose_name": "Car Transfer Log", + "verbose_name_plural": "Car Transfer Logs", }, ), migrations.CreateModel( - name='CarLocation', + 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')), + ( + "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', + "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'), + 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'), + 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', + 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')), + ( + "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', + "verbose_name": "Activity", + "verbose_name_plural": "Activities", }, ), migrations.CreateModel( - name='DealerSettings', + 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')), + ( + "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', + 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)), + ( + "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', + "verbose_name": "Email", + "verbose_name_plural": "Emails", }, ), migrations.CreateModel( - name='Lead', + 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')), + ( + "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', + "verbose_name": "Lead", + "verbose_name_plural": "Leads", }, ), migrations.CreateModel( - name='Notes', + 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')), + ( + "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', + "verbose_name": "Note", + "verbose_name_plural": "Notes", }, ), migrations.CreateModel( - name='Notification', + 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)), + ( + "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'], + "verbose_name": "Notification", + "verbose_name_plural": "Notifications", + "ordering": ["-created"], }, ), migrations.CreateModel( - name='Organization', + 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)), + ( + "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', + "verbose_name": "Organization", + "verbose_name_plural": "Organizations", }, bases=(models.Model, inventory.mixins.LocalizedNameMixin), ), migrations.CreateModel( - name='Opportunity', + 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')), + ( + "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', + "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'), + 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', + 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')), + ( + "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', + "verbose_name": "refund", + "verbose_name_plural": "refunds", }, ), migrations.CreateModel( - name='Representative', + 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')), + ( + "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', + "verbose_name": "Representative", + "verbose_name_plural": "Representatives", }, bases=(models.Model, inventory.mixins.LocalizedNameMixin), ), migrations.CreateModel( - name='SaleOrder', + 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')), + ( + "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'], + "verbose_name": "Sales Order", + "verbose_name_plural": "Sales Orders", + "ordering": ["-order_date"], }, ), migrations.CreateModel( - name='Schedule', + 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)), + ( + "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'], + "ordering": ["-scheduled_at"], }, ), migrations.CreateModel( - name='Staff', + 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')), + ( + "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': [], + "verbose_name": "Staff", + "verbose_name_plural": "Staff", + "permissions": [], }, bases=(models.Model, inventory.mixins.LocalizedNameMixin), managers=[ - ('objects', inventory.models.StaffUserManager()), + ("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'), + 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', + 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')), + ( + "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', + "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'), + 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', + 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')), + ( + "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', + "verbose_name": "Task", + "verbose_name_plural": "Tasks", }, ), migrations.CreateModel( - name='UserActivityLog', + 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)), + ( + "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'], + "verbose_name": "User Activity Log", + "verbose_name_plural": "User Activity Logs", + "ordering": ["-timestamp"], }, ), migrations.CreateModel( - name='Vendor', + 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')), + ( + "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', + "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'), + 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', + 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')), + ( + "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')}, + "verbose_name": "Car Reservation", + "verbose_name_plural": "Car Reservations", + "ordering": ["-reserved_at"], + "unique_together": {("car", "reserved_until")}, }, ), migrations.CreateModel( - name='DealersMake', + 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')), + ( + "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')}, + "unique_together": {("dealer", "car_make")}, }, ), migrations.CreateModel( - name='CarColors', + 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')), + ( + "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')}, + "verbose_name": "Color", + "verbose_name_plural": "Colors", + "unique_together": {("car", "exterior", "interior")}, }, ), migrations.CreateModel( - name='PaymentHistory', + 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)), + ( + "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')], + "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" + ), + ], }, ), ] diff --git a/inventory/migrations/0002_remove_saleorder_journal_entry.py b/inventory/migrations/0002_remove_saleorder_journal_entry.py index aee1533b..78d5b484 100644 --- a/inventory/migrations/0002_remove_saleorder_journal_entry.py +++ b/inventory/migrations/0002_remove_saleorder_journal_entry.py @@ -4,14 +4,13 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('inventory', '0001_initial'), + ("inventory", "0001_initial"), ] operations = [ migrations.RemoveField( - model_name='saleorder', - name='journal_entry', + model_name="saleorder", + name="journal_entry", ), ] diff --git a/inventory/migrations/0003_saleorder_journal_entry.py b/inventory/migrations/0003_saleorder_journal_entry.py index 5cee8325..c0134202 100644 --- a/inventory/migrations/0003_saleorder_journal_entry.py +++ b/inventory/migrations/0003_saleorder_journal_entry.py @@ -5,16 +5,20 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('django_ledger', '0022_alter_billmodel_bill_items_and_more'), - ('inventory', '0002_remove_saleorder_journal_entry'), + ("django_ledger", "0022_alter_billmodel_bill_items_and_more"), + ("inventory", "0002_remove_saleorder_journal_entry"), ] operations = [ migrations.AddField( - model_name='saleorder', - name='journal_entry', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='django_ledger.journalentrymodel'), + model_name="saleorder", + name="journal_entry", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="django_ledger.journalentrymodel", + ), ), ] diff --git a/inventory/migrations/0004_remove_saleorder_agreed_price_and_more.py b/inventory/migrations/0004_remove_saleorder_agreed_price_and_more.py index 5d924dd6..51a90490 100644 --- a/inventory/migrations/0004_remove_saleorder_agreed_price_and_more.py +++ b/inventory/migrations/0004_remove_saleorder_agreed_price_and_more.py @@ -4,58 +4,57 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('inventory', '0003_saleorder_journal_entry'), + ("inventory", "0003_saleorder_journal_entry"), ] operations = [ migrations.RemoveField( - model_name='saleorder', - name='agreed_price', + model_name="saleorder", + name="agreed_price", ), migrations.RemoveField( - model_name='saleorder', - name='customer', + model_name="saleorder", + name="customer", ), migrations.RemoveField( - model_name='saleorder', - name='down_payment_amount', + model_name="saleorder", + name="down_payment_amount", ), migrations.RemoveField( - model_name='saleorder', - name='estimate', + model_name="saleorder", + name="estimate", ), migrations.RemoveField( - model_name='saleorder', - name='journal_entry', + model_name="saleorder", + name="journal_entry", ), migrations.RemoveField( - model_name='saleorder', - name='loan_amount', + model_name="saleorder", + name="loan_amount", ), migrations.RemoveField( - model_name='saleorder', - name='opportunity', + model_name="saleorder", + name="opportunity", ), migrations.RemoveField( - model_name='saleorder', - name='payment_method', + model_name="saleorder", + name="payment_method", ), migrations.RemoveField( - model_name='saleorder', - name='remaining_balance', + model_name="saleorder", + name="remaining_balance", ), migrations.RemoveField( - model_name='saleorder', - name='total_paid_amount', + model_name="saleorder", + name="total_paid_amount", ), migrations.RemoveField( - model_name='saleorder', - name='trade_in_value', + model_name="saleorder", + name="trade_in_value", ), migrations.RemoveField( - model_name='saleorder', - name='trade_in_vehicle', + model_name="saleorder", + name="trade_in_vehicle", ), ] diff --git a/inventory/migrations/0005_remove_saleorder_car.py b/inventory/migrations/0005_remove_saleorder_car.py index 113040fc..5aa3c25f 100644 --- a/inventory/migrations/0005_remove_saleorder_car.py +++ b/inventory/migrations/0005_remove_saleorder_car.py @@ -4,14 +4,13 @@ from django.db import migrations class Migration(migrations.Migration): - dependencies = [ - ('inventory', '0004_remove_saleorder_agreed_price_and_more'), + ("inventory", "0004_remove_saleorder_agreed_price_and_more"), ] operations = [ migrations.RemoveField( - model_name='saleorder', - name='car', + model_name="saleorder", + name="car", ), ] diff --git a/inventory/migrations/0006_saleorder_dealer.py b/inventory/migrations/0006_saleorder_dealer.py index 16181308..40eafea4 100644 --- a/inventory/migrations/0006_saleorder_dealer.py +++ b/inventory/migrations/0006_saleorder_dealer.py @@ -5,16 +5,20 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('inventory', '0005_remove_saleorder_car'), + ("inventory", "0005_remove_saleorder_car"), ] operations = [ migrations.AddField( - model_name='saleorder', - name='dealer', - field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='sale_orders', to='inventory.dealer'), + model_name="saleorder", + name="dealer", + field=models.ForeignKey( + default=1, + on_delete=django.db.models.deletion.CASCADE, + related_name="sale_orders", + to="inventory.dealer", + ), preserve_default=False, ), ] diff --git a/inventory/migrations/0007_saleorder_estimate.py b/inventory/migrations/0007_saleorder_estimate.py index 7d5254db..6e32e257 100644 --- a/inventory/migrations/0007_saleorder_estimate.py +++ b/inventory/migrations/0007_saleorder_estimate.py @@ -5,16 +5,22 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('django_ledger', '0022_alter_billmodel_bill_items_and_more'), - ('inventory', '0006_saleorder_dealer'), + ("django_ledger", "0022_alter_billmodel_bill_items_and_more"), + ("inventory", "0006_saleorder_dealer"), ] operations = [ migrations.AddField( - model_name='saleorder', - name='estimate', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='sale_orders', to='django_ledger.estimatemodel', verbose_name='Estimate'), + model_name="saleorder", + name="estimate", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="sale_orders", + to="django_ledger.estimatemodel", + verbose_name="Estimate", + ), ), ] diff --git a/inventory/migrations/0008_saleorder_opportunity.py b/inventory/migrations/0008_saleorder_opportunity.py index 41fecf33..ad5caf00 100644 --- a/inventory/migrations/0008_saleorder_opportunity.py +++ b/inventory/migrations/0008_saleorder_opportunity.py @@ -5,15 +5,21 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('inventory', '0007_saleorder_estimate'), + ("inventory", "0007_saleorder_estimate"), ] operations = [ migrations.AddField( - model_name='saleorder', - name='opportunity', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='sale_orders', to='inventory.opportunity', verbose_name='Opportunity'), + model_name="saleorder", + name="opportunity", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="sale_orders", + to="inventory.opportunity", + verbose_name="Opportunity", + ), ), ] diff --git a/inventory/migrations/0009_saleorder_customer.py b/inventory/migrations/0009_saleorder_customer.py index 0fc198f5..47eddd24 100644 --- a/inventory/migrations/0009_saleorder_customer.py +++ b/inventory/migrations/0009_saleorder_customer.py @@ -5,15 +5,21 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('inventory', '0008_saleorder_opportunity'), + ("inventory", "0008_saleorder_opportunity"), ] operations = [ migrations.AddField( - model_name='saleorder', - name='customer', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='sale_orders', to='inventory.customer', verbose_name='Customer'), + model_name="saleorder", + name="customer", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="sale_orders", + to="inventory.customer", + verbose_name="Customer", + ), ), ] diff --git a/inventory/migrations/0010_alter_saleorder_created_by_and_more.py b/inventory/migrations/0010_alter_saleorder_created_by_and_more.py index 72054443..95c30c5c 100644 --- a/inventory/migrations/0010_alter_saleorder_created_by_and_more.py +++ b/inventory/migrations/0010_alter_saleorder_created_by_and_more.py @@ -6,21 +6,34 @@ from django.db import migrations, models class Migration(migrations.Migration): - dependencies = [ - ('inventory', '0009_saleorder_customer'), + ("inventory", "0009_saleorder_customer"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.AlterField( - model_name='saleorder', - name='created_by', - field=models.ForeignKey(blank=True, 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), + model_name="saleorder", + name="created_by", + field=models.ForeignKey( + blank=True, + 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, + ), ), migrations.AlterField( - model_name='saleorder', - name='last_modified_by', - field=models.ForeignKey(blank=True, 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), + model_name="saleorder", + name="last_modified_by", + field=models.ForeignKey( + blank=True, + 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, + ), ), ] diff --git a/inventory/models.py b/inventory/models.py index 5dcb548e..ade6dd21 100644 --- a/inventory/models.py +++ b/inventory/models.py @@ -2479,7 +2479,6 @@ class SaleOrder(models.Model): return self.invoice.get_itemtxs_data()[0] return [] - @property def cars(self): if self.items: @@ -2497,6 +2496,7 @@ class CustomGroup(models.Model): @property def entity(self): return self.invoice.entity + @property def users(self): return self.group.user_set.all() diff --git a/inventory/signals.py b/inventory/signals.py index f91edee5..a37a1b4c 100644 --- a/inventory/signals.py +++ b/inventory/signals.py @@ -309,7 +309,9 @@ def update_item_model_cost(sender, instance, created, **kwargs): # entity.get_all_accounts() # .filter(name="Cash", role=roles.ASSET_CA_CASH) # .first() - entity.get_all_accounts().filter(role=roles.ASSET_CA_CASH,role_default=True).first() + entity.get_all_accounts() + .filter(role=roles.ASSET_CA_CASH, role_default=True) + .first() ) ledger = LedgerModel.objects.create( diff --git a/inventory/templatetags/custom_filters.py b/inventory/templatetags/custom_filters.py index e10334a9..0d121a69 100644 --- a/inventory/templatetags/custom_filters.py +++ b/inventory/templatetags/custom_filters.py @@ -9,6 +9,7 @@ from django.forms import ValidationError from django.utils.formats import number_format from django_ledger.io.io_core import get_localdate, validate_activity from django_ledger.models import InvoiceModel, JournalEntryModel, BillModel + register = template.Library() @@ -452,7 +453,9 @@ def po_item_formset_table(context, po_model, itemtxs_formset): # print(len(itemtxs_formset.forms)) for form in itemtxs_formset.forms: - form.fields['item_model'].queryset = form.fields['item_model'].queryset.filter(item_role="inventory") + form.fields["item_model"].queryset = form.fields["item_model"].queryset.filter( + item_role="inventory" + ) return { "entity_slug": context["view"].kwargs["entity_slug"], "po_model": po_model, @@ -604,27 +607,26 @@ def get_vehicle_type_name(car_serie): return "sedan" - @register.filter def status_badge_color(status): color_map = { - 'PENDING_APPROVAL': 'warning', - 'APPROVED': 'info', - 'IN_FINANCING': 'primary', - 'PARTIALLY_PAID': 'success', - 'FULLY_PAID': 'success', - 'PENDING_DELIVERY': 'warning', - 'DELIVERED': 'success', - 'CANCELLED': 'danger', + "PENDING_APPROVAL": "warning", + "APPROVED": "info", + "IN_FINANCING": "primary", + "PARTIALLY_PAID": "success", + "FULLY_PAID": "success", + "PENDING_DELIVERY": "warning", + "DELIVERED": "success", + "CANCELLED": "danger", } - return color_map.get(status, 'secondary') + return color_map.get(status, "secondary") -@register.inclusion_tag('inventory/tags/inventory_table.html', takes_context=True) +@register.inclusion_tag("inventory/tags/inventory_table.html", takes_context=True) def inventory_table(context, queryset): ctx = { - 'entity_slug': context['view'].kwargs['entity_slug'], - 'inventory_list': queryset + "entity_slug": context["view"].kwargs["entity_slug"], + "inventory_list": queryset, } - ctx.update(queryset.aggregate(inventory_total_value=Sum('total_value'))) - return ctx \ No newline at end of file + ctx.update(queryset.aggregate(inventory_total_value=Sum("total_value"))) + return ctx diff --git a/inventory/urls.py b/inventory/urls.py index a763ac0b..e20406d8 100644 --- a/inventory/urls.py +++ b/inventory/urls.py @@ -375,9 +375,16 @@ urlpatterns = [ views.sales_list_view, name="sales_list", ), - path('sale_orders//', views.SaleOrderDetailView.as_view(), name='order_detail'), - path('inventory//list/', views.InventoryListView.as_view(), name='inventort_list'), - + path( + "sale_orders//", + views.SaleOrderDetailView.as_view(), + name="order_detail", + ), + path( + "inventory//list/", + views.InventoryListView.as_view(), + name="inventort_list", + ), # Sales URLs quotation_create # path( # "sales/quotations/create/", diff --git a/inventory/views.py b/inventory/views.py index e87d8b7d..91b3781d 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -3626,26 +3626,28 @@ def sales_list_view(request): context = {"txs": page_obj, "page_obj": page_obj} return render(request, "sales/sales_list.html", context) + class SaleOrderDetailView(LoginRequiredMixin, DetailView): model = models.SaleOrder - template_name = 'sales/saleorder_detail.html' - context_object_name = 'sale_order' + template_name = "sales/saleorder_detail.html" + context_object_name = "sale_order" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) sale_order = self.get_object() # Add additional context data - context['status_choices'] = dict(models.SaleOrder.STATUS_CHOICES) - context['page_title'] = _('Sales Order Details') + context["status_choices"] = dict(models.SaleOrder.STATUS_CHOICES) + context["page_title"] = _("Sales Order Details") # Calculate any additional properties you want to display - context['is_delivered'] = sale_order.status == 'DELIVERED' - context['is_cancelled'] = sale_order.status == 'CANCELLED' - context['is_pending_approval'] = sale_order.status == 'PENDING_APPROVAL' + context["is_delivered"] = sale_order.status == "DELIVERED" + context["is_cancelled"] = sale_order.status == "CANCELLED" + context["is_pending_approval"] = sale_order.status == "PENDING_APPROVAL" return context + # Estimates class EstimateListView(LoginRequiredMixin, PermissionRequiredMixin, ListView): """ @@ -4042,8 +4044,7 @@ def create_sale_order(request, pk): customer = estimate.customer.customer_set.first() form.fields["estimate"].queryset = EstimateModel.objects.filter(pk=pk) form.initial["estimate"] = estimate - form.fields["customer"].queryset = models.Customer.objects.filter( - pk=customer.pk) + form.fields["customer"].queryset = models.Customer.objects.filter(pk=customer.pk) form.initial["customer"] = customer if hasattr(estimate, "opportunity"): form.initial["opportunity"] = estimate.opportunity @@ -4569,7 +4570,6 @@ def invoice_create(request, pk): } ) - context = { "form": form, "estimate": estimate, @@ -8966,7 +8966,11 @@ def InventoryItemCreateView(request): trim_name = models.CarTrim.objects.get(pk=trim) inventory_name = f"{make_name.name} || {model_name.name} || {serie_name.name} || {trim_name.name} || {year} || {exterior.name} || {interior.name}" - if inventory := entity.get_items_inventory().filter(name=inventory_name).first(): + if ( + inventory := entity.get_items_inventory() + .filter(name=inventory_name) + .first() + ): messages.error(request, _("Inventory item already exists")) return redirect(f"{reverse('inventory_item_create')}?for_po={for_po}") uom = entity.get_uom_all().get(name="Unit") @@ -9123,8 +9127,8 @@ class PurchaseOrderUpdateView(PurchaseOrderModelUpdateViewBase): else: itemtxs_qs, itemtxs_agg = po_model.get_itemtxs_data() - context['itemtxs_qs'] = itemtxs_qs - context['itemtxs_formset'] = itemtxs_formset + context["itemtxs_qs"] = itemtxs_qs + context["itemtxs_formset"] = itemtxs_formset return context def get_success_url(self): @@ -9255,7 +9259,7 @@ class BasePurchaseOrderActionActionView(BasePurchaseOrderActionActionViewBase): po_model: PurchaseOrderModel = self.get_object() try: - getattr(po_model, self.action_name)(commit=self.commit,**kwargs) + getattr(po_model, self.action_name)(commit=self.commit, **kwargs) messages.add_message( request, message="PO updated successfully.", @@ -9510,7 +9514,6 @@ def bulk_update_car_price(request): return response - class InventoryListView(InventoryListViewBase): template_name = "inventory/list.html" @@ -9521,4 +9524,4 @@ class InventoryListView(InventoryListViewBase): self.queryset = ItemTransactionModel.objects.inventory_pipeline_aggregate( entity_slug=dealer.entity.slug, ) - return super().get_queryset() \ No newline at end of file + return super().get_queryset() diff --git a/templates/inventory/car_list_view.html b/templates/inventory/car_list_view.html index 914b3209..43ffefc8 100644 --- a/templates/inventory/car_list_view.html +++ b/templates/inventory/car_list_view.html @@ -3,297 +3,297 @@ {%block title%} {%trans 'Stocks'%} {%endblock%} {% block customCSS %} - + {% endblock customCSS %} {% block content %} -
-
- -
- - - - - -
-
-
- {% csrf_token %} -
- - -
- -
-
-
-
+
+
+
+
-
-
- {{ _("Select All") }} + hx-on::after-request="on_after_request()"> + + + + + + + +
+
+
+
+ Loading...
- {% for car in cars %} -
-
-
-
-
- -
-
- -
-
- {{ car.vin }} -
-
- -
-
- -
-
{{ car.year }}
-

- - {{ car.id_car_make.get_local_name }} - - {{ car.id_car_model.get_local_name }} -

- - {{ car.id_car_trim }} - + +
+
+
+
+ + + + + +
+
+
+ {% csrf_token %} +
+ + +
+ +
+
+
+
+
+
+ {{ _("Select All") }} +
+ {% for car in cars %} +
+
+
+
+
+ +
+ +
+
+ {{ car.vin }} +
+
+ +
+
+ +
+
{{ car.year }}
+

+ + {{ car.id_car_make.get_local_name }} + + {{ car.id_car_model.get_local_name }} +

+ + {{ car.id_car_trim }} + +
-
-

- {{ car.colors.exterior.get_local_name }} -

- - {{ car.receiving_date|naturalday|capfirst }} - -
+
+

+ {{ car.colors.exterior.get_local_name }} +

+ + {{ car.receiving_date|naturalday|capfirst }} + +
-
- {% if car.status == "available" %} - {{ _("Available") }} - {% elif car.status == "reserved" %} - {{ _("Reserved") }} - {% elif car.status == "sold" %} - {{ _("Sold") }} - {% elif car.status == "transfer" %} - {{ _("Transfer") }} - {% endif %} -
+
+ {% if car.status == "available" %} + {{ _("Available") }} + {% elif car.status == "reserved" %} + {{ _("Reserved") }} + {% elif car.status == "sold" %} + {{ _("Sold") }} + {% elif car.status == "transfer" %} + {{ _("Transfer") }} + {% endif %} +
-
-
- {{ _("Inventory Ready") }} - {% if car.ready %} - - Ready - - {{ _("Yes") }} - {% else %} - - Not Ready - - {{ _("No") }} - {% endif %} +
+
+ {{ _("Inventory Ready") }} + {% if car.ready %} + + Ready + + {{ _("Yes") }} + {% else %} + + Not Ready + + {{ _("No") }} + {% endif %} +
+
+
+
+ + +
- - - + {% empty %} +
+
+ +

{{ _("No vehicles found") }}

+

{{ _("Try adjusting your search criteria or filters") }}

-
+ {% endfor %}
- {% empty %} -
-
- -

{{ _("No vehicles found") }}

-

{{ _("Try adjusting your search criteria or filters") }}

-
-
- {% endfor %}
-
-
-
- {% if is_paginated %} {% include 'partials/pagination.html' %} {% endif %} +
+
+ {% if is_paginated %} {% include 'partials/pagination.html' %} {% endif %} +
-
- {% endblock %} {% block customJS %} +{% endblock %} {% block customJS %} - {% endblock customJS %} +{% endblock customJS %}
diff --git a/templates/inventory/list.html b/templates/inventory/list.html index 0df8ddf3..d229b914 100644 --- a/templates/inventory/list.html +++ b/templates/inventory/list.html @@ -4,80 +4,80 @@ {% load custom_filters %} {% block content %} -
-
+
+
-
-
-
-

- {% trans "Inventory Ordered" %} -

-
-
- {% if inventory_ordered %} -
- {% inventory_table inventory_ordered %} -
- {% else %} -
- -

{% trans "No inventory in ordered status." %}

-
- {% endif %} +
+
+
+

+ {% trans "Inventory Ordered" %} +

+
+
+ {% if inventory_ordered %} +
+ {% inventory_table inventory_ordered %} +
+ {% else %} +
+ +

{% trans "No inventory in ordered status." %}

+
+ {% endif %} +
-
-
-
-
-

- {% trans "Inventory In Transit" %} -

-
-
- {% if inventory_in_transit %} -
- {% inventory_table inventory_in_transit %} -
- {% else %} -
- -

{% trans "No inventory in transit." %}

-
- {% endif %} +
+
+
+

+ {% trans "Inventory In Transit" %} +

+
+
+ {% if inventory_in_transit %} +
+ {% inventory_table inventory_in_transit %} +
+ {% else %} +
+ +

{% trans "No inventory in transit." %}

+
+ {% endif %} +
-
-
-
-
-

- {% trans "Inventory Received" %} -

-
-
- {% if inventory_received %} -
- {% inventory_table inventory_received %} -
- {% else %} -
- -

{% trans "No inventory in received status." %}

-
- {% endif %} +
+
+
+

+ {% trans "Inventory Received" %} +

+
+
+ {% if inventory_received %} +
+ {% inventory_table inventory_received %} +
+ {% else %} +
+ +

{% trans "No inventory in received status." %}

+
+ {% endif %} +
-
-
-
+
+
+
-
{% endblock %} \ No newline at end of file diff --git a/templates/sales/estimates/sale_order_form1.html b/templates/sales/estimates/sale_order_form1.html index 55a747ee..5869b419 100644 --- a/templates/sales/estimates/sale_order_form1.html +++ b/templates/sales/estimates/sale_order_form1.html @@ -128,64 +128,64 @@
-
+
-
- {{form.status|as_crispy_field}} -
- +
+ {{form.status|as_crispy_field}}
+
+
-
-

- Financial Details -

-
+
+

+ Financial Details +

+
-
-

- Delivery Information -

+
+

+ Delivery Information +

-
+
-
- {{form.order_date|as_crispy_field}} -
-
- {{form.expected_delivery_date|as_crispy_field}} -
- +
+ {{form.order_date|as_crispy_field}}
+
+ {{form.expected_delivery_date|as_crispy_field}} +
+ +
-
- - -
+
+ +
+
-
-
- - Cancel - -
+
+
+ + Cancel + +
- -
+
- -
+
+
+
diff --git a/templates/sales/saleorder_detail.html b/templates/sales/saleorder_detail.html index 27ee1d7f..81b5e866 100644 --- a/templates/sales/saleorder_detail.html +++ b/templates/sales/saleorder_detail.html @@ -5,265 +5,265 @@ {% block title %}{{ page_title }} - {{ sale_order.formatted_order_id }}{% endblock %} {% block content %} -
-
-
-

- {% trans "Sales Order" %} #{{ sale_order.formatted_order_id }} - - {{ status_choices|get_item:sale_order.status }} - -

-
+
+
+
+

+ {% trans "Sales Order" %} #{{ sale_order.formatted_order_id }} + + {{ status_choices|get_item:sale_order.status }} + +

+
-
+
-
-
-

{% trans "Customer Information" %}

-

- {% trans "Name" %}: {{ sale_order.full_name }}
- {% if sale_order.customer %} - {% trans "Contact" %}: {{ sale_order.customer.phone_number }}
- {% trans "Email" %}: {{ sale_order.customer.email }} - {% endif %} -

-
- -
-

{% trans "Order Details" %}

-

- {% trans "Order Date" %}: {{ sale_order.order_date|date }}
- {% trans "Dealer" %}: {{ sale_order.dealer.name }}
- {% trans "Created By" %}: {{ sale_order.created_by }} -

-
-
- - - {% if sale_order.estimate %} -
-
-

{% trans "Estimate Information" %}

-
-
-
-
-

- {% trans "Estimate Number" %}: {{ sale_order.estimate.estimate_number }}
- {% trans "Date" %}: {{ sale_order.estimate.created|date }}
- {% trans "Status" %}: {{ sale_order.estimate.get_status_display }} -

-
-
- -
-
- {% if sale_order.estimate.notes %} -
- {% trans "Notes" %}: -
{{ sale_order.estimate.notes|linebreaks }}
-
- {% endif %} -
-
-
-
- {% endif %} - - - {% if sale_order.invoice %} -
-
-

{% trans "Invoice Information" %}

-
-
-
-
-

- {% trans "Invoice Number" %}: {{ sale_order.invoice.invoice_number }}
- {% trans "Date" %}: {{ sale_order.invoice.created|date }}
- {% trans "Status" %}: - - {{ sale_order.invoice.invoice_status|capfirst }} - -

-
-
-

- - - - - - - - - - - - - - - - - - - -
{% trans "Amount Paid" %}:{{CURRENCY}}{{ sale_order.invoice.amount_paid|floatformat:2 }}
{% trans "Balance Due" %}:{{CURRENCY}}{{ sale_order.invoice.amount_due|floatformat:2 }}
{% trans "Amount Unearned" %}:{{CURRENCY}}{{ sale_order.invoice.amount_unearned|floatformat:2 }}
{% trans "Amount Receivable" %}:{{CURRENCY}}{{ sale_order.invoice.amount_receivable|floatformat:2 }}
-

-
-
- {% if sale_order.invoice.notes %} -
- {% trans "Notes" %}: -
{{ sale_order.invoice.notes|linebreaks }}
-
- {% endif %} -
-
-
-
- {% endif %} - - - {% if sale_order.invoice.ledger %} -
-
-

{% trans "Ledger Information" %}

-
-
-
-
-

- {% trans "Ledger Number" %}: {{ sale_order.invoice.ledger }}
- {% trans "Date" %}: {{ sale_order.invoice.ledger.created|date }}
-

-
-
-

- - - {% for je in sale_order.invoice.ledger.journal_entries.all %} - - - - {% endfor %} - -
{{je}}
-

-
-
- {% if sale_order.invoice.notes %} -
- {% trans "Notes" %}: -
{{ sale_order.invoice.notes|linebreaks }}
-
- {% endif %} -
-
-
-
- {% endif %} - - - {% if sale_order.expected_delivery_date or sale_order.actual_delivery_date %} -
-
-

{% trans "Delivery Information" %}

-

- {% if sale_order.expected_delivery_date %} - {% trans "Expected Delivery" %}: {{ sale_order.expected_delivery_date|date:"DATE_FORMAT" }}
- {% endif %} - {% if sale_order.actual_delivery_date %} - {% trans "Actual Delivery" %}: {{ sale_order.actual_delivery_date|date:"DATETIME_FORMAT" }} - {% endif %} -

-
-
- {% endif %} - - - {% if sale_order.cars %} -
-
-

{% trans "Vehicles" %}

-
- - - - - - - - - - - - {% for car in sale_order.cars %} - - - - - - - - {% endfor %} - -
{% trans "Make" %}{% trans "Model" %}{% trans "Year" %}{% trans "VIN" %}{% trans "Price" %}
{{ car.id_car_make }}{{ car.id_car_model }}{{ car.year }}{{ car.vin }}{{CURRENCY}}{{ car.finances.selling_price|floatformat:2 }}
-
-
-
- {% endif %} - - - {% if is_cancelled %} -
-
-
-

{% trans "Order Cancelled" %}

+
+
+

{% trans "Customer Information" %}

- {% trans "Cancellation Date" %}: {{ sale_order.cancelled_date|date:"DATETIME_FORMAT" }}
- {% trans "Reason" %}: {{ sale_order.cancellation_reason }} + {% trans "Name" %}: {{ sale_order.full_name }}
+ {% if sale_order.customer %} + {% trans "Contact" %}: {{ sale_order.customer.phone_number }}
+ {% trans "Email" %}: {{ sale_order.customer.email }} + {% endif %} +

+
+ +
+

{% trans "Order Details" %}

+

+ {% trans "Order Date" %}: {{ sale_order.order_date|date }}
+ {% trans "Dealer" %}: {{ sale_order.dealer.name }}
+ {% trans "Created By" %}: {{ sale_order.created_by }}

-
- {% endif %} - - {% if sale_order.comments %} -
-
-

{% trans "Comments" %}

-
-
- {{ sale_order.comments|linebreaks }} + + {% if sale_order.estimate %} +
+
+

{% trans "Estimate Information" %}

+
+
+
+
+

+ {% trans "Estimate Number" %}: {{ sale_order.estimate.estimate_number }}
+ {% trans "Date" %}: {{ sale_order.estimate.created|date }}
+ {% trans "Status" %}: {{ sale_order.estimate.get_status_display }} +

+
+
+ +
+
+ {% if sale_order.estimate.notes %} +
+ {% trans "Notes" %}: +
{{ sale_order.estimate.notes|linebreaks }}
+
+ {% endif %} +
+
-
-
- {% endif %} -
+ {% endif %} - + +
-
{% endblock %} \ No newline at end of file