from phonenumber_field.formfields import PhoneNumberField from django.core.validators import RegexValidator from django import forms from django.contrib.auth import get_user_model from .mixins import AddClassMixin from django.forms.models import inlineformset_factory from .models import ( Dealer, # Branch, Vendor, Customer, Car, CarFinance, CustomCard, CarRegistration, CarColors, ExteriorColors, InteriorColors, SaleQuotation, CarLocation, Organization, Representative, Payment, SaleQuotationCar, AdditionalServices, Staff, Opportunity ) from django_ledger.models import ItemModel from django.forms import ModelMultipleChoiceField, ValidationError 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): 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"}) ) 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): staff_instance = super().save(commit=False) user = staff_instance.user user.email = self.cleaned_data['email'] if commit: user.save() staff_instance.save() return staff_instance # Dealer Form class DealerForm(forms.ModelForm): class Meta: model = Dealer fields = ['name', 'arabic_name', 'crn', 'vrn', 'phone_number', 'address', 'logo'] # Customer Form class CustomerForm(forms.ModelForm, AddClassMixin): class Meta: model = Customer fields = [ 'first_name', 'middle_name', 'last_name', 'email', 'national_id', 'phone_number', 'address' ] 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: 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(AddClassMixin, 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', 'additional_finances','profit_margin', 'vat_amount', 'total', 'vat_rate','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'}), } # 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 = [ 'car', 'plate_number', 'text1', 'text2', 'text3', 'registration_date' ] 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( widget=forms.EmailInput(attrs={ 'class': 'form-control', 'placeholder': 'Email address', 'required': 'required', }), error_messages={ 'required': _('You must add an email.'), } ) password = forms.CharField( widget=forms.PasswordInput(attrs={ 'class': 'form-control', 'placeholder': _('Password'), 'required': 'required', }), error_messages={ 'required': _('This field is required.'), } ) confirm_password = forms.CharField( widget=forms.PasswordInput(attrs={ 'class': 'form-control', 'placeholder': _('Confirm Password'), 'required': 'required', }), error_messages={ 'required': _('This field is required.'), } ) terms = forms.BooleanField( 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( widget=forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': _('English Name'), 'required': 'required', }), error_messages={ 'required': _('Please enter an English Name.'), } ) arabic_name = forms.CharField( widget=forms.TextInput(attrs={ 'class': 'form-control', 'placeholder': _('Arabic Name'), 'required': 'required', }), error_messages={ 'required': _('Please enter an Arabic name.'), } ) phone_number = PhoneNumberField( min_length=10, max_length=10, widget=forms.TextInput(attrs={ 'class': 'form-control', '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( widget=forms.TextInput(attrs={ 'class': 'form-control', '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( widget=forms.TextInput(attrs={ 'class': 'form-control', '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( widget=forms.Textarea(attrs={ 'class': 'form-control', '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=ItemModel.objects.all(),label="Item", required=True) 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 OpportunityForm(forms.ModelForm): class Meta: model = Opportunity fields = [ 'car', 'deal_name', 'deal_value', 'deal_status', 'priority', 'source' ] widgets = { 'deal_status': forms.Select(choices=Opportunity.DEAL_STATUS_CHOICES), 'priority': forms.Select(choices=Opportunity.PRIORITY_CHOICES), 'source': forms.Select(choices=Opportunity.DEAL_SOURCES_CHOICES), }