changes
This commit is contained in:
parent
3458671826
commit
bc77e6c79d
@ -22,7 +22,7 @@ from django_ledger.forms.estimate import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from django_ledger.forms.bill import BillModelCreateForm as BillModelCreateFormBase
|
from django_ledger.forms.bill import BillModelCreateForm as BillModelCreateFormBase
|
||||||
from django_ledger.forms.vendor import VendorModelForm
|
|
||||||
from .models import (
|
from .models import (
|
||||||
Dealer,
|
Dealer,
|
||||||
# Branch,
|
# Branch,
|
||||||
@ -39,26 +39,24 @@ from .models import (
|
|||||||
InteriorColors,
|
InteriorColors,
|
||||||
# SaleQuotation,
|
# SaleQuotation,
|
||||||
CarLocation,
|
CarLocation,
|
||||||
Organization,
|
|
||||||
Representative,
|
Representative,
|
||||||
Payment,
|
|
||||||
# SaleQuotationCar,
|
# SaleQuotationCar,
|
||||||
AdditionalServices,
|
AdditionalServices,
|
||||||
Staff,
|
Staff,
|
||||||
Opportunity,
|
Opportunity,
|
||||||
Priority,
|
|
||||||
Sources,
|
|
||||||
Lead,
|
Lead,
|
||||||
Activity,
|
Activity,
|
||||||
Notes,
|
Notes,
|
||||||
CarModel,
|
CarModel,
|
||||||
SaleOrder,
|
SaleOrder,
|
||||||
CarMake,
|
CarMake,
|
||||||
|
DealerSettings
|
||||||
)
|
)
|
||||||
from django_ledger import models as ledger_models
|
from django_ledger import models as ledger_models
|
||||||
from django.forms import (
|
from django.forms import (
|
||||||
ModelMultipleChoiceField,
|
|
||||||
ValidationError,
|
|
||||||
DateInput,
|
DateInput,
|
||||||
DateTimeInput,
|
DateTimeInput,
|
||||||
)
|
)
|
||||||
@ -465,7 +463,7 @@ class WizardForm1(forms.Form):
|
|||||||
"placeholder": _("Email address"),
|
"placeholder": _("Email address"),
|
||||||
"name": _("email"),
|
"name": _("email"),
|
||||||
"required": "required",
|
"required": "required",
|
||||||
**hx_attrs
|
# **hx_attrs
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
error_messages={
|
error_messages={
|
||||||
@ -480,7 +478,7 @@ class WizardForm1(forms.Form):
|
|||||||
"class": "form-control form-control-sm",
|
"class": "form-control form-control-sm",
|
||||||
"placeholder": _("Password"),
|
"placeholder": _("Password"),
|
||||||
"required": "required",
|
"required": "required",
|
||||||
**hx_attrs
|
# **hx_attrs
|
||||||
},
|
},
|
||||||
render_value=True
|
render_value=True
|
||||||
),
|
),
|
||||||
@ -497,7 +495,7 @@ class WizardForm1(forms.Form):
|
|||||||
"class": "form-control form-control-sm",
|
"class": "form-control form-control-sm",
|
||||||
"placeholder": _("Confirm Password"),
|
"placeholder": _("Confirm Password"),
|
||||||
"required": "required",
|
"required": "required",
|
||||||
**hx_attrs
|
# **hx_attrs
|
||||||
},
|
},
|
||||||
render_value=True
|
render_value=True
|
||||||
),
|
),
|
||||||
@ -513,7 +511,7 @@ class WizardForm1(forms.Form):
|
|||||||
attrs={
|
attrs={
|
||||||
"class": "form-check-input",
|
"class": "form-check-input",
|
||||||
"required": "required",
|
"required": "required",
|
||||||
**hx_attrs
|
# **hx_attrs
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
error_messages={
|
error_messages={
|
||||||
@ -789,10 +787,10 @@ class OpportunityForm(forms.ModelForm):
|
|||||||
class InvoiceModelCreateForm(InvoiceModelCreateFormBase):
|
class InvoiceModelCreateForm(InvoiceModelCreateFormBase):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
# self.fields["cash_account"].widget = forms.HiddenInput()
|
self.fields["cash_account"].widget = forms.HiddenInput()
|
||||||
# self.fields["prepaid_account"].widget = forms.HiddenInput()
|
self.fields["prepaid_account"].widget = forms.HiddenInput()
|
||||||
# self.fields["unearned_account"].widget = forms.HiddenInput()
|
self.fields["unearned_account"].widget = forms.HiddenInput()
|
||||||
self.fields["date_draft"] = forms.DateField(
|
self.fields["date_draft"] = forms.DateField(
|
||||||
widget=DateInput(attrs={"type": "date"})
|
widget=DateInput(attrs={"type": "date"})
|
||||||
)
|
)
|
||||||
@ -807,13 +805,13 @@ class InvoiceModelCreateForm(InvoiceModelCreateFormBase):
|
|||||||
class BillModelCreateForm(BillModelCreateFormBase):
|
class BillModelCreateForm(BillModelCreateFormBase):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.fields["cash_account"].widget = forms.HiddenInput()
|
self.fields["cash_account"].widget = forms.HiddenInput()
|
||||||
self.fields["prepaid_account"].widget = forms.HiddenInput()
|
self.fields["prepaid_account"].widget = forms.HiddenInput()
|
||||||
self.fields["unearned_account"].widget = forms.HiddenInput()
|
self.fields["unearned_account"].widget = forms.HiddenInput()
|
||||||
self.fields["date_draft"] = forms.DateField(
|
# self.fields["date_draft"] = forms.DateField(
|
||||||
widget=DateInput(attrs={"type": "date"})
|
# widget=DateInput(attrs={"type": "date"})
|
||||||
)
|
# )
|
||||||
|
|
||||||
|
|
||||||
class SaleOrderForm(forms.ModelForm):
|
class SaleOrderForm(forms.ModelForm):
|
||||||
@ -926,4 +924,10 @@ class UserGroupForm(forms.ModelForm):
|
|||||||
)
|
)
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CustomGroup
|
model = CustomGroup
|
||||||
fields = ["name"]
|
fields = ["name"]
|
||||||
|
|
||||||
|
class DealerSettingsForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = DealerSettings
|
||||||
|
fields = "__all__"
|
||||||
|
|
||||||
33
inventory/migrations/0040_usersettings.py
Normal file
33
inventory/migrations/0040_usersettings.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# 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)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
# 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),
|
||||||
|
),
|
||||||
|
]
|
||||||
21
inventory/migrations/0042_alter_usersettings_user.py
Normal file
21
inventory/migrations/0042_alter_usersettings_user.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# 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),
|
||||||
|
),
|
||||||
|
]
|
||||||
21
inventory/migrations/0043_alter_usersettings_user.py
Normal file
21
inventory/migrations/0043_alter_usersettings_user.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# 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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
# 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',
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
# 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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
# 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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
# 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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
# 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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -16,7 +16,7 @@ from django.core.exceptions import ValidationError
|
|||||||
from phonenumber_field.modelfields import PhoneNumberField
|
from phonenumber_field.modelfields import PhoneNumberField
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from .mixins import LocalizedNameMixin
|
from .mixins import LocalizedNameMixin
|
||||||
from django_ledger.models import EntityModel, ItemModel,EstimateModel,InvoiceModel
|
from django_ledger.models import EntityModel, ItemModel,EstimateModel,InvoiceModel,AccountModel
|
||||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from appointment.models import StaffMember
|
from appointment.models import StaffMember
|
||||||
@ -1852,4 +1852,20 @@ class CustomGroup(models.Model):
|
|||||||
Permission.objects.get(codename=perm)
|
Permission.objects.get(codename=perm)
|
||||||
self.add_permission(perm)
|
self.add_permission(perm)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class DealerSettings(models.Model):
|
||||||
|
dealer = models.OneToOneField(Dealer, on_delete=models.CASCADE, related_name="settings",null=True, blank=True)
|
||||||
|
invoice_cash_account = models.ForeignKey(AccountModel,related_name="invoice_cash", on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
|
invoice_prepaid_account = models.ForeignKey(AccountModel,related_name="invoice_prepaid", on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
|
invoice_unearned_account = models.ForeignKey(AccountModel,related_name="invoice_unearned", on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
|
|
||||||
|
bill_cash_account = models.ForeignKey(AccountModel,related_name="bill_cash", on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
|
bill_prepaid_account = models.ForeignKey(AccountModel,related_name="bill_prepaid", on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
|
bill_unearned_account = models.ForeignKey(AccountModel,related_name="bill_unearned", on_delete=models.SET_NULL, null=True, blank=True)
|
||||||
|
additional_info = models.JSONField(default=dict,null=True,blank=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Settings for {self.dealer}"
|
||||||
@ -82,6 +82,11 @@ def create_car_location(sender, instance, created, **kwargs):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Failed to create CarLocation for car {instance.vin}: {e}")
|
print(f"Failed to create CarLocation for car {instance.vin}: {e}")
|
||||||
|
|
||||||
|
@receiver(post_save, sender=models.Dealer)
|
||||||
|
def create_dealer_settings(sender, instance, created, **kwargs):
|
||||||
|
if created:
|
||||||
|
models.DealerSettings.objects.create(dealer=instance)
|
||||||
|
|
||||||
# Create Entity
|
# Create Entity
|
||||||
@receiver(post_save, sender=models.Dealer)
|
@receiver(post_save, sender=models.Dealer)
|
||||||
def create_ledger_entity(sender, instance, created, **kwargs):
|
def create_ledger_entity(sender, instance, created, **kwargs):
|
||||||
|
|||||||
@ -43,6 +43,8 @@ urlpatterns = [
|
|||||||
# ),
|
# ),
|
||||||
# ),
|
# ),
|
||||||
# Dashboards
|
# Dashboards
|
||||||
|
# path("user/<int:pk>/settings/", views.UserSettingsView.as_view(), name="user_settings"),
|
||||||
|
path("dealer/<int:pk>/settings/", views.DealerSettingsView, name="dealer_settings"),
|
||||||
path("dashboards/manager/", views.ManagerDashboard.as_view(), name="manager_dashboard"),
|
path("dashboards/manager/", views.ManagerDashboard.as_view(), name="manager_dashboard"),
|
||||||
path("test/", views.TestView.as_view(), name="test"),
|
path("test/", views.TestView.as_view(), name="test"),
|
||||||
path('cars/inventory/table/', views.CarListViewTable.as_view(), name="car_table"),
|
path('cars/inventory/table/', views.CarListViewTable.as_view(), name="car_table"),
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
from django.views.generic.edit import FormView
|
||||||
from django.db.models import Func
|
from django.db.models import Func
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
from appointment.models import Appointment,AppointmentRequest,Service,StaffMember
|
from appointment.models import Appointment,AppointmentRequest,Service,StaffMember
|
||||||
@ -74,7 +75,7 @@ from django.contrib import messages
|
|||||||
from django.db.models import Sum, F, Count
|
from django.db.models import Sum, F, Count
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from shapely.speedups import available
|
from shapely.speedups import available
|
||||||
|
from django_ledger.io import roles
|
||||||
from .services import (
|
from .services import (
|
||||||
decodevin,
|
decodevin,
|
||||||
get_make,
|
get_make,
|
||||||
@ -194,7 +195,7 @@ def dealer_signup(request, *args, **kwargs):
|
|||||||
data = json.loads(request.body)
|
data = json.loads(request.body)
|
||||||
wf1 = data.get("wizardValidationForm1")
|
wf1 = data.get("wizardValidationForm1")
|
||||||
wf2 = data.get("wizardValidationForm2")
|
wf2 = data.get("wizardValidationForm2")
|
||||||
wf3 = data.get("wizardValidationForm3")
|
wf3 = data.get("wizardValidationForm3")
|
||||||
email = wf1.get("email")
|
email = wf1.get("email")
|
||||||
password = wf1.get("password")
|
password = wf1.get("password")
|
||||||
password_confirm = wf1.get("confirm_password")
|
password_confirm = wf1.get("confirm_password")
|
||||||
@ -3179,13 +3180,9 @@ def invoice_create(request, pk):
|
|||||||
form.initial.update(
|
form.initial.update(
|
||||||
{
|
{
|
||||||
"customer": estimate.customer,
|
"customer": estimate.customer,
|
||||||
"cash_account": entity.get_default_coa_accounts().get(name="Cash"),
|
"cash_account": dealer.settings.invoice_cash_account,
|
||||||
"prepaid_account": entity.get_default_coa_accounts().get(
|
"prepaid_account": dealer.settings.invoice_prepaid_account,
|
||||||
name="Accounts Receivable"
|
"unearned_account": dealer.settings.invoice_unearned_account,
|
||||||
),
|
|
||||||
"unearned_account": entity.get_default_coa_accounts().get(
|
|
||||||
name="Deferred Revenue"
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -4149,13 +4146,9 @@ def bill_create(request):
|
|||||||
form = forms.BillModelCreateForm(entity_model=entity)
|
form = forms.BillModelCreateForm(entity_model=entity)
|
||||||
form.initial.update(
|
form.initial.update(
|
||||||
{
|
{
|
||||||
"cash_account": entity.get_default_coa_accounts().get(name="Cash"),
|
"cash_account": dealer.settings.bill_cash_account,
|
||||||
"prepaid_account": entity.get_default_coa_accounts().get(
|
"prepaid_account": dealer.settings.bill_prepaid_account,
|
||||||
name="Prepaid Expenses"
|
"unearned_account": dealer.settings.bill_unearned_account
|
||||||
),
|
|
||||||
"unearned_account": entity.get_default_coa_accounts().get(
|
|
||||||
name="Accounts Payable"
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
car_list = models.Car.objects.filter(dealer=dealer)
|
car_list = models.Car.objects.filter(dealer=dealer)
|
||||||
@ -4598,3 +4591,44 @@ class CarListViewTable(ExportMixin, LoginRequiredMixin, SingleTableView):
|
|||||||
"finances", "colors__exterior", "colors__interior"
|
"finances", "colors__exterior", "colors__interior"
|
||||||
).filter(dealer=dealer)
|
).filter(dealer=dealer)
|
||||||
|
|
||||||
|
|
||||||
|
# class UserSettingsView(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
|
||||||
|
# template_name = 'account/user_settings.html'
|
||||||
|
# form_class = forms.UserSettingsForm
|
||||||
|
# model = models.UserSettings
|
||||||
|
# success_message = 'User settings updated'
|
||||||
|
|
||||||
|
# def get_object(self, queryset=None):
|
||||||
|
# return models.UserSettings.objects.get(user=self.request.user)
|
||||||
|
|
||||||
|
# def get_context_data(self, **kwargs):
|
||||||
|
# context = super().get_context_data(**kwargs)
|
||||||
|
# context['form'] = self.form_class(instance=self.get_object())
|
||||||
|
# return context
|
||||||
|
|
||||||
|
# def form_valid(self, form):
|
||||||
|
# form.instance.user = self.request.user
|
||||||
|
# return super().form_valid(form)
|
||||||
|
|
||||||
|
def DealerSettingsView(request,pk):
|
||||||
|
dealer_setting = get_object_or_404(models.DealerSettings, pk=pk)
|
||||||
|
dealer = get_user_type(request)
|
||||||
|
if request.method == 'POST':
|
||||||
|
form = forms.DealerSettingsForm(request.POST, instance=dealer_setting)
|
||||||
|
if form.is_valid():
|
||||||
|
instance = form.save(commit=False)
|
||||||
|
instance.dealer = dealer
|
||||||
|
instance.save()
|
||||||
|
messages.success(request, 'ssettings updated')
|
||||||
|
return redirect('dealer_settings', pk=dealer.pk)
|
||||||
|
else:
|
||||||
|
print(form.errors)
|
||||||
|
form = forms.DealerSettingsForm(instance=dealer_setting,initial={'dealer':dealer})
|
||||||
|
form.fields['invoice_cash_account'].queryset = dealer.entity.get_all_accounts().filter(role=roles.ASSET_CA_CASH)
|
||||||
|
form.fields['invoice_prepaid_account'].queryset = dealer.entity.get_all_accounts().filter(role=roles.ASSET_CA_RECEIVABLES)
|
||||||
|
form.fields['invoice_unearned_account'].queryset = dealer.entity.get_all_accounts().filter(role=roles.LIABILITY_CL_DEFERRED_REVENUE)
|
||||||
|
|
||||||
|
form.fields['bill_cash_account'].queryset = dealer.entity.get_all_accounts().filter(role=roles.ASSET_CA_CASH)
|
||||||
|
form.fields['bill_prepaid_account'].queryset = dealer.entity.get_all_accounts().filter(role=roles.ASSET_CA_PREPAID)
|
||||||
|
form.fields['bill_unearned_account'].queryset = dealer.entity.get_all_accounts().filter(role=roles.LIABILITY_CL_ACC_PAYABLE)
|
||||||
|
return render(request, 'account/user_settings.html', {'form': form})
|
||||||
@ -38,7 +38,7 @@
|
|||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div class="tab-pane active" role="tabpanel" aria-labelledby="bootstrap-wizard-validation-tab1" id="bootstrap-wizard-validation-tab1">
|
<div class="tab-pane active" role="tabpanel" aria-labelledby="bootstrap-wizard-validation-tab1" id="bootstrap-wizard-validation-tab1">
|
||||||
<form class="needs-validation" id="wizardValidationForm1" novalidate="novalidate" data-wizard-form="1">
|
<form class="needs-validation" id="wizardValidationForm1" novalidate="novalidate" data-wizard-form="1">
|
||||||
{{form1|crispy}}
|
{{form1|crispy}}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane" role="tabpanel" aria-labelledby="bootstrap-wizard-validation-tab2" id="bootstrap-wizard-validation-tab2">
|
<div class="tab-pane" role="tabpanel" aria-labelledby="bootstrap-wizard-validation-tab2" id="bootstrap-wizard-validation-tab2">
|
||||||
@ -70,7 +70,7 @@
|
|||||||
<div class="d-flex pager wizard list-inline mb-0">
|
<div class="d-flex pager wizard list-inline mb-0">
|
||||||
<button class="d-none btn btn-link ps-0" type="button" data-wizard-prev-btn="data-wizard-prev-btn">{% trans 'Previous' %}</button>
|
<button class="d-none btn btn-link ps-0" type="button" data-wizard-prev-btn="data-wizard-prev-btn">{% trans 'Previous' %}</button>
|
||||||
<div class="flex-1 text-end">
|
<div class="flex-1 text-end">
|
||||||
<button class="btn btn-phoenix-primary px-6 px-sm-6" type="submit" data-wizard-next-btn="data-wizard-next-btn">{% trans 'Next' %}</button>
|
<button class="btn btn-phoenix-primary px-6 px-sm-6 next" type="submit" data-wizard-next-btn="data-wizard-next-btn">{% trans 'Next' %}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -83,7 +83,113 @@
|
|||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
||||||
{% block customJS %}
|
{% block customJS %}
|
||||||
|
<script src="https://unpkg.com/just-validate@latest/dist/just-validate.production.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
const validator = new JustValidate('#wizardValidationForm1', {
|
||||||
|
validateBeforeSubmitting: true,
|
||||||
|
});
|
||||||
|
const validator1 = new JustValidate('#wizardValidationForm2', {
|
||||||
|
validateBeforeSubmitting: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
validator1.addField('#wizardValidationForm2 [name="phone_number"]', [
|
||||||
|
{
|
||||||
|
rule: 'required',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rule: 'customRegexp',
|
||||||
|
value: /^05\d{8}$/,
|
||||||
|
errorMessage: '{% trans 'Please enter a valid phone number' %}',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rule: 'maxLength',
|
||||||
|
value: 10,
|
||||||
|
errorMessage: '{% trans 'Please enter a valid phone number' %}',
|
||||||
|
},
|
||||||
|
|
||||||
|
]);
|
||||||
|
|
||||||
|
validator.addField('#wizardValidationForm1 [name="email"]', [
|
||||||
|
{
|
||||||
|
rule: 'required',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rule: 'email',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
validator.addField('#wizardValidationForm1 [name="password"]', [
|
||||||
|
{
|
||||||
|
rule: 'required',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rule: 'minLength',
|
||||||
|
value: 6,
|
||||||
|
},
|
||||||
|
|
||||||
|
]);
|
||||||
|
validator.addField('#wizardValidationForm1 [name="confirm_password"]', [
|
||||||
|
{
|
||||||
|
rule: 'required',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rule: 'minLength',
|
||||||
|
value: 6,
|
||||||
|
errorMessage: '{% trans 'Password does not match' %}',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
validator: (value, context) => {
|
||||||
|
if (value !== document.querySelector('#id_password').value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
validator.addField('#wizardValidationForm1 [name="terms"]', [
|
||||||
|
{
|
||||||
|
rule: 'required',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
validator = new JustValidate('#wizardValidationForm1', {
|
||||||
|
rules: {
|
||||||
|
email: {
|
||||||
|
required: true,
|
||||||
|
email: true,
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
required: true,
|
||||||
|
min: 6,
|
||||||
|
},
|
||||||
|
confirm_password: {
|
||||||
|
required: true,
|
||||||
|
min: 6,
|
||||||
|
equalTo: '#password',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
messages: {
|
||||||
|
name: {
|
||||||
|
required: 'Please enter your name',
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
required: 'Please enter your email',
|
||||||
|
email: 'Please enter a valid email address',
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
required: 'Please enter your password',
|
||||||
|
min: 'Password must be at least 6 characters',
|
||||||
|
},
|
||||||
|
confirm_password: {
|
||||||
|
required: 'Please confirm your password',
|
||||||
|
min: 'Password must be at least 6 characters',
|
||||||
|
equalTo: 'Passwords do not match',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
*/
|
||||||
const url = "{% url 'account_signup' %}";
|
const url = "{% url 'account_signup' %}";
|
||||||
let submit_btn = document.getElementById('submit_btn');
|
let submit_btn = document.getElementById('submit_btn');
|
||||||
const csrftoken = getCookie('csrftoken');
|
const csrftoken = getCookie('csrftoken');
|
||||||
|
|||||||
51
templates/account/user_settings.html
Normal file
51
templates/account/user_settings.html
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load crispy_forms_filters %}
|
||||||
|
{% load i18n static %}
|
||||||
|
{% load allauth account %}
|
||||||
|
{% block head_title %}
|
||||||
|
{% trans 'User Settings' %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<form action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="col-12 col-xl-8">
|
||||||
|
<div class="border-bottom mb-4">
|
||||||
|
|
||||||
|
<div class="row gx-3 mb-6 gy-6 gy-sm-3">
|
||||||
|
<div class="col-12 col-sm-8">
|
||||||
|
<h4 class="mb-4">Default Invoice Accounts</h4>
|
||||||
|
<div class="form-icon-container mb-3">
|
||||||
|
{{ form.invoice_cash_account|as_crispy_field }}
|
||||||
|
</div>
|
||||||
|
<div class="form-icon-container mb-3">
|
||||||
|
{{ form.invoice_prepaid_account|as_crispy_field }}
|
||||||
|
</div>
|
||||||
|
<div class="form-icon-container mb-3">
|
||||||
|
{{ form.invoice_unearned_account|as_crispy_field }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row gx-3 mb-6 gy-6 gy-sm-3">
|
||||||
|
<div class="col-12 col-sm-8">
|
||||||
|
<h4 class="mb-4">Default Bill Accounts</h4>
|
||||||
|
<div class="form-icon-container mb-3">
|
||||||
|
{{ form.bill_cash_account|as_crispy_field }}
|
||||||
|
</div>
|
||||||
|
<div class="form-icon-container mb-3">
|
||||||
|
{{ form.bill_prepaid_account|as_crispy_field }}
|
||||||
|
</div>
|
||||||
|
<div class="form-icon-container mb-3">
|
||||||
|
{{ form.bill_unearned_account|as_crispy_field }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-start mb-6">
|
||||||
|
<div>
|
||||||
|
<button type="submit" class="btn btn-phoenix-primary">Update</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
@ -108,7 +108,7 @@
|
|||||||
<script src="https://unpkg.com/@turf/turf@6/turf.min.js"></script>
|
<script src="https://unpkg.com/@turf/turf@6/turf.min.js"></script>
|
||||||
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
|
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
|
||||||
<script src="{% static 'vendors/swiper/swiper-bundle.min.js' %}"></script>
|
<script src="{% static 'vendors/swiper/swiper-bundle.min.js' %}"></script>
|
||||||
<script src="{% static 'vendors/flatpickr/flatpickr.min.js' %}"></script>
|
<script src="{% static 'vendors/flatpickr/flatpickr.min.js' %}"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
{% if entity_slug %}
|
{% if entity_slug %}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user