895 lines
26 KiB
Python
895 lines
26 KiB
Python
from appointment.models import Appointment, Service, StaffMember
|
|
from django.urls import reverse
|
|
from django_countries.widgets import CountrySelectWidget
|
|
from django_ledger.models import CustomerModel
|
|
from phonenumber_field.formfields import PhoneNumberField
|
|
from django.core.validators import MinLengthValidator
|
|
from django.core.validators import RegexValidator
|
|
from django import forms
|
|
from django.contrib.auth import get_user_model
|
|
from phonenumber_field.phonenumber import PhoneNumber
|
|
from .models import Status, Stage
|
|
from .mixins import AddClassMixin
|
|
from django.forms.models import inlineformset_factory
|
|
from django_ledger.forms.invoice import (
|
|
InvoiceModelCreateForm as InvoiceModelCreateFormBase,
|
|
)
|
|
from django_ledger.forms.estimate import (
|
|
EstimateModelCreateForm as EstimateModelCreateFormBase,
|
|
)
|
|
|
|
from django_ledger.forms.bill import BillModelCreateForm as BillModelCreateFormBase
|
|
from django_ledger.forms.vendor import VendorModelForm
|
|
from .models import (
|
|
Dealer,
|
|
# Branch,
|
|
Vendor,
|
|
Schedule,
|
|
Customer,
|
|
Car,
|
|
CarTransfer,
|
|
CarFinance,
|
|
CustomCard,
|
|
CarRegistration,
|
|
CarColors,
|
|
ExteriorColors,
|
|
InteriorColors,
|
|
# SaleQuotation,
|
|
CarLocation,
|
|
Organization,
|
|
Representative,
|
|
Payment,
|
|
# SaleQuotationCar,
|
|
AdditionalServices,
|
|
Staff,
|
|
Opportunity,
|
|
Priority,
|
|
Sources,
|
|
Lead,
|
|
Activity,
|
|
Notes,
|
|
CarModel,
|
|
SaleOrder,
|
|
CarMake,
|
|
)
|
|
from django_ledger import models as ledger_models
|
|
from django.forms import (
|
|
ModelMultipleChoiceField,
|
|
ValidationError,
|
|
DateInput,
|
|
DateTimeInput,
|
|
)
|
|
from django.utils.translation import gettext_lazy as _
|
|
import django_tables2 as tables
|
|
from django.forms import formset_factory
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class AdditionalServiceForm(forms.ModelForm):
|
|
class Meta:
|
|
model = AdditionalServices
|
|
fields = ["name", "price", "description", "taxable", "uom"]
|
|
|
|
|
|
# class PaymentForm(forms.ModelForm):
|
|
# invoice = forms.ModelChoiceField(queryset=InvoiceModel.objects.all(),label="Invoice", required=True)
|
|
# class Meta:
|
|
# model = Payment
|
|
# fields = ['amount','payment_method', 'reference_number']
|
|
|
|
|
|
class StaffForm(forms.ModelForm):
|
|
email = forms.EmailField(
|
|
required=True,
|
|
label="Email",
|
|
widget=forms.EmailInput(attrs={"class": "form-control form-control-sm"}),
|
|
)
|
|
|
|
class Meta:
|
|
model = Staff
|
|
fields = ["name", "arabic_name", "phone_number", "staff_type"]
|
|
|
|
# def __init__(self, *args, **kwargs):
|
|
# user_instance = kwargs.get("instance")
|
|
# if user_instance and user_instance.user:
|
|
# initial = kwargs.setdefault("initial", {})
|
|
# initial["email"] = user_instance.user.email
|
|
# super().__init__(*args, **kwargs)
|
|
#
|
|
# def save(self, commit=True):
|
|
# user_instance = super().save(commit=False)
|
|
# user = user_instance.user
|
|
# user.email = self.cleaned_data["email"]
|
|
# if commit:
|
|
# user.save()
|
|
# user_instance.save()
|
|
# return user_instance
|
|
|
|
|
|
# Dealer Form
|
|
class DealerForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Dealer
|
|
fields = [
|
|
"name",
|
|
"arabic_name",
|
|
"crn",
|
|
"vrn",
|
|
"phone_number",
|
|
"address",
|
|
"logo",
|
|
]
|
|
|
|
|
|
class CustomerForm(forms.Form):
|
|
first_name = forms.CharField()
|
|
middle_name = forms.CharField()
|
|
last_name = forms.CharField()
|
|
national_id = forms.CharField(max_length=10)
|
|
email = forms.EmailField()
|
|
phone_number = PhoneNumberField(region="SA")
|
|
address = forms.CharField()
|
|
|
|
|
|
class OrganizationForm(forms.Form):
|
|
name = forms.CharField()
|
|
arabic_name = forms.CharField()
|
|
email = forms.EmailField()
|
|
phone_number = PhoneNumberField(region="SA")
|
|
crn = forms.CharField()
|
|
vrn = forms.CharField()
|
|
address = forms.CharField()
|
|
contact_person = forms.CharField(required=False)
|
|
logo = forms.ImageField(required=False)
|
|
|
|
|
|
# class CustomerForm(forms.ModelForm, AddClassMixin):
|
|
# class Meta:
|
|
# model = Customer
|
|
# fields = [
|
|
# "title",
|
|
# "first_name",
|
|
# "middle_name",
|
|
# "last_name",
|
|
# "gender",
|
|
# "dob",
|
|
# "email",
|
|
# "national_id",
|
|
|
|
# "phone_number",
|
|
# "address",
|
|
# ]
|
|
# widgets = {
|
|
# "phone_number": forms.TextInput(attrs={"class": "phone"}),
|
|
# "dob": forms.DateInput(attrs={"type": "date"}),
|
|
# }
|
|
|
|
|
|
class CarForm(
|
|
forms.ModelForm,
|
|
AddClassMixin,
|
|
):
|
|
class Meta:
|
|
model = Car
|
|
fields = [
|
|
"vin",
|
|
"id_car_make",
|
|
"id_car_model",
|
|
"year",
|
|
"id_car_serie",
|
|
"id_car_trim",
|
|
"stock_type",
|
|
"remarks",
|
|
"mileage",
|
|
"receiving_date",
|
|
"vendor",
|
|
]
|
|
widgets = {
|
|
"receiving_date": forms.DateTimeInput(attrs={"type": "datetime-local"}),
|
|
"remarks": forms.Textarea(attrs={"rows": 2}),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
dealer = kwargs.pop("dealer", None)
|
|
super().__init__(*args, **kwargs)
|
|
|
|
if "id_car_make" in self.fields:
|
|
queryset = self.fields["id_car_make"].queryset.filter(is_sa_import=True)
|
|
self.fields["id_car_make"].choices = [
|
|
(obj.id_car_make, obj.get_local_name()) for obj in queryset
|
|
]
|
|
if "id_car_model" in self.fields:
|
|
queryset = self.fields["id_car_model"].queryset
|
|
self.fields["id_car_model"].choices = [
|
|
(obj.id_car_model, obj.get_local_name()) for obj in queryset
|
|
]
|
|
if "vendor" in self.fields:
|
|
self.fields["vendor"].queryset = ledger_models.VendorModel.objects.filter(
|
|
active=True
|
|
)
|
|
# queryset = self.fields["vendor"].queryset
|
|
# self.fields["vendor"].choices = [
|
|
# (obj.pk, obj.get_local_name()) for obj in queryset
|
|
# ]
|
|
|
|
|
|
class CarUpdateForm(forms.ModelForm, AddClassMixin):
|
|
class Meta:
|
|
model = Car
|
|
fields = [
|
|
"vendor",
|
|
"status",
|
|
"stock_type",
|
|
"mileage",
|
|
"receiving_date",
|
|
"remarks",
|
|
]
|
|
|
|
widgets = {
|
|
"receiving_date": forms.DateTimeInput(attrs={"type": "datetime-local"}),
|
|
"remarks": forms.Textarea(attrs={"rows": 2}),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
dealer = kwargs.pop("dealer", None)
|
|
super().__init__(*args, **kwargs)
|
|
|
|
# if dealer and 'branch' in self.fields:
|
|
# self.fields['branch'].queryset = Branch.objects.filter(dealer=dealer)
|
|
# self.fields['branch'].choices = [
|
|
# (branch.id, branch.get_local_name()) for branch in self.fields['branch'].queryset
|
|
# ]
|
|
|
|
# if "vendor" in self.fields:
|
|
# queryset = self.fields["vendor"].queryset
|
|
# if queryset:
|
|
# self.fields["vendor"].choices = [
|
|
# (vendor.id, vendor.get_local_name()) for vendor in queryset
|
|
# ]
|
|
|
|
|
|
class CarFinanceForm(forms.ModelForm):
|
|
additional_finances = forms.ModelMultipleChoiceField(
|
|
queryset=AdditionalServices.objects.all(),
|
|
widget=forms.CheckboxSelectMultiple(attrs={"class": "form-check-input"}),
|
|
required=False,
|
|
)
|
|
|
|
class Meta:
|
|
model = CarFinance
|
|
exclude = [
|
|
"car",
|
|
"profit_margin",
|
|
"vat_amount",
|
|
"total",
|
|
"additional_services",
|
|
]
|
|
|
|
# def __init__(self, *args, **kwargs):
|
|
# super().__init__(*args, **kwargs)
|
|
# if self.instance.pk:
|
|
# self.fields[
|
|
# "additional_finances"
|
|
# ].initial = self.instance.additional_services.all()
|
|
|
|
def save(self, commit=True):
|
|
instance = super().save()
|
|
instance.additional_services.set(self.cleaned_data["additional_finances"])
|
|
instance.save()
|
|
return instance
|
|
|
|
|
|
class CarLocationForm(forms.ModelForm):
|
|
class Meta:
|
|
model = CarLocation
|
|
fields = ["showroom", "description"]
|
|
widgets = {
|
|
"description": forms.Textarea(attrs={"rows": 2, "class": "form-control"}),
|
|
}
|
|
|
|
|
|
class CarTransferForm(forms.ModelForm):
|
|
class Meta:
|
|
model = CarTransfer
|
|
fields = ["car", "to_dealer", "remarks"]
|
|
widgets = {
|
|
"remarks": forms.Textarea(attrs={"rows": 2, "class": "form-control"}),
|
|
}
|
|
|
|
|
|
# Custom Card Form
|
|
class CustomCardForm(forms.ModelForm):
|
|
custom_date = forms.DateTimeField(
|
|
widget=forms.DateInput(attrs={"type": "date"}),
|
|
label=_("Custom Date"),
|
|
)
|
|
|
|
class Meta:
|
|
model = CustomCard
|
|
fields = ["custom_number", "custom_date"]
|
|
|
|
|
|
# Car Registration Form
|
|
class CarRegistrationForm(forms.ModelForm):
|
|
class Meta:
|
|
model = CarRegistration
|
|
fields = ["plate_number", "text1", "text2", "text3", "registration_date"]
|
|
|
|
widgets = {
|
|
"registration_date": forms.DateTimeInput(attrs={"type": "datetime-local"}),
|
|
}
|
|
|
|
|
|
# class VendorForm(VendorModelForm):
|
|
# pass
|
|
class VendorForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Vendor
|
|
fields = [
|
|
"name",
|
|
"arabic_name",
|
|
"crn",
|
|
"vrn",
|
|
"email",
|
|
"phone_number",
|
|
"contact_person",
|
|
"address",
|
|
"logo",
|
|
]
|
|
|
|
|
|
class CarColorsForm(forms.ModelForm):
|
|
class Meta:
|
|
model = CarColors
|
|
fields = ["exterior", "interior"]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.fields["exterior"].queryset = ExteriorColors.objects.all()
|
|
self.fields["exterior"].widget = forms.RadioSelect(
|
|
attrs={"class": "form-check-input"}
|
|
)
|
|
self.fields["exterior"].choices = [
|
|
(color.id, f"{color.get_local_name}")
|
|
for color in ExteriorColors.objects.all().order_by("-name")
|
|
]
|
|
|
|
self.fields["interior"].queryset = InteriorColors.objects.all()
|
|
self.fields["interior"].widget = forms.RadioSelect(
|
|
attrs={"class": "form-check-input"}
|
|
)
|
|
self.fields["interior"].choices = [
|
|
(color.id, f"{color.get_local_name}")
|
|
for color in InteriorColors.objects.all().order_by("-name")
|
|
]
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
exterior = cleaned_data.get("exterior")
|
|
interior = cleaned_data.get("interior")
|
|
|
|
if not exterior or not interior:
|
|
raise forms.ValidationError(
|
|
_("Both exterior and interior colors must be selected.")
|
|
)
|
|
|
|
return cleaned_data
|
|
|
|
|
|
# class QuotationForm(forms.ModelForm):
|
|
# cars = ModelMultipleChoiceField(
|
|
# queryset=Car.objects.none(), # Default empty queryset
|
|
# widget=forms.CheckboxSelectMultiple,
|
|
# label="Select Cars",
|
|
# )
|
|
#
|
|
# class Meta:
|
|
# model = SaleQuotation
|
|
# fields = ["customer", "cars", "remarks"]
|
|
#
|
|
# def __init__(self, *args, **kwargs):
|
|
# super().__init__(*args, **kwargs)
|
|
#
|
|
# self.fields["cars"].queryset = Car.objects.filter(
|
|
# finances__isnull=False
|
|
# ).distinct()
|
|
|
|
|
|
# class OrganizationForm(forms.ModelForm):
|
|
# class Meta:
|
|
# model = Organization
|
|
# fields = [
|
|
# "name",
|
|
# "arabic_name",
|
|
# "crn",
|
|
# "vrn",
|
|
# "phone_number",
|
|
# "address",
|
|
# "logo",
|
|
# ]
|
|
|
|
# def __init__(self, *args, **kwargs):
|
|
# dealer = kwargs.pop("dealer", None)
|
|
# super().__init__(*args, **kwargs)
|
|
|
|
|
|
class RepresentativeForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Representative
|
|
fields = [
|
|
"name",
|
|
"arabic_name",
|
|
"id_number",
|
|
"phone_number",
|
|
"address",
|
|
"organization",
|
|
]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
dealer = kwargs.pop("dealer", None)
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
|
class CarSelectionTable(tables.Table):
|
|
select = tables.CheckBoxColumn(accessor="pk", orderable=False)
|
|
|
|
class Meta:
|
|
model = Car
|
|
fields = ["vin", "year", "id_car_make", "id_car_model"]
|
|
template_name = "django_tables2/bootstrap4.html"
|
|
|
|
|
|
class WizardForm1(forms.Form):
|
|
hx_attrs = {
|
|
"hx-post":"",
|
|
"hx-target": "#wizardValidationForm1",
|
|
"hx-select": "#wizardValidationForm1",
|
|
"hx-trigger": "blur delay:500ms",
|
|
"hx-swap": "innerHTML",
|
|
}
|
|
email = forms.EmailField(
|
|
label=_("Email Address"),
|
|
widget=forms.EmailInput(
|
|
attrs={
|
|
"class": "form-control form-control-sm email",
|
|
"placeholder": _("Email address"),
|
|
"name": _("email"),
|
|
"required": "required",
|
|
**hx_attrs
|
|
}
|
|
),
|
|
error_messages={
|
|
"required": _("You must add an email."),
|
|
},
|
|
)
|
|
|
|
password = forms.CharField(
|
|
label=_("Password"),
|
|
widget=forms.PasswordInput(
|
|
attrs={
|
|
"class": "form-control form-control-sm",
|
|
"placeholder": _("Password"),
|
|
"required": "required",
|
|
**hx_attrs
|
|
},
|
|
render_value=True
|
|
),
|
|
error_messages={
|
|
"required": _("This field is required."),
|
|
},
|
|
min_length=8,
|
|
)
|
|
|
|
confirm_password = forms.CharField(
|
|
label=_("Confirm Password"),
|
|
widget=forms.PasswordInput(
|
|
attrs={
|
|
"class": "form-control form-control-sm",
|
|
"placeholder": _("Confirm Password"),
|
|
"required": "required",
|
|
**hx_attrs
|
|
},
|
|
render_value=True
|
|
),
|
|
error_messages={
|
|
"required": _("This field is required."),
|
|
},
|
|
min_length=8,
|
|
)
|
|
|
|
terms = forms.BooleanField(
|
|
label=_("I accept the Terms and Privacy Policy"),
|
|
widget=forms.CheckboxInput(
|
|
attrs={
|
|
"class": "form-check-input",
|
|
"required": "required",
|
|
**hx_attrs
|
|
}
|
|
),
|
|
error_messages={
|
|
"required": _("You must accept the terms and privacy policy."),
|
|
},
|
|
)
|
|
|
|
|
|
def clean_email(self):
|
|
email = self.cleaned_data.get("email")
|
|
if email:
|
|
if User.objects.filter(email=email).exists():
|
|
raise forms.ValidationError(
|
|
_("An account with this email already exists.")
|
|
)
|
|
return email
|
|
|
|
def clean_confirm_password(self):
|
|
password = self.cleaned_data.get("password")
|
|
confirm_password = self.cleaned_data.get("confirm_password")
|
|
if password and confirm_password and password != confirm_password:
|
|
raise forms.ValidationError(_("Passwords do not match."))
|
|
return confirm_password
|
|
|
|
|
|
class WizardForm2(forms.Form):
|
|
name = forms.CharField(
|
|
label=_("Name"),
|
|
widget=forms.TextInput(
|
|
attrs={
|
|
"class": "form-control form-control-sm",
|
|
"placeholder": _("English Name"),
|
|
"required": "required",
|
|
}
|
|
),
|
|
error_messages={
|
|
"required": _("Please enter an English Name."),
|
|
},
|
|
)
|
|
|
|
arabic_name = forms.CharField(
|
|
label=_("Arabic Name"),
|
|
widget=forms.TextInput(
|
|
attrs={
|
|
"class": "form-control form-control-sm",
|
|
"placeholder": _("Arabic Name"),
|
|
"required": "required",
|
|
}
|
|
),
|
|
error_messages={
|
|
"required": _("Please enter an Arabic name."),
|
|
},
|
|
)
|
|
|
|
phone_number = PhoneNumberField(
|
|
label=_("Phone Number"),
|
|
widget=forms.TextInput(
|
|
attrs={
|
|
"placeholder": _("Phone"),
|
|
}
|
|
),
|
|
region="SA",
|
|
error_messages={
|
|
"required": _("This field is required."),
|
|
"invalid": _("Phone number must be in the format 05xxxxxxxx"),
|
|
},
|
|
required=True,
|
|
)
|
|
|
|
|
|
class WizardForm3(forms.Form):
|
|
# CRN field with max length of 10
|
|
crn = forms.CharField(
|
|
label=_("CRN"),
|
|
widget=forms.TextInput(
|
|
attrs={
|
|
"class": "form-control form-control-sm",
|
|
"placeholder": _("Commercial Registration Number"),
|
|
"required": "required",
|
|
"maxlength": "10",
|
|
}
|
|
),
|
|
max_length=10,
|
|
error_messages={
|
|
"required": _("This field is required."),
|
|
"max_length": "Commercial Registration Number must be 10 characters.",
|
|
},
|
|
)
|
|
|
|
# VRN field with max length of 15
|
|
vrn = forms.CharField(
|
|
label=_("VRN"),
|
|
widget=forms.TextInput(
|
|
attrs={
|
|
"class": "form-control form-control-sm",
|
|
"placeholder": _("VAT Registration Number"),
|
|
"required": "required",
|
|
"maxlength": "15",
|
|
}
|
|
),
|
|
max_length=15, #
|
|
error_messages={
|
|
"required": _("This field is required."),
|
|
"max_length": _("VAT Registration Number must be 15 characters."),
|
|
},
|
|
)
|
|
|
|
address = forms.CharField(
|
|
label=_("Address"),
|
|
widget=forms.Textarea(
|
|
attrs={
|
|
"class": "form-control form-control-sm",
|
|
"rows": "3",
|
|
"required": "required",
|
|
}
|
|
),
|
|
error_messages={
|
|
"required": _("This field is required."),
|
|
},
|
|
)
|
|
|
|
# def clean(self):
|
|
# cleaned_data = super().clean()
|
|
# password = cleaned_data.get("password")
|
|
# confirm_password = cleaned_data.get("confirm_password")
|
|
|
|
# if password != confirm_password:
|
|
# raise forms.ValidationError("Passwords do not match.")
|
|
# else:
|
|
# return cleaned_data
|
|
|
|
|
|
class ItemForm(forms.Form):
|
|
item = forms.ModelChoiceField(
|
|
queryset=ledger_models.ItemModel.objects.all(),
|
|
label="Item",
|
|
required=True,
|
|
validators=[MinLengthValidator(5)],
|
|
)
|
|
quantity = forms.DecimalField(label="Quantity", required=True)
|
|
# unit = forms.DecimalField(label="Unit", required=True)
|
|
# unit_cost = forms.DecimalField(label="Unit Cost", required=True)
|
|
# unit_sales_price = forms.DecimalField(label="Unit Sales Price", required=True)
|
|
|
|
|
|
class PaymentForm(forms.Form):
|
|
invoice = forms.ModelChoiceField(
|
|
queryset=ledger_models.InvoiceModel.objects.all(),
|
|
label="Invoice",
|
|
required=False,
|
|
)
|
|
bill = forms.ModelChoiceField(
|
|
queryset=ledger_models.BillModel.objects.all(), label="Bill", required=False
|
|
)
|
|
amount = forms.DecimalField(label="Amount", required=True)
|
|
payment_method = forms.ChoiceField(
|
|
choices=[
|
|
("cash", _("cash")),
|
|
("credit", _("credit")),
|
|
("transfer", _("transfer")),
|
|
("debit", _("debit")),
|
|
("SADAD", _("SADAD")),
|
|
],
|
|
label="Payment Method",
|
|
required=True,
|
|
)
|
|
payment_date = forms.DateField(
|
|
label="Payment Date", widget=DateInput(attrs={"type": "date"}), required=True
|
|
)
|
|
|
|
def clean_amount(self):
|
|
invoice = self.cleaned_data["invoice"]
|
|
bill = self.cleaned_data["bill"]
|
|
model = invoice if invoice else bill
|
|
amount = self.cleaned_data["amount"]
|
|
if amount + model.amount_paid > model.amount_due:
|
|
raise forms.ValidationError("Payment amount is greater than amount due")
|
|
if amount <= 0:
|
|
raise forms.ValidationError("Payment amount must be greater than 0")
|
|
if model.is_paid():
|
|
raise forms.ValidationError("Invoice is already paid")
|
|
if amount > model.amount_due:
|
|
raise forms.ValidationError("Payment amount is greater than amount due")
|
|
return amount
|
|
|
|
|
|
class EmailForm(forms.Form):
|
|
subject = forms.CharField(max_length=255)
|
|
message = forms.CharField(widget=forms.Textarea)
|
|
from_email = forms.EmailField()
|
|
to_email = forms.EmailField(label="To")
|
|
|
|
|
|
class LeadForm(forms.ModelForm):
|
|
id_car_make = forms.ModelChoiceField(
|
|
label="Make",
|
|
queryset=CarMake.objects.filter(is_sa_import=True),
|
|
widget=forms.Select(
|
|
attrs={
|
|
"class": "form-control form-control-sm",
|
|
"hx-get": "",
|
|
"hx-include": "#id_id_car_make",
|
|
"hx-select": "#div_id_id_car_model",
|
|
"hx-target": "#div_id_id_car_model",
|
|
"hx-swap": "outerHTML",
|
|
"hx-on::before-request": "document.querySelector('#id_id_car_model').setAttribute('disabled', true)",
|
|
"hx-on::after-request": "document.querySelector('#id_id_car_model').removeAttribute('disabled')",
|
|
}
|
|
),
|
|
required=True,
|
|
)
|
|
id_car_model = forms.ModelChoiceField(
|
|
label="Model",
|
|
queryset=CarModel.objects.none(),
|
|
widget=forms.Select(attrs={"class": "form-control form-control-sm"}),
|
|
required=True,
|
|
)
|
|
|
|
class Meta:
|
|
model = Lead
|
|
fields = [
|
|
"first_name",
|
|
"last_name",
|
|
"email",
|
|
"phone_number",
|
|
"address",
|
|
"id_car_make",
|
|
"id_car_model",
|
|
"year",
|
|
"source",
|
|
"channel",
|
|
"staff",
|
|
"priority",
|
|
]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
if "id_car_make" in self.fields:
|
|
queryset = self.fields["id_car_make"].queryset.filter(is_sa_import=True)
|
|
self.fields["id_car_make"].choices = [
|
|
(obj.id_car_make, obj.get_local_name()) for obj in queryset
|
|
]
|
|
|
|
|
|
class ScheduleForm(forms.ModelForm):
|
|
scheduled_at = forms.DateTimeField(
|
|
widget=DateTimeInput(attrs={"type": "datetime-local"})
|
|
)
|
|
|
|
class Meta:
|
|
model = Schedule
|
|
fields = ["purpose", "scheduled_type", "scheduled_at", "duration", "notes"]
|
|
|
|
|
|
class NoteForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Notes
|
|
fields = ["note"]
|
|
|
|
|
|
class ActivityForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Activity
|
|
fields = ["activity_type", "notes"]
|
|
|
|
|
|
class OpportunityForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Opportunity
|
|
fields = ["customer", "car", "stage", "probability", "staff", "closing_date"]
|
|
|
|
|
|
class InvoiceModelCreateForm(InvoiceModelCreateFormBase):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
# self.fields["cash_account"].widget = forms.HiddenInput()
|
|
# self.fields["prepaid_account"].widget = forms.HiddenInput()
|
|
# self.fields["unearned_account"].widget = forms.HiddenInput()
|
|
self.fields["date_draft"] = forms.DateField(
|
|
widget=DateInput(attrs={"type": "date"})
|
|
)
|
|
|
|
def get_customer_queryset(self):
|
|
if "customer" in self.fields:
|
|
self.fields[
|
|
"customer"
|
|
].queryset = self.USER_MODEL.dealer.entity.get_customers()
|
|
|
|
|
|
class BillModelCreateForm(BillModelCreateFormBase):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.fields["cash_account"].widget = forms.HiddenInput()
|
|
self.fields["prepaid_account"].widget = forms.HiddenInput()
|
|
self.fields["unearned_account"].widget = forms.HiddenInput()
|
|
self.fields["date_draft"] = forms.DateField(
|
|
widget=DateInput(attrs={"type": "date"})
|
|
)
|
|
|
|
|
|
class SaleOrderForm(forms.ModelForm):
|
|
class Meta:
|
|
model = SaleOrder
|
|
fields = ["estimate", "payment_method", "comments"]
|
|
widgets = {
|
|
"comments": forms.Textarea(attrs={"rows": 3}),
|
|
}
|
|
|
|
|
|
class EstimateModelCreateForm(EstimateModelCreateFormBase):
|
|
class Meta:
|
|
model = ledger_models.EstimateModel
|
|
fields = ["title","customer", "terms"]
|
|
widgets = {
|
|
"customer": forms.Select(
|
|
attrs={
|
|
"id": "djl-customer-estimate-customer-input",
|
|
"class": "input",
|
|
"label": _("Customer"),
|
|
}
|
|
),
|
|
'terms': forms.Select(attrs={
|
|
'id': 'djl-customer-estimate-terms-input',
|
|
'class': 'input',
|
|
'label': _('Terms'),
|
|
}),
|
|
'title': forms.TextInput(attrs={
|
|
'id': 'djl-customer-job-title-input',
|
|
'class': 'input' + ' is-large',
|
|
'label': _('Title'),
|
|
})
|
|
}
|
|
labels = {
|
|
'title': _('Title'),
|
|
'terms': _('Terms'),
|
|
"customer": _("Customer"),
|
|
}
|
|
|
|
def __init__(self, *args, entity_slug, user_model, **kwargs):
|
|
super(EstimateModelCreateForm, self).__init__(
|
|
*args, entity_slug=entity_slug, user_model=user_model, **kwargs
|
|
)
|
|
self.ENTITY_SLUG = entity_slug
|
|
self.USER_MODEL = user_model
|
|
self.fields["customer"].queryset = self.get_customer_queryset()
|
|
|
|
def get_customer_queryset(self):
|
|
return self.USER_MODEL.dealer.entity.get_customers()
|
|
|
|
|
|
class OpportunityStatusForm(forms.Form):
|
|
status = forms.ChoiceField(
|
|
label="Status",
|
|
choices=Status.choices,
|
|
widget=forms.Select(
|
|
attrs={
|
|
"class": "form-control form-control-sm",
|
|
"hx-get": "{% url 'opportunity_update_status' opportunity.id %}",
|
|
"hx-target": ".other-information",
|
|
"hx-select": ".other-information",
|
|
"hx-swap": "outerHTML",
|
|
"hx-on::after-request": "this.setAttribute('disabled','true')",
|
|
"disabled": "disabled",
|
|
}
|
|
),
|
|
required=True,
|
|
)
|
|
stage = forms.ChoiceField(
|
|
label="Stage",
|
|
choices=Stage.choices,
|
|
widget=forms.Select(
|
|
attrs={
|
|
"class": "form-control form-control-sm",
|
|
"hx-target": ".other-information",
|
|
"hx-select": ".other-information",
|
|
"hx-swap": "outerHTML",
|
|
"hx-on::after-request": "this.setAttribute('disabled','true')",
|
|
"disabled": "disabled",
|
|
}
|
|
),
|
|
required=True,
|
|
)
|
|
|