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 .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( min_length=10, max_length=10, region="SA", ) address = forms.CharField() class OrganizationForm(forms.Form): name = forms.CharField() arabic_name = forms.CharField() email = forms.EmailField() phone_number = PhoneNumberField( min_length=10, max_length=10, 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): email = forms.EmailField( label=_("Email Address"), widget=forms.EmailInput( attrs={ "class": "form-control form-control-sm email", "placeholder": _("Email address"), "name": _("email"), "required": "required", } ), 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", } ), error_messages={ "required": _("This field is required."), }, ) confirm_password = forms.CharField( label=_("Confirm Password"), widget=forms.PasswordInput( attrs={ "class": "form-control form-control-sm", "placeholder": _("Confirm Password"), "required": "required", } ), error_messages={ "required": _("This field is required."), }, ) terms = forms.BooleanField( label=_("I accept the Terms and Privacy Policy"), widget=forms.CheckboxInput( attrs={ "class": "form-check-input", "required": "required", } ), error_messages={ "required": _("You must accept the terms and privacy policy."), }, ) 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"), min_length=10, max_length=10, widget=forms.TextInput( attrs={ "class": "form-control form-control-sm", "placeholder": _("Phone"), "required": "required", } ), region="SA", error_messages={ "required": _("This field is required."), "invalid": _("Phone number must be in the format 05xxxxxxxx"), }, ) 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"}), 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()