change
This commit is contained in:
parent
7dd5791d14
commit
bada43ba64
22
.dockerignore
Normal file
22
.dockerignore
Normal file
@ -0,0 +1,22 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.log
|
||||
*.sqlite3
|
||||
*.db
|
||||
migrations/
|
||||
media/
|
||||
static/
|
||||
node_modules/
|
||||
venv/
|
||||
env/
|
||||
.git/
|
||||
.gitignore
|
||||
.DS_Store
|
||||
docker-compose.yml
|
||||
README.md
|
||||
car*.json
|
||||
.vscode
|
||||
.idea
|
||||
*/migrations/*
|
||||
*/migrations/
|
||||
inventory/migrations/
|
||||
39
Dockerfile
Normal file
39
Dockerfile
Normal file
@ -0,0 +1,39 @@
|
||||
# Use an official Python image as a base
|
||||
FROM python:3.11.11-slim-bullseye
|
||||
|
||||
# Set the working directory to /app
|
||||
WORKDIR /app
|
||||
|
||||
# Create a new user and group
|
||||
RUN groupadd -r appgroup
|
||||
RUN useradd -r -g appgroup -G appgroup -m -d /app -s /bin/false appuser
|
||||
|
||||
# Copy the requirements file
|
||||
COPY requirements.txt .
|
||||
|
||||
# Install the dependencies
|
||||
RUN pip install -r requirements.txt
|
||||
RUN apt-get update && apt-get install -y libgl1
|
||||
RUN apt-get update && apt-get install -y libglib2.0-dev
|
||||
RUN apt-get update && apt-get install -y libzbar0
|
||||
|
||||
# Copy the application code
|
||||
COPY . .
|
||||
|
||||
# Expose the port
|
||||
EXPOSE 8000
|
||||
|
||||
# Copy the entrypoint script
|
||||
COPY entrypoint.sh /app/entrypoint.sh
|
||||
|
||||
# Make the script executable
|
||||
RUN chmod +x /app/entrypoint.sh
|
||||
|
||||
# Change ownership of the app directory to the new user
|
||||
RUN chown -R appuser:appgroup /app
|
||||
|
||||
RUN find /app -path "*/migrations/*.py" -not -name "__init__.py" -delete
|
||||
RUN find /app -path "*/migrations/*.pyc" -delete
|
||||
|
||||
# Set the entrypoint to execute the script as the new user
|
||||
ENTRYPOINT ["sh", "-c", "python3 manage.py makemigrations && python3 manage.py migrate && python3 manage.py collectstatic --no-input && python3 manage.py runserver 0.0.0.0:8000"]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
31
docker-compose.yml
Normal file
31
docker-compose.yml
Normal file
@ -0,0 +1,31 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgres
|
||||
restart: always
|
||||
environment:
|
||||
- POSTGRES_DB=haikal_db
|
||||
- POSTGRES_USER=haikal_user
|
||||
- POSTGRES_PASSWORD=haikal_pass
|
||||
healthcheck:
|
||||
test: ["CMD", "pg_isready", "-U", "haikal_user", "-d", "haikal_db"]
|
||||
interval: 1m30s
|
||||
timeout: 30s
|
||||
retries: 5
|
||||
start_period: 30s
|
||||
web:
|
||||
build: .
|
||||
command: python manage.py runserver 0.0.0.0:8000
|
||||
environment:
|
||||
- DATABASE_HOST=db
|
||||
- DATABASE_PORT=5432
|
||||
- POSTGRES_DB=haikal_db
|
||||
- POSTGRES_USER=haikal_user
|
||||
- POSTGRES_PASSWORD=haikal_pass
|
||||
volumes:
|
||||
- .:/app
|
||||
ports:
|
||||
- "8000:8000"
|
||||
depends_on:
|
||||
- db
|
||||
5
entrypoint.sh
Normal file
5
entrypoint.sh
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
python manage.py migrate
|
||||
python manage.py collectstatic --no-input
|
||||
python manage.py runserver 0.0.0.0:8000
|
||||
@ -1,4 +1,4 @@
|
||||
# Generated by Django 5.1.5 on 2025-01-30 11:28
|
||||
# Generated by Django 5.1.6 on 2025-03-06 01:43
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Generated by Django 5.1.5 on 2025-01-30 11:28
|
||||
# Generated by Django 5.1.6 on 2025-03-06 01:43
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,5 +1,6 @@
|
||||
# Generated by Django 5.1.5 on 2025-01-30 11:28
|
||||
# Generated by Django 5.1.6 on 2025-03-06 01:43
|
||||
|
||||
import datetime
|
||||
import django.db.models.deletion
|
||||
import inventory.mixins
|
||||
import inventory.models
|
||||
@ -14,8 +15,12 @@ class Migration(migrations.Migration):
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('appointment', '__first__'),
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
('contenttypes', '0002_remove_content_type_name'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_ACCOUNT_MODEL),
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_CUSTOMER_MODEL),
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_ENTITY_MODEL),
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_ESTIMATE_MODEL),
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_INVOICE_MODEL),
|
||||
@ -94,25 +99,6 @@ class Migration(migrations.Migration):
|
||||
'verbose_name_plural': 'payments',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SubscriptionPlan',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(help_text='Name of the subscription plan', max_length=100, unique=True)),
|
||||
('description', models.TextField()),
|
||||
('price', models.DecimalField(decimal_places=2, max_digits=10)),
|
||||
('max_users', models.PositiveIntegerField(default=1, help_text='Maximum number of users allowed')),
|
||||
('max_inventory_size', models.PositiveIntegerField(default=50, help_text='Maximum number of cars in inventory')),
|
||||
('support_level', models.CharField(choices=[('basic', 'Basic Support'), ('priority', 'Priority Support'), ('dedicated', 'Dedicated Support')], default='basic', help_text='Level of support provided', max_length=50)),
|
||||
('custom_features', models.JSONField(blank=True, help_text='Additional features specific to this plan', null=True)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Subscription Plan',
|
||||
'verbose_name_plural': 'Subscription Plans',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='VatRate',
|
||||
fields=[
|
||||
@ -122,23 +108,6 @@ class Migration(migrations.Migration):
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Activity',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('object_id', models.PositiveIntegerField()),
|
||||
('activity_type', models.CharField(choices=[('call', 'Call'), ('sms', 'SMS'), ('email', 'Email'), ('whatsapp', 'WhatsApp'), ('visit', 'Visit'), ('add_car', 'Add Car'), ('reserve_car', 'Reserve 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.CASCADE, to='contenttypes.contenttype')),
|
||||
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='activities_created', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Activity',
|
||||
'verbose_name_plural': 'Activities',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='AdditionalServices',
|
||||
fields=[
|
||||
@ -168,6 +137,7 @@ class Migration(migrations.Migration):
|
||||
('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')),
|
||||
('vendor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='cars', to=settings.DJANGO_LEDGER_VENDOR_MODEL, verbose_name='Vendor')),
|
||||
('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')),
|
||||
],
|
||||
@ -242,10 +212,10 @@ class Migration(migrations.Migration):
|
||||
('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(max_length=1, verbose_name='Text 2')),
|
||||
('text3', models.CharField(max_length=1, verbose_name='Text 3')),
|
||||
('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.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='registrations', to='inventory.car', verbose_name='Car')),
|
||||
('car', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='registrations', to='inventory.car', verbose_name='Car')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Registration',
|
||||
@ -362,6 +332,15 @@ class Migration(migrations.Migration):
|
||||
('objects', inventory.models.DealerUserManager()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CustomGroup',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=100)),
|
||||
('group', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='auth.group', verbose_name='')),
|
||||
('dealer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='groups', to='inventory.dealer')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Customer',
|
||||
fields=[
|
||||
@ -378,6 +357,7 @@ class Migration(migrations.Migration):
|
||||
('address', models.CharField(blank=True, max_length=200, null=True, verbose_name='Address')),
|
||||
('created', models.DateTimeField(auto_now_add=True, verbose_name='Created')),
|
||||
('updated', models.DateTimeField(auto_now=True, verbose_name='Updated')),
|
||||
('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={
|
||||
@ -432,19 +412,78 @@ class Migration(migrations.Migration):
|
||||
name='dealer',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inventory.dealer', verbose_name='Dealer'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Activity',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('object_id', models.PositiveIntegerField()),
|
||||
('activity_type', models.CharField(choices=[('call', 'Call'), ('sms', 'SMS'), ('email', 'Email'), ('whatsapp', 'WhatsApp'), ('visit', 'Visit'), ('add_car', 'Add Car'), ('sale_car', 'Sale Car'), ('reserve_car', 'Reserve Car'), ('transfer_car', 'Transfer Car'), ('remove_car', 'Remove Car'), ('create_quotation', 'Create Quotation'), ('cancel_quotation', 'Cancel Quotation'), ('create_order', 'Create Order'), ('cancel_order', 'Cancel Order'), ('create_invoice', 'Create Invoice'), ('cancel_invoice', 'Cancel Invoice')], max_length=50, verbose_name='Activity Type')),
|
||||
('notes', models.TextField(blank=True, null=True, verbose_name='Notes')),
|
||||
('created', models.DateTimeField(auto_now_add=True, verbose_name='Created')),
|
||||
('updated', models.DateTimeField(auto_now=True, verbose_name='Updated')),
|
||||
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='contenttypes.contenttype')),
|
||||
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='activities_created_by', to=settings.AUTH_USER_MODEL)),
|
||||
('dealer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='inventory.dealer')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Activity',
|
||||
'verbose_name_plural': 'Activities',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DealerSettings',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('additional_info', models.JSONField(blank=True, default=dict, null=True)),
|
||||
('bill_cash_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bill_cash', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('bill_prepaid_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bill_prepaid', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('bill_unearned_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bill_unearned', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('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=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('invoice_prepaid_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='invoice_prepaid', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('invoice_unearned_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='invoice_unearned', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Email',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('object_id', models.PositiveIntegerField()),
|
||||
('from_email', models.TextField(blank=True, null=True, verbose_name='From Email')),
|
||||
('to_email', models.TextField(blank=True, null=True, verbose_name='To Email')),
|
||||
('subject', models.TextField(blank=True, null=True, verbose_name='Subject')),
|
||||
('message', models.TextField(blank=True, null=True, verbose_name='Message')),
|
||||
('status', models.CharField(choices=[('SENT', 'Sent'), ('FAILED', 'Failed'), ('DELIVERED', 'Delivered'), ('OPEN', 'Open'), ('DRAFT', 'Draft')], default='OPEN', max_length=20, verbose_name='Status')),
|
||||
('created', models.DateTimeField(auto_now_add=True, verbose_name='Created')),
|
||||
('updated', models.DateTimeField(auto_now=True, verbose_name='Updated')),
|
||||
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
|
||||
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='emails_created', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Email',
|
||||
'verbose_name_plural': 'Emails',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Lead',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('first_name', models.CharField(max_length=50, verbose_name='First Name')),
|
||||
('last_name', models.CharField(max_length=50, verbose_name='Last Name')),
|
||||
('email', models.EmailField(max_length=254, verbose_name='Email')),
|
||||
('phone_number', phonenumber_field.modelfields.PhoneNumberField(max_length=128, region='SA', verbose_name='Phone Number')),
|
||||
('lead_type', models.CharField(choices=[('customer', 'Customer'), ('organization', 'Organization')], default='customer', max_length=50, verbose_name='Lead Type')),
|
||||
('year', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='Year')),
|
||||
('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')),
|
||||
('city', models.CharField(max_length=50, verbose_name='City')),
|
||||
('crn', models.CharField(blank=True, max_length=10, null=True, unique=True, verbose_name='Commercial Registration Number')),
|
||||
('vrn', models.CharField(blank=True, max_length=15, null=True, unique=True, verbose_name='VAT Registration Number')),
|
||||
('address', models.CharField(max_length=50, verbose_name='address')),
|
||||
('priority', models.CharField(choices=[('low', 'Low'), ('medium', 'Medium'), ('high', 'High')], default='medium', max_length=10, verbose_name='Priority')),
|
||||
('status', models.CharField(choices=[('new', 'New'), ('pending', 'Pending'), ('in_progress', 'In Progress'), ('qualified', 'Qualified'), ('canceled', 'Canceled')], db_index=True, default='new', max_length=50, verbose_name='Status')),
|
||||
('status', models.CharField(choices=[('new', 'New'), ('pending', 'Pending'), ('in_progress', 'In Progress'), ('qualified', 'Qualified'), ('contacted', 'Contacted'), ('converted', 'Converted'), ('canceled', 'Canceled')], db_index=True, default='new', max_length=50, verbose_name='Status')),
|
||||
('created', models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='Created')),
|
||||
('updated', models.DateTimeField(auto_now=True, verbose_name='Updated')),
|
||||
('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='leads', to='inventory.customer')),
|
||||
('customer', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='leads', to=settings.DJANGO_LEDGER_CUSTOMER_MODEL)),
|
||||
('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')),
|
||||
@ -554,6 +593,26 @@ class Migration(migrations.Migration):
|
||||
'ordering': ['-created'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Schedule',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('purpose', models.CharField(choices=[('Product Demo', 'Product Demo'), ('Follow-Up Call', 'Follow-Up Call'), ('Contract Discussion', 'Contract Discussion'), ('Sales Meeting', 'Sales Meeting'), ('Support Call', 'Support Call'), ('Other', 'Other')], max_length=200)),
|
||||
('scheduled_at', models.DateTimeField()),
|
||||
('scheduled_type', models.CharField(choices=[('Call', 'Call'), ('Meeting', 'Meeting'), ('Email', 'Email')], default='Call', max_length=200)),
|
||||
('duration', models.DurationField(default=datetime.timedelta(seconds=300))),
|
||||
('notes', models.TextField(blank=True, null=True)),
|
||||
('status', models.CharField(choices=[('Scheduled', 'Scheduled'), ('Completed', 'Completed'), ('Canceled', 'Canceled')], default='Scheduled', max_length=200)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('customer', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='schedules', to=settings.DJANGO_LEDGER_CUSTOMER_MODEL)),
|
||||
('lead', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='schedules', to='inventory.lead')),
|
||||
('scheduled_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['-scheduled_at'],
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Staff',
|
||||
fields=[
|
||||
@ -561,11 +620,11 @@ class Migration(migrations.Migration):
|
||||
('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=[('manager', 'Manager'), ('inventory', 'Inventory'), ('accountant', 'Accountant'), ('sales', 'Sales'), ('coordinator', 'Coordinator'), ('receptionist', 'Receptionist'), ('agent', 'Agent')], max_length=255, verbose_name='Staff Type')),
|
||||
('staff_type', models.CharField(choices=[('inventory', 'Inventory'), ('accountant', 'Accountant'), ('sales', 'Sales')], max_length=255, verbose_name='Staff Type')),
|
||||
('created', models.DateTimeField(auto_now_add=True, verbose_name='Created')),
|
||||
('updated', models.DateTimeField(auto_now=True, verbose_name='Updated')),
|
||||
('dealer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='staff', to='inventory.dealer')),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='staff', to=settings.AUTH_USER_MODEL)),
|
||||
('staff_member', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='staff', to='appointment.staffmember')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Staff',
|
||||
@ -582,15 +641,17 @@ class Migration(migrations.Migration):
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('stage', models.CharField(choices=[('prospect', 'Prospect'), ('proposal', 'Proposal'), ('negotiation', 'Negotiation'), ('closed_won', 'Closed Won'), ('closed_lost', 'Closed Lost')], max_length=20, verbose_name='Stage')),
|
||||
('status', models.CharField(choices=[('new', 'New'), ('pending', 'Pending'), ('in_progress', 'In Progress'), ('qualified', 'Qualified'), ('canceled', 'Canceled')], default='new', max_length=20, verbose_name='Status')),
|
||||
('status', models.CharField(choices=[('new', 'New'), ('pending', 'Pending'), ('in_progress', 'In Progress'), ('qualified', 'Qualified'), ('contacted', 'Contacted'), ('converted', 'Converted'), ('canceled', 'Canceled')], default='new', max_length=20, verbose_name='Status')),
|
||||
('probability', models.PositiveIntegerField(validators=[inventory.models.validate_probability])),
|
||||
('closing_date', models.DateField(verbose_name='Closing Date')),
|
||||
('closing_date', models.DateField(blank=True, null=True, verbose_name='Closing Date')),
|
||||
('created', models.DateTimeField(auto_now_add=True, verbose_name='Created')),
|
||||
('updated', models.DateTimeField(auto_now=True, verbose_name='Updated')),
|
||||
('closed', models.BooleanField(default=False, verbose_name='Closed')),
|
||||
('car', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='inventory.car', verbose_name='Car')),
|
||||
('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='opportunities', to='inventory.customer')),
|
||||
('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='opportunities', to=settings.DJANGO_LEDGER_CUSTOMER_MODEL)),
|
||||
('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=settings.DJANGO_LEDGER_ESTIMATE_MODEL)),
|
||||
('lead', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='opportunity', to='inventory.lead')),
|
||||
('staff', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='owner', to='inventory.staff', verbose_name='Owner')),
|
||||
],
|
||||
options={
|
||||
@ -602,8 +663,8 @@ class Migration(migrations.Migration):
|
||||
name='LeadStatusHistory',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('old_status', models.CharField(choices=[('new', 'New'), ('pending', 'Pending'), ('in_progress', 'In Progress'), ('qualified', 'Qualified'), ('canceled', 'Canceled')], max_length=50, verbose_name='Old Status')),
|
||||
('new_status', models.CharField(choices=[('new', 'New'), ('pending', 'Pending'), ('in_progress', 'In Progress'), ('qualified', 'Qualified'), ('canceled', 'Canceled')], max_length=50, verbose_name='New Status')),
|
||||
('old_status', models.CharField(choices=[('new', 'New'), ('pending', 'Pending'), ('in_progress', 'In Progress'), ('qualified', 'Qualified'), ('contacted', 'Contacted'), ('converted', 'Converted'), ('canceled', 'Canceled')], max_length=50, verbose_name='Old Status')),
|
||||
('new_status', models.CharField(choices=[('new', 'New'), ('pending', 'Pending'), ('in_progress', 'In Progress'), ('qualified', 'Qualified'), ('contacted', 'Contacted'), ('converted', 'Converted'), ('canceled', 'Canceled')], 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')),
|
||||
@ -618,40 +679,6 @@ class Migration(migrations.Migration):
|
||||
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='Subscription',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('start_date', models.DateField(help_text='Date when the subscription starts')),
|
||||
('end_date', models.DateField(help_text='Date when the subscription ends')),
|
||||
('is_active', models.BooleanField(default=True)),
|
||||
('billing_cycle', models.CharField(choices=[('monthly', 'Monthly'), ('annual', 'Annual')], default='monthly', help_text='Billing cycle for the subscription', max_length=10)),
|
||||
('last_payment_date', models.DateField(blank=True, help_text='Date of the last payment made', null=True)),
|
||||
('next_payment_date', models.DateField(blank=True, help_text='Date of the next payment due', null=True)),
|
||||
('plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subscriptions', to='inventory.subscriptionplan')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Subscription',
|
||||
'verbose_name_plural': 'Subscriptions',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SubscriptionUser',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('subscription', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inventory.subscription')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Subscription User',
|
||||
'verbose_name_plural': 'Subscription Users',
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='subscription',
|
||||
name='users',
|
||||
field=models.ManyToManyField(through='inventory.SubscriptionUser', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserActivityLog',
|
||||
fields=[
|
||||
@ -704,11 +731,23 @@ class Migration(migrations.Migration):
|
||||
'unique_together': {('car', 'reserved_until')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DealersMake',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('added_at', models.DateTimeField(auto_now_add=True)),
|
||||
('car_make', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='car_dealers', to='inventory.carmake')),
|
||||
('dealer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='dealer_makes', to='inventory.dealer')),
|
||||
],
|
||||
options={
|
||||
'unique_together': {('dealer', 'car_make')},
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='CarColors',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('car', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='colors', to='inventory.car')),
|
||||
('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')),
|
||||
],
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
# Generated by Django 5.1.5 on 2025-02-04 04:37
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='carregistration',
|
||||
name='car',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='registrations', to='inventory.car', verbose_name='Car'),
|
||||
),
|
||||
]
|
||||
@ -1,21 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-04 09:34
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_CUSTOMER_MODEL),
|
||||
('inventory', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='lead',
|
||||
name='customer',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='leads', to=settings.DJANGO_LEDGER_CUSTOMER_MODEL),
|
||||
),
|
||||
]
|
||||
@ -1,46 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-04 11:38
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import phonenumber_field.modelfields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_CUSTOMER_MODEL),
|
||||
('inventory', '0002_alter_lead_customer'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='lead',
|
||||
name='email',
|
||||
field=models.EmailField(default='x@tenhal.sa', max_length=254, verbose_name='Email'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='lead',
|
||||
name='first_name',
|
||||
field=models.CharField(default='test', max_length=50, verbose_name='First Name'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='lead',
|
||||
name='last_name',
|
||||
field=models.CharField(default='test', max_length=50, verbose_name='Last Name'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='lead',
|
||||
name='phone_number',
|
||||
field=phonenumber_field.modelfields.PhoneNumberField(default='056523656', max_length=128, region='SA', verbose_name='Phone Number'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='lead',
|
||||
name='customer',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='leads', to=settings.DJANGO_LEDGER_CUSTOMER_MODEL),
|
||||
),
|
||||
]
|
||||
@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-04 14:21
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0003_lead_email_lead_first_name_lead_last_name_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='lead',
|
||||
name='city',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='lead',
|
||||
name='address',
|
||||
field=models.CharField(default='', max_length=50, verbose_name='address'),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
@ -1,33 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-04 15:15
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_CUSTOMER_MODEL),
|
||||
('inventory', '0004_remove_lead_city_lead_address'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Schedule',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('purpose', models.CharField(max_length=200)),
|
||||
('scheduled_at', models.DateTimeField()),
|
||||
('notes', models.TextField(blank=True, null=True)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='schedules', to=settings.DJANGO_LEDGER_CUSTOMER_MODEL)),
|
||||
('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='inventory.staff')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['-scheduled_at'],
|
||||
},
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-04 15:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0005_schedule'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='schedule',
|
||||
name='purpose',
|
||||
field=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),
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-04 15:36
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0006_alter_schedule_purpose'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='schedule',
|
||||
name='scheduled_type',
|
||||
field=models.CharField(choices=[('Call', 'Call'), ('Meeting', 'Meeting'), ('Email', 'Email')], default='Call', max_length=200),
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-05 09:43
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0007_schedule_scheduled_type'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='schedule',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('Scheduled', 'Scheduled'), ('Completed', 'Completed'), ('Canceled', 'Canceled')], default='Scheduled', max_length=200),
|
||||
),
|
||||
]
|
||||
@ -1,21 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-05 10:00
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_CUSTOMER_MODEL),
|
||||
('inventory', '0008_schedule_status'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='opportunity',
|
||||
name='customer',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='opportunities', to=settings.DJANGO_LEDGER_CUSTOMER_MODEL),
|
||||
),
|
||||
]
|
||||
@ -1,27 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-05 10:05
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0009_alter_opportunity_customer'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='lead',
|
||||
name='id_car_make',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='lead',
|
||||
name='id_car_model',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='lead',
|
||||
name='car',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='inventory.car', verbose_name='Car'),
|
||||
),
|
||||
]
|
||||
@ -1,25 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-05 10:17
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_CUSTOMER_MODEL),
|
||||
('inventory', '0010_remove_lead_id_car_make_remove_lead_id_car_model_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='lead',
|
||||
name='year',
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='schedule',
|
||||
name='customer',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='schedules', to=settings.DJANGO_LEDGER_CUSTOMER_MODEL),
|
||||
),
|
||||
]
|
||||
@ -1,14 +0,0 @@
|
||||
# Generated by Django 5.1.5 on 2025-02-06 08:51
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0002_alter_carregistration_car'),
|
||||
('inventory', '0011_remove_lead_year_alter_schedule_customer'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
||||
@ -1,14 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-06 10:08
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0002_alter_carregistration_car'),
|
||||
('inventory', '0011_remove_lead_year_alter_schedule_customer'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
||||
@ -1,23 +0,0 @@
|
||||
# Generated by Django 5.1.5 on 2025-02-07 01:25
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0012_merge_20250206_1151'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='carregistration',
|
||||
name='text2',
|
||||
field=models.CharField(blank=True, max_length=1, null=True, verbose_name='Text 2'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='carregistration',
|
||||
name='text3',
|
||||
field=models.CharField(blank=True, max_length=1, null=True, verbose_name='Text 3'),
|
||||
),
|
||||
]
|
||||
@ -1,33 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-06 12:07
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0013_alter_carregistration_text2_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='lead',
|
||||
name='car',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='lead',
|
||||
name='id_car_make',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='inventory.carmake', verbose_name='Make'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='lead',
|
||||
name='id_car_model',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='inventory.carmodel', verbose_name='Model'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='lead',
|
||||
name='year',
|
||||
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='Year'),
|
||||
),
|
||||
]
|
||||
@ -1,14 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-09 08:16
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0012_merge_20250206_1308'),
|
||||
('inventory', '0014_remove_lead_car_lead_id_car_make_lead_id_car_model_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
||||
@ -1,19 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-09 08:23
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0015_merge_20250209_1116'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='schedule',
|
||||
name='duration',
|
||||
field=models.DurationField(default=datetime.timedelta(seconds=300)),
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-09 11:36
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0016_schedule_duration'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='car',
|
||||
name='hash',
|
||||
field=models.CharField(blank=True, max_length=64, null=True, verbose_name='Hash'),
|
||||
),
|
||||
]
|
||||
@ -1,22 +0,0 @@
|
||||
# Generated by Django 5.1.5 on 2025-02-11 00:23
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0017_car_hash'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='customer',
|
||||
name='user',
|
||||
field=models.OneToOneField(default=4, on_delete=django.db.models.deletion.CASCADE, related_name='customer_profile', to=settings.AUTH_USER_MODEL),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
@ -1,19 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-12 10:26
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0018_customer_user'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='opportunity',
|
||||
name='lead',
|
||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='inventory.lead'),
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-12 10:32
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0019_opportunity_lead'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='opportunity',
|
||||
name='closing_date',
|
||||
field=models.DateField(blank=True, null=True, verbose_name='Closing Date'),
|
||||
),
|
||||
]
|
||||
@ -1,19 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-12 10:37
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0020_alter_opportunity_closing_date'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='opportunity',
|
||||
name='lead',
|
||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='opportunity', to='inventory.lead'),
|
||||
),
|
||||
]
|
||||
@ -1,21 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-12 14:09
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_ESTIMATE_MODEL),
|
||||
('inventory', '0021_alter_opportunity_lead'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='opportunity',
|
||||
name='estimate',
|
||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='opportunity', to=settings.DJANGO_LEDGER_ESTIMATE_MODEL),
|
||||
),
|
||||
]
|
||||
@ -1,36 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-13 09:01
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('contenttypes', '0002_remove_content_type_name'),
|
||||
('inventory', '0022_opportunity_estimate'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Email',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('object_id', models.PositiveIntegerField()),
|
||||
('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')),
|
||||
('body', models.TextField(blank=True, null=True, verbose_name='Body')),
|
||||
('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',
|
||||
},
|
||||
),
|
||||
]
|
||||
@ -1,22 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-13 09:03
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0023_email'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='email',
|
||||
name='body',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='email',
|
||||
name='message',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='Message'),
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-13 09:12
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0024_remove_email_body_email_message'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='email',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('SENT', 'Sent'), ('FAILED', 'Failed'), ('DELIVERED', 'Delivered'), ('OPEN', 'Open'), ('DRAFT', 'Draft')], default='OPEN', max_length=20, verbose_name='Status'),
|
||||
),
|
||||
]
|
||||
@ -1,29 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-17 08:54
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0025_email_status'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='CarHistory',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('event_date', models.DateField()),
|
||||
('event_type', models.CharField(choices=[('PURCHASE', 'Purchase'), ('SALE', 'Sale'), ('TRANSFER', 'Transfer'), ('ACCIDENT', 'Accident'), ('MAINTENANCE', 'Maintenance'), ('SERVICE', 'Service'), ('OTHER', 'Other')], max_length=50)),
|
||||
('description', models.TextField(blank=True, null=True)),
|
||||
('mileage', models.IntegerField(blank=True, null=True)),
|
||||
('cost', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)),
|
||||
('car', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='history', to='inventory.car')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['-event_date'],
|
||||
},
|
||||
),
|
||||
]
|
||||
@ -1,20 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-17 08:57
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0026_carhistory'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='carhistory',
|
||||
name='dealer',
|
||||
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='history', to='inventory.dealer'),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-17 09:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0027_carhistory_dealer'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='carhistory',
|
||||
name='additional_info',
|
||||
field=models.JSONField(blank=True, default=dict, null=True, verbose_name='Car History Additional Info'),
|
||||
),
|
||||
]
|
||||
@ -1,21 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-17 09:03
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0028_carhistory_additional_info'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='carhistory',
|
||||
name='cost',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='carhistory',
|
||||
name='mileage',
|
||||
),
|
||||
]
|
||||
@ -1,21 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-17 09:50
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0029_remove_carhistory_cost_remove_carhistory_mileage'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='activity_type',
|
||||
field=models.CharField(choices=[('call', 'Call'), ('sms', 'SMS'), ('email', 'Email'), ('whatsapp', 'WhatsApp'), ('visit', 'Visit'), ('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'),
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='CarHistory',
|
||||
),
|
||||
]
|
||||
@ -1,33 +0,0 @@
|
||||
# Generated by Django 5.1.5 on 2025-02-17 14:05
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('contenttypes', '0002_remove_content_type_name'),
|
||||
('inventory', '0030_alter_activity_activity_type_delete_carhistory'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='activity',
|
||||
name='dealer',
|
||||
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='inventory.dealer'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='content_type',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='contenttypes.contenttype'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='activity',
|
||||
name='created_by',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='activities_created_by', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@ -1,19 +0,0 @@
|
||||
# Generated by Django 5.1.6 on 2025-02-17 17:40
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0031_activity_dealer_alter_activity_content_type_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='carcolors',
|
||||
name='car',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='colors', to='inventory.car'),
|
||||
),
|
||||
]
|
||||
@ -1,32 +0,0 @@
|
||||
# Generated by Django 5.1.6 on 2025-02-19 05:25
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
# ('appointment', '0002_alter_workinghours_options'),
|
||||
('inventory', '0032_alter_carcolors_car'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='staff',
|
||||
name='user',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='staff',
|
||||
name='staff_member',
|
||||
field=models.OneToOneField(default=5, on_delete=django.db.models.deletion.CASCADE, related_name='staff', to='appointment.staffmember'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='schedule',
|
||||
name='scheduled_by',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@ -1,38 +0,0 @@
|
||||
# Generated by Django 5.1.6 on 2025-02-20 01:29
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0033_remove_staff_user_staff_staff_member_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='subscription',
|
||||
name='plan',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='subscription',
|
||||
name='users',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='subscriptionuser',
|
||||
name='subscription',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='subscriptionuser',
|
||||
name='user',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='SubscriptionPlan',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='Subscription',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='SubscriptionUser',
|
||||
),
|
||||
]
|
||||
@ -1,25 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-20 08:16
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
# ('inventory', '0037_alter_schedule_scheduled_type'),
|
||||
('inventory', '0034_remove_subscription_plan_remove_subscription_users_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='CustomGroup',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=100)),
|
||||
('dealer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inventory.dealer')),
|
||||
('group', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='auth.group', verbose_name='')),
|
||||
],
|
||||
),
|
||||
]
|
||||
@ -1,19 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-20 08:17
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0038_customgroup'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='customgroup',
|
||||
name='dealer',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='groups', to='inventory.dealer'),
|
||||
),
|
||||
]
|
||||
@ -1,33 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-23 14:31
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_ACCOUNT_MODEL),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('inventory', '0039_alter_customgroup_dealer'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='UserSettings',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('language', models.CharField(choices=[('en', 'English'), ('ar', 'Arabic')], default='ar', max_length=20)),
|
||||
('theme', models.CharField(choices=[('default', 'Default'), ('dark', 'Dark')], default='default', max_length=20)),
|
||||
('additional_info', models.JSONField(default=dict)),
|
||||
('bill_cash_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bill_ca', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('bill_payable_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bill_payable', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('bill_prepaid_expense_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bill_prepaid_expense', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('invoice_cash_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='invoice_ca', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('invoice_payable_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='invoice_payable', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('invoice_prepaid_expense_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='invoice_prepaid_expense', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-23 14:56
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0040_usersettings'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='usersettings',
|
||||
name='additional_info',
|
||||
field=models.JSONField(blank=True, default=dict, null=True),
|
||||
),
|
||||
]
|
||||
@ -1,21 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-23 15:34
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('inventory', '0041_alter_usersettings_additional_info'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='usersettings',
|
||||
name='user',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='settings', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@ -1,21 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-23 16:23
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('inventory', '0042_alter_usersettings_user'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='usersettings',
|
||||
name='user',
|
||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='settings', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@ -1,33 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-23 16:31
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_ACCOUNT_MODEL),
|
||||
('inventory', '0043_alter_usersettings_user'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='DealerSettings',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('additional_info', models.JSONField(blank=True, default=dict, null=True)),
|
||||
('bill_cash_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bill_ca', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('bill_payable_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bill_payable', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('bill_prepaid_expense_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bill_prepaid_expense', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('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_ca', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('invoice_payable_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='invoice_payable', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
('invoice_prepaid_expense_account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='invoice_prepaid_expense', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='UserSettings',
|
||||
),
|
||||
]
|
||||
@ -1,39 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-24 09:01
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_ACCOUNT_MODEL),
|
||||
('inventory', '0044_dealersettings_delete_usersettings'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='dealersettings',
|
||||
name='invoice_payable_account',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='dealersettings',
|
||||
name='invoice_prepaid_expense_account',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dealersettings',
|
||||
name='invoice_prepaid_account',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='invoice_prepaid', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dealersettings',
|
||||
name='invoice_unearned_account',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='invoice_unearned', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='dealersettings',
|
||||
name='invoice_cash_account',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='invoice_cash', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL),
|
||||
),
|
||||
]
|
||||
@ -1,25 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-24 09:10
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_ACCOUNT_MODEL),
|
||||
('inventory', '0045_remove_dealersettings_invoice_payable_account_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='dealersettings',
|
||||
name='invoice_prepaid_account',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dealersettings',
|
||||
name='invoice_recivable_account',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='invoice_recivable', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL),
|
||||
),
|
||||
]
|
||||
@ -1,25 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-24 09:11
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_ACCOUNT_MODEL),
|
||||
('inventory', '0046_remove_dealersettings_invoice_prepaid_account_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='dealersettings',
|
||||
name='invoice_recivable_account',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dealersettings',
|
||||
name='invoice_prepaid_account',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='invoice_prepaid', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL),
|
||||
),
|
||||
]
|
||||
@ -1,39 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-24 09:14
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_ACCOUNT_MODEL),
|
||||
('inventory', '0047_remove_dealersettings_invoice_recivable_account_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='dealersettings',
|
||||
name='bill_payable_account',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='dealersettings',
|
||||
name='bill_prepaid_expense_account',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dealersettings',
|
||||
name='bill_prepaid_account',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bill_prepaid', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='dealersettings',
|
||||
name='bill_unearned_account',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bill_unearned', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='dealersettings',
|
||||
name='bill_cash_account',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='bill_cash', to=settings.DJANGO_LEDGER_ACCOUNT_MODEL),
|
||||
),
|
||||
]
|
||||
@ -1,33 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-26 08:53
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0048_remove_dealersettings_bill_payable_account_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='lead',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('new', 'New'), ('pending', 'Pending'), ('in_progress', 'In Progress'), ('qualified', 'Qualified'), ('contacted', 'Contacted'), ('converted', 'Converted'), ('canceled', 'Canceled')], db_index=True, default='new', max_length=50, verbose_name='Status'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='leadstatushistory',
|
||||
name='new_status',
|
||||
field=models.CharField(choices=[('new', 'New'), ('pending', 'Pending'), ('in_progress', 'In Progress'), ('qualified', 'Qualified'), ('contacted', 'Contacted'), ('converted', 'Converted'), ('canceled', 'Canceled')], max_length=50, verbose_name='New Status'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='leadstatushistory',
|
||||
name='old_status',
|
||||
field=models.CharField(choices=[('new', 'New'), ('pending', 'Pending'), ('in_progress', 'In Progress'), ('qualified', 'Qualified'), ('contacted', 'Contacted'), ('converted', 'Converted'), ('canceled', 'Canceled')], max_length=50, verbose_name='Old Status'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='opportunity',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('new', 'New'), ('pending', 'Pending'), ('in_progress', 'In Progress'), ('qualified', 'Qualified'), ('contacted', 'Contacted'), ('converted', 'Converted'), ('canceled', 'Canceled')], default='new', max_length=20, verbose_name='Status'),
|
||||
),
|
||||
]
|
||||
@ -1,22 +0,0 @@
|
||||
# Generated by Django 5.1.6 on 2025-02-24 17:25
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0048_remove_dealersettings_bill_payable_account_and_more'),
|
||||
migrations.swappable_dependency(settings.DJANGO_LEDGER_CUSTOMER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='carreservation',
|
||||
name='reserved_for',
|
||||
field=models.ForeignKey(default='dd747dc3-39bc-411f-a17d-c930a50220fe', on_delete=django.db.models.deletion.CASCADE, related_name='reservations', to=settings.DJANGO_LEDGER_CUSTOMER_MODEL, verbose_name='Reserved For'),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
@ -1,17 +0,0 @@
|
||||
# Generated by Django 5.1.6 on 2025-02-25 01:05
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0049_carreservation_reserved_for'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='carreservation',
|
||||
name='reserved_for',
|
||||
),
|
||||
]
|
||||
@ -1,14 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-26 13:54
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0049_alter_lead_status_alter_leadstatushistory_new_status_and_more'),
|
||||
('inventory', '0050_remove_carreservation_reserved_for'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-02-27 15:48
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0051_merge_20250226_1654'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='lead',
|
||||
name='lead_type',
|
||||
field=models.CharField(choices=[('customer', 'Customer'), ('organization', 'Organization')], default='customer', max_length=50, verbose_name='Lead Type'),
|
||||
),
|
||||
]
|
||||
@ -1,23 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-03-01 21:22
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0052_lead_lead_type'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='lead',
|
||||
name='crn',
|
||||
field=models.CharField(blank=True, max_length=10, null=True, unique=True, verbose_name='Commercial Registration Number'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='lead',
|
||||
name='vrn',
|
||||
field=models.CharField(blank=True, max_length=15, null=True, unique=True, verbose_name='VAT Registration Number'),
|
||||
),
|
||||
]
|
||||
@ -1,18 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-03-04 01:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0053_lead_crn_lead_vrn'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='staff',
|
||||
name='staff_type',
|
||||
field=models.CharField(choices=[('inventory', 'Inventory'), ('accountant', 'Accountant'), ('sales', 'Sales')], max_length=255, verbose_name='Staff Type'),
|
||||
),
|
||||
]
|
||||
@ -1,26 +0,0 @@
|
||||
# Generated by Django 5.1.6 on 2025-03-03 16:59
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0053_lead_crn_lead_vrn'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='DealersMake',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('added_at', models.DateTimeField(auto_now_add=True)),
|
||||
('car_make', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='car_dealers', to='inventory.carmake')),
|
||||
('dealer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='dealer_makes', to='inventory.dealer')),
|
||||
],
|
||||
options={
|
||||
'unique_together': {('dealer', 'car_make')},
|
||||
},
|
||||
),
|
||||
]
|
||||
@ -1,14 +0,0 @@
|
||||
# Generated by Django 4.2.17 on 2025-03-04 21:15
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inventory', '0054_alter_staff_staff_type'),
|
||||
('inventory', '0054_dealersmake'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
||||
Binary file not shown.
@ -210,6 +210,11 @@ def dealer_signup(request, *args, **kwargs):
|
||||
user = User.objects.create(username=email, email=email)
|
||||
user.set_password(password)
|
||||
user.save()
|
||||
group = Group.objects.create(name=f'{user.pk}-Admin')
|
||||
user.groups.add(group)
|
||||
for perm in Permission.objects.filter(content_type__app_label__in=["inventory","django_ledger"]):
|
||||
group.permissions.add(perm)
|
||||
|
||||
StaffMember.objects.create(user=user)
|
||||
models.Dealer.objects.create(
|
||||
user=user,
|
||||
@ -1300,7 +1305,7 @@ class CustomerDetailView(LoginRequiredMixin,PermissionRequiredMixin, DetailView)
|
||||
return context
|
||||
|
||||
@login_required
|
||||
def add_note_to_customer(request, customer_id):
|
||||
def add_note_to_customer(request, customer_id):
|
||||
customer = get_object_or_404(CustomerModel, uuid=customer_id)
|
||||
if request.method == "POST":
|
||||
form = forms.NoteForm(request.POST)
|
||||
@ -2721,7 +2726,7 @@ class UserActivityLogListView(LoginRequiredMixin,ListView):
|
||||
queryset = super().get_queryset()
|
||||
if "user" in self.request.GET:
|
||||
queryset = queryset.filter(user__email=self.request.GET["user"])
|
||||
return queryset
|
||||
return queryset[:100] # will update later with better pagination
|
||||
|
||||
|
||||
# CRM RELATED VIEWS
|
||||
|
||||
@ -23,7 +23,7 @@ certifi==2025.1.31
|
||||
cffi==1.17.1
|
||||
chardet==5.2.0
|
||||
charset-normalizer==3.4.1
|
||||
click==8.1.8
|
||||
click
|
||||
colorama==0.4.6
|
||||
commonmark==0.9.1
|
||||
contourpy==1.3.1
|
||||
@ -55,7 +55,7 @@ django-extensions==3.2.3
|
||||
django-filter==25.1
|
||||
django-formtools==2.5.1
|
||||
django-import-export==4.3.5
|
||||
django-ledger==0.7.4.1
|
||||
django-ledger
|
||||
django-model-utils==5.0.0
|
||||
django-money==3.5.3
|
||||
django-next-url-mixin==0.4.0
|
||||
@ -89,7 +89,6 @@ et_xmlfile==2.0.0
|
||||
Faker==36.1.1
|
||||
filelock==3.17.0
|
||||
fire==0.7.0
|
||||
Flask==3.1.0
|
||||
fonttools==4.56.0
|
||||
fpdf2==2.8.2
|
||||
frozenlist==1.5.0
|
||||
@ -151,22 +150,16 @@ packaging==24.2
|
||||
pandas==2.2.3
|
||||
pango==0.0.1
|
||||
pdfkit==1.0.0
|
||||
phonenumbers==8.13.55
|
||||
pillow==11.1.0
|
||||
platformdirs==4.3.6
|
||||
prometheus_client==0.21.1
|
||||
propcache==0.2.1
|
||||
protobuf==5.29.3
|
||||
psycopg==3.2.4
|
||||
psycopg-binary==3.2.4
|
||||
psycopg-c==3.2.4
|
||||
py-moneyed==3.0
|
||||
PyAutoGUI==0.9.54
|
||||
pyclipper==1.3.0.post6
|
||||
pycodestyle==2.12.1
|
||||
pycparser==2.22
|
||||
pydantic==2.10.6
|
||||
pydantic_core==2.29.0
|
||||
pydotplus==2.0.2
|
||||
pydyf==0.11.0
|
||||
PyGetWindow==0.0.9
|
||||
@ -174,10 +167,6 @@ Pygments==2.19.1
|
||||
PyJWT==2.10.1
|
||||
pylint==3.3.4
|
||||
PyMsgBox==1.0.9
|
||||
PyMySQL==1.1.1
|
||||
pyobjc-core==11.0
|
||||
pyobjc-framework-Cocoa==11.0
|
||||
pyobjc-framework-Quartz==11.0
|
||||
pyparsing==3.2.1
|
||||
pypdf==5.3.0
|
||||
PyPDF2==3.0.1
|
||||
@ -198,8 +187,6 @@ pytweening==1.2.0
|
||||
pytz==2025.1
|
||||
pyvin==0.0.2
|
||||
pywa==2.7.0
|
||||
pywhat==5.1.0
|
||||
pywhatkit==5.4
|
||||
PyYAML==6.0.2
|
||||
pyzbar==0.1.9
|
||||
qrcode==8.0
|
||||
@ -229,7 +216,6 @@ sqlparse==0.5.3
|
||||
stanza==1.10.1
|
||||
stringzilla==3.11.3
|
||||
suds==1.2.0
|
||||
swapper==1.4.0
|
||||
sympy==1.13.1
|
||||
tablib==3.8.0
|
||||
termcolor==2.5.0
|
||||
@ -263,3 +249,5 @@ wsproto==1.2.0
|
||||
xmlsec==1.3.14
|
||||
yarl==1.18.3
|
||||
zopfli==0.2.3.post1
|
||||
python-dotenv
|
||||
psycopg2-binary
|
||||
@ -1,3 +1,5 @@
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import Group
|
||||
from django_ledger.models.invoice import InvoiceModel
|
||||
@ -17,6 +19,7 @@ import hashlib
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
load_dotenv(".env")
|
||||
def run():
|
||||
# print(Service.objects.first().pk)
|
||||
# print(Appointment.objects.first().client)
|
||||
@ -145,7 +148,8 @@ def run():
|
||||
# print(Permission.objects.filter(codename__in=['view_car','view_carlocation','view_customcard','view_carcolors','view_cartransfer','view_estimatemodel','view_invoicemodel','view_saleorder']))
|
||||
# print(Permission.objects.filter(codename__in=['view_estimatemodel','view_invoicemodel','view_saleorder']))
|
||||
# CustomGroup.objects.filter(name='Accountant').last().set_default_permissions()
|
||||
CustomGroup.objects.filter(name='Inventory').last().set_default_permissions()
|
||||
# CustomGroup.objects.filter(name='Inventory').last().set_default_permissions()
|
||||
|
||||
# EntityManagementModel.objects.create(entity=,user=)
|
||||
# print(Permission.objects.filter(codename__icontains='customermodel').first().codename)
|
||||
print(os.getenv("DJANGO_ALLOWED_HOSTS"))
|
||||
|
||||
@ -273,3 +273,7 @@ select.admin-autocomplete {
|
||||
display: block;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.errors .select2-selection {
|
||||
border: 1px solid var(--error-fg);
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ html[data-theme="light"],
|
||||
--body-fg: #333;
|
||||
--body-bg: #fff;
|
||||
--body-quiet-color: #666;
|
||||
--body-medium-color: #444;
|
||||
--body-loud-color: #000;
|
||||
|
||||
--header-color: #ffc;
|
||||
@ -22,11 +23,11 @@ html[data-theme="light"],
|
||||
|
||||
--breadcrumbs-fg: #c4dce8;
|
||||
--breadcrumbs-link-fg: var(--body-bg);
|
||||
--breadcrumbs-bg: var(--primary);
|
||||
--breadcrumbs-bg: #264b5d;
|
||||
|
||||
--link-fg: #417893;
|
||||
--link-hover-color: #036;
|
||||
--link-selected-fg: #5b80b2;
|
||||
--link-selected-fg: var(--secondary);
|
||||
|
||||
--hairline-color: #e8e8e8;
|
||||
--border-color: #ccc;
|
||||
@ -42,10 +43,10 @@ html[data-theme="light"],
|
||||
--selected-row: #ffc;
|
||||
|
||||
--button-fg: #fff;
|
||||
--button-bg: var(--primary);
|
||||
--button-hover-bg: #609ab6;
|
||||
--default-button-bg: var(--secondary);
|
||||
--default-button-hover-bg: #205067;
|
||||
--button-bg: var(--secondary);
|
||||
--button-hover-bg: #205067;
|
||||
--default-button-bg: #205067;
|
||||
--default-button-hover-bg: var(--secondary);
|
||||
--close-button-bg: #747474;
|
||||
--close-button-hover-bg: #333;
|
||||
--delete-button-bg: #ba2121;
|
||||
@ -56,8 +57,6 @@ html[data-theme="light"],
|
||||
--object-tools-hover-bg: var(--close-button-hover-bg);
|
||||
|
||||
--font-family-primary:
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
"Segoe UI",
|
||||
system-ui,
|
||||
Roboto,
|
||||
@ -86,6 +85,8 @@ html[data-theme="light"],
|
||||
"Segoe UI Emoji",
|
||||
"Segoe UI Symbol",
|
||||
"Noto Color Emoji";
|
||||
|
||||
color-scheme: light;
|
||||
}
|
||||
|
||||
html, body {
|
||||
@ -149,7 +150,6 @@ h1 {
|
||||
margin: 0 0 20px;
|
||||
font-weight: 300;
|
||||
font-size: 1.25rem;
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
h2 {
|
||||
@ -165,7 +165,7 @@ h2.subhead {
|
||||
h3 {
|
||||
font-size: 0.875rem;
|
||||
margin: .8em 0 .3em 0;
|
||||
color: var(--body-quiet-color);
|
||||
color: var(--body-medium-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@ -173,6 +173,7 @@ h4 {
|
||||
font-size: 0.75rem;
|
||||
margin: 1em 0 .8em 0;
|
||||
padding-bottom: 3px;
|
||||
color: var(--body-medium-color);
|
||||
}
|
||||
|
||||
h5 {
|
||||
@ -219,6 +220,10 @@ fieldset {
|
||||
border-top: 1px solid var(--hairline-color);
|
||||
}
|
||||
|
||||
details summary {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
font-size: 0.6875rem;
|
||||
color: #777;
|
||||
@ -315,7 +320,7 @@ td, th {
|
||||
}
|
||||
|
||||
th {
|
||||
font-weight: 600;
|
||||
font-weight: 500;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@ -336,7 +341,7 @@ tfoot td {
|
||||
}
|
||||
|
||||
thead th.required {
|
||||
color: var(--body-loud-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
tr.alt {
|
||||
@ -484,8 +489,13 @@ textarea {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
input[type=text], input[type=password], input[type=email], input[type=url],
|
||||
input[type=number], input[type=tel], textarea, select, .vTextField {
|
||||
/*
|
||||
Minifiers remove the default (text) "type" attribute from "input" HTML tags.
|
||||
Add input:not([type]) to make the CSS stylesheet work the same.
|
||||
*/
|
||||
input:not([type]), input[type=text], input[type=password], input[type=email],
|
||||
input[type=url], input[type=number], input[type=tel], textarea, select,
|
||||
.vTextField {
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
padding: 5px 6px;
|
||||
@ -494,9 +504,13 @@ input[type=number], input[type=tel], textarea, select, .vTextField {
|
||||
background-color: var(--body-bg);
|
||||
}
|
||||
|
||||
input[type=text]:focus, input[type=password]:focus, input[type=email]:focus,
|
||||
input[type=url]:focus, input[type=number]:focus, input[type=tel]:focus,
|
||||
textarea:focus, select:focus, .vTextField:focus {
|
||||
/*
|
||||
Minifiers remove the default (text) "type" attribute from "input" HTML tags.
|
||||
Add input:not([type]) to make the CSS stylesheet work the same.
|
||||
*/
|
||||
input:not([type]):focus, input[type=text]:focus, input[type=password]:focus,
|
||||
input[type=email]:focus, input[type=url]:focus, input[type=number]:focus,
|
||||
input[type=tel]:focus, textarea:focus, select:focus, .vTextField:focus {
|
||||
border-color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
@ -586,7 +600,7 @@ input[type=button][disabled].default {
|
||||
font-weight: 400;
|
||||
font-size: 0.8125rem;
|
||||
text-align: left;
|
||||
background: var(--primary);
|
||||
background: var(--header-bg);
|
||||
color: var(--header-link-color);
|
||||
}
|
||||
|
||||
@ -722,6 +736,11 @@ div.breadcrumbs a:focus, div.breadcrumbs a:hover {
|
||||
background: url(../img/icon-viewlink.svg) 0 1px no-repeat;
|
||||
}
|
||||
|
||||
.hidelink {
|
||||
padding-left: 16px;
|
||||
background: url(../img/icon-hidelink.svg) 0 1px no-repeat;
|
||||
}
|
||||
|
||||
.addlink {
|
||||
padding-left: 16px;
|
||||
background: url(../img/icon-addlink.svg) 0 1px no-repeat;
|
||||
@ -831,10 +850,6 @@ a.deletelink:focus, a.deletelink:hover {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#container > div {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
#container > .main {
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
@ -879,9 +894,10 @@ a.deletelink:focus, a.deletelink:hover {
|
||||
margin-right: -300px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
clear: both;
|
||||
padding: 10px;
|
||||
@media (forced-colors: active) {
|
||||
#content-related {
|
||||
border: 1px solid;
|
||||
}
|
||||
}
|
||||
|
||||
/* COLUMN TYPES */
|
||||
@ -919,7 +935,6 @@ a.deletelink:focus, a.deletelink:hover {
|
||||
padding: 10px 40px;
|
||||
background: var(--header-bg);
|
||||
color: var(--header-color);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#header a:link, #header a:visited, #logout-form button {
|
||||
@ -930,11 +945,17 @@ a.deletelink:focus, a.deletelink:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
#header {
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
}
|
||||
|
||||
#branding {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#branding h1 {
|
||||
#site-name {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
margin-inline-end: 20px;
|
||||
@ -943,7 +964,7 @@ a.deletelink:focus, a.deletelink:hover {
|
||||
color: var(--header-branding-color);
|
||||
}
|
||||
|
||||
#branding h1 a:link, #branding h1 a:visited {
|
||||
#site-name a:link, #site-name a:visited {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
@ -1143,3 +1164,16 @@ a.deletelink:focus, a.deletelink:hover {
|
||||
.base-svgs {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.visually-hidden {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0,0,0,0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
color: var(--body-fg);
|
||||
background-color: var(--body-bg);
|
||||
}
|
||||
|
||||
@ -139,6 +139,12 @@
|
||||
margin: 0 0 0 30px;
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
#changelist-filter {
|
||||
border: 1px solid;
|
||||
}
|
||||
}
|
||||
|
||||
#changelist-filter h2 {
|
||||
font-size: 0.875rem;
|
||||
text-transform: uppercase;
|
||||
@ -215,9 +221,9 @@
|
||||
color: var(--link-hover-color);
|
||||
}
|
||||
|
||||
#changelist-filter #changelist-filter-clear a {
|
||||
#changelist-filter #changelist-filter-extra-actions {
|
||||
font-size: 0.8125rem;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
}
|
||||
|
||||
@ -265,6 +271,15 @@
|
||||
background-color: var(--selected-row);
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
#changelist tbody tr.selected {
|
||||
background-color: SelectedItem;
|
||||
}
|
||||
#changelist tbody tr:has(.action-select:checked) {
|
||||
background-color: SelectedItem;
|
||||
}
|
||||
}
|
||||
|
||||
#changelist .actions {
|
||||
padding: 10px;
|
||||
background: var(--body-bg);
|
||||
|
||||
@ -5,7 +5,8 @@
|
||||
|
||||
--body-fg: #eeeeee;
|
||||
--body-bg: #121212;
|
||||
--body-quiet-color: #e0e0e0;
|
||||
--body-quiet-color: #d0d0d0;
|
||||
--body-medium-color: #e0e0e0;
|
||||
--body-loud-color: #ffffff;
|
||||
|
||||
--breadcrumbs-link-fg: #e0e0e0;
|
||||
@ -29,6 +30,8 @@
|
||||
|
||||
--close-button-bg: #333333;
|
||||
--close-button-hover-bg: #666666;
|
||||
|
||||
color-scheme: dark;
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,7 +42,8 @@ html[data-theme="dark"] {
|
||||
|
||||
--body-fg: #eeeeee;
|
||||
--body-bg: #121212;
|
||||
--body-quiet-color: #e0e0e0;
|
||||
--body-quiet-color: #d0d0d0;
|
||||
--body-medium-color: #e0e0e0;
|
||||
--body-loud-color: #ffffff;
|
||||
|
||||
--breadcrumbs-link-fg: #e0e0e0;
|
||||
@ -63,6 +67,8 @@ html[data-theme="dark"] {
|
||||
|
||||
--close-button-bg: #333333;
|
||||
--close-button-hover-bg: #666666;
|
||||
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/* THEME SWITCH */
|
||||
@ -122,16 +128,3 @@ html[data-theme="dark"] .theme-toggle svg.theme-icon-when-dark {
|
||||
html[data-theme="light"] .theme-toggle svg.theme-icon-when-light {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.visually-hidden {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip: rect(0,0,0,0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
color: var(--body-fg);
|
||||
background-color: var(--body-bg);
|
||||
}
|
||||
|
||||
@ -44,7 +44,6 @@ label {
|
||||
|
||||
.required label, label.required {
|
||||
font-weight: bold;
|
||||
color: var(--body-fg);
|
||||
}
|
||||
|
||||
/* RADIO BUTTONS */
|
||||
@ -76,6 +75,20 @@ form ul.inline li {
|
||||
padding-right: 7px;
|
||||
}
|
||||
|
||||
/* FIELDSETS */
|
||||
|
||||
fieldset .fieldset-heading,
|
||||
fieldset .inline-heading,
|
||||
:not(.inline-related) .collapse summary {
|
||||
border: 1px solid var(--header-bg);
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
font-weight: 400;
|
||||
font-size: 0.8125rem;
|
||||
background: var(--header-bg);
|
||||
color: var(--header-link-color);
|
||||
}
|
||||
|
||||
/* ALIGNED FIELDSETS */
|
||||
|
||||
.aligned label {
|
||||
@ -84,14 +97,12 @@ form ul.inline li {
|
||||
min-width: 160px;
|
||||
width: 160px;
|
||||
word-wrap: break-word;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.aligned label:not(.vCheckboxLabel):after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
height: 1.625rem;
|
||||
}
|
||||
|
||||
.aligned label + p, .aligned .checkbox-row + div.help, .aligned label + div.readonly {
|
||||
@ -158,6 +169,10 @@ form .aligned select + div.help {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
form .aligned select option:checked {
|
||||
background-color: var(--selected-row);
|
||||
}
|
||||
|
||||
form .aligned ul li {
|
||||
list-style: none;
|
||||
}
|
||||
@ -168,11 +183,7 @@ form .aligned table p {
|
||||
}
|
||||
|
||||
.aligned .vCheckboxLabel {
|
||||
float: none;
|
||||
width: auto;
|
||||
display: inline-block;
|
||||
vertical-align: -3px;
|
||||
padding: 0 0 5px 5px;
|
||||
padding: 1px 0 0 5px;
|
||||
}
|
||||
|
||||
.aligned .vCheckboxLabel + p.help,
|
||||
@ -194,14 +205,8 @@ fieldset .fieldBox {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
form .wide p,
|
||||
form .wide ul.errorlist,
|
||||
form .wide input + p.help,
|
||||
form .wide input + div.help {
|
||||
margin-left: 200px;
|
||||
}
|
||||
|
||||
form .wide p.help,
|
||||
form .wide ul.errorlist,
|
||||
form .wide div.help {
|
||||
padding-left: 50px;
|
||||
}
|
||||
@ -215,35 +220,16 @@ form div.help ul {
|
||||
width: 450px;
|
||||
}
|
||||
|
||||
/* COLLAPSED FIELDSETS */
|
||||
/* COLLAPSIBLE FIELDSETS */
|
||||
|
||||
fieldset.collapsed * {
|
||||
display: none;
|
||||
}
|
||||
|
||||
fieldset.collapsed h2, fieldset.collapsed {
|
||||
display: block;
|
||||
}
|
||||
|
||||
fieldset.collapsed {
|
||||
border: 1px solid var(--hairline-color);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
fieldset.collapsed h2 {
|
||||
background: var(--darkened-bg);
|
||||
color: var(--body-quiet-color);
|
||||
}
|
||||
|
||||
fieldset .collapse-toggle {
|
||||
color: var(--header-link-color);
|
||||
}
|
||||
|
||||
fieldset.collapsed .collapse-toggle {
|
||||
.collapse summary .fieldset-heading,
|
||||
.collapse summary .inline-heading {
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: currentColor;
|
||||
display: inline;
|
||||
color: var(--link-fg);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* MONOSPACE TEXTAREAS */
|
||||
@ -395,14 +381,16 @@ body.popup .submit-row {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.inline-related h3 {
|
||||
.inline-related h4,
|
||||
.inline-related:not(.tabular) .collapse summary {
|
||||
margin: 0;
|
||||
color: var(--body-quiet-color);
|
||||
color: var(--body-medium-color);
|
||||
padding: 5px;
|
||||
font-size: 0.8125rem;
|
||||
background: var(--darkened-bg);
|
||||
border-top: 1px solid var(--hairline-color);
|
||||
border-bottom: 1px solid var(--hairline-color);
|
||||
border: 1px solid var(--hairline-color);
|
||||
border-left-color: var(--darkened-bg);
|
||||
border-right-color: var(--darkened-bg);
|
||||
}
|
||||
|
||||
.inline-related h3 span.delete {
|
||||
@ -421,16 +409,6 @@ body.popup .submit-row {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.inline-related fieldset.module h3 {
|
||||
margin: 0;
|
||||
padding: 2px 5px 3px 5px;
|
||||
font-size: 0.6875rem;
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
background: #bcd;
|
||||
color: var(--body-bg);
|
||||
}
|
||||
|
||||
.inline-group .tabular fieldset.module {
|
||||
border: none;
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
}
|
||||
|
||||
.login #content {
|
||||
padding: 20px 20px 0;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.login #container {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user