This commit is contained in:
gitea 2025-02-24 11:31:24 +00:00
parent 3458671826
commit bc77e6c79d
17 changed files with 514 additions and 42 deletions

View File

@ -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__"

View 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)),
],
),
]

View File

@ -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),
),
]

View 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),
),
]

View 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),
),
]

View File

@ -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',
),
]

View File

@ -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),
),
]

View File

@ -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),
),
]

View File

@ -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),
),
]

View File

@ -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),
),
]

View File

@ -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}"

View File

@ -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):

View File

@ -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"),

View File

@ -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})

View File

@ -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');

View 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 %}

View File

@ -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 %}