160 lines
9.1 KiB
Python
160 lines
9.1 KiB
Python
from django import forms
|
|
from .models import Truck, Shipment, Bid, Profile, Country, OTPCode, City, TruckType, AppSetting
|
|
from django.utils.translation import gettext_lazy as _
|
|
from django.contrib.auth.forms import UserCreationForm
|
|
from django.contrib.auth.models import User
|
|
|
|
class UserRegistrationForm(UserCreationForm):
|
|
email = forms.EmailField(required=True, widget=forms.EmailInput(attrs={'class': 'form-control'}))
|
|
confirm_email = forms.EmailField(required=True, widget=forms.EmailInput(attrs={'class': 'form-control'}), label=_("Confirm Email"))
|
|
role = forms.ChoiceField(choices=[choice for choice in Profile.ROLE_CHOICES if choice[0] != 'ADMIN'], widget=forms.Select(attrs={'class': 'form-select'}))
|
|
country_code = forms.ChoiceField(choices=[], widget=forms.Select(attrs={'class': 'form-select'}))
|
|
phone_number = forms.CharField(max_length=20, required=True, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '123456789'}))
|
|
subscription_plan = forms.ChoiceField(choices=[('MONTHLY', _('Monthly')), ('ANNUAL', _('Annual'))], required=False, widget=forms.Select(attrs={'class': 'form-select'}), label=_('Subscription Plan'))
|
|
accept_terms = forms.BooleanField(required=True, widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}), label=_('I have read and agree to the Terms and Conditions and Privacy Policy'))
|
|
|
|
class Meta(UserCreationForm.Meta):
|
|
model = User
|
|
fields = UserCreationForm.Meta.fields + ('email',)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
# Dynamic country codes from the database
|
|
countries = Country.objects.all()
|
|
if countries.exists():
|
|
self.fields['country_code'].choices = [(c.code, str(c)) for c in countries]
|
|
default_country = countries.filter(is_default=True).first()
|
|
if default_country:
|
|
self.fields['country_code'].initial = default_country.code
|
|
else:
|
|
# Fallback if no countries are defined yet
|
|
self.fields['country_code'].choices = [('966', 'Saudi Arabia (+966)')]
|
|
self.fields['country_code'].initial = '966'
|
|
|
|
app_settings = AppSetting.objects.first()
|
|
if app_settings and app_settings.subscription_enabled:
|
|
self.fields['subscription_plan'].choices = [
|
|
('MONTHLY', _('Monthly (%(fee)s)') % {'fee': app_settings.monthly_fee}),
|
|
('ANNUAL', _('Annual (%(fee)s)') % {'fee': app_settings.annual_fee}),
|
|
]
|
|
self.fields['subscription_plan'].required = True
|
|
else:
|
|
self.fields['subscription_plan'].required = False
|
|
|
|
for field in self.fields.values():
|
|
if not isinstance(field.widget, (forms.CheckboxInput, forms.Select)):
|
|
field.widget.attrs.update({'class': 'form-control'})
|
|
|
|
def clean_email(self):
|
|
email = self.cleaned_data.get('email')
|
|
if User.objects.filter(email=email).exists():
|
|
raise forms.ValidationError(_("This email is already in use."))
|
|
return email
|
|
|
|
def clean_phone_number(self):
|
|
phone_number = self.cleaned_data.get('phone_number')
|
|
country_code = self.cleaned_data.get('country_code')
|
|
# We check uniqueness of phone_number in Profile
|
|
if Profile.objects.filter(phone_number=phone_number).exists():
|
|
raise forms.ValidationError(_("This phone number is already in use."))
|
|
return phone_number
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
email = cleaned_data.get("email")
|
|
confirm_email = cleaned_data.get("confirm_email")
|
|
|
|
if email and confirm_email and email != confirm_email:
|
|
self.add_error('confirm_email', _("The two email fields didn't match."))
|
|
|
|
return cleaned_data
|
|
|
|
class OTPVerifyForm(forms.Form):
|
|
otp_code = forms.CharField(label=_("OTP Code"), max_length=6, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '123456'}))
|
|
|
|
class TruckForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Truck
|
|
fields = [
|
|
'truck_type_link', 'model', 'model_ar', 'year', 'plate_no',
|
|
'load_capacity', 'load_capacity_ar', 'color', 'color_ar', 'registration_expiry_date',
|
|
'truck_picture', 'registration_front', 'registration_back', 'driver_license_front', 'driver_license_back'
|
|
]
|
|
widgets = {
|
|
'truck_type_link': forms.Select(attrs={'class': 'form-select'}),
|
|
'model': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'model_ar': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'year': forms.NumberInput(attrs={'class': 'form-control'}),
|
|
'plate_no': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'load_capacity': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'load_capacity_ar': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'color': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'color_ar': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'registration_expiry_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
|
|
'truck_picture': forms.FileInput(attrs={'class': 'form-control'}),
|
|
'registration_front': forms.FileInput(attrs={'class': 'form-control'}),
|
|
'registration_back': forms.FileInput(attrs={'class': 'form-control'}),
|
|
'driver_license_front': forms.FileInput(attrs={'class': 'form-control'}),
|
|
'driver_license_back': forms.FileInput(attrs={'class': 'form-control'}),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.fields['truck_type_link'].label = _("Truck Type")
|
|
|
|
class ShipmentForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Shipment
|
|
fields = [
|
|
'description', 'weight', 'required_truck_type_link',
|
|
'origin_country', 'origin_city',
|
|
'destination_country', 'destination_city',
|
|
'delivery_date'
|
|
]
|
|
widgets = {
|
|
'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
|
|
'weight': forms.TextInput(attrs={'class': 'form-control'}),
|
|
'required_truck_type_link': forms.Select(attrs={'class': 'form-select'}),
|
|
'origin_country': forms.Select(attrs={'class': 'form-select location-selector', 'data-type': 'origin'}),
|
|
'origin_city': forms.Select(attrs={'class': 'form-select'}),
|
|
'destination_country': forms.Select(attrs={'class': 'form-select location-selector', 'data-type': 'destination'}),
|
|
'destination_city': forms.Select(attrs={'class': 'form-select'}),
|
|
'delivery_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.fields['required_truck_type_link'].label = _("Truck Type")
|
|
|
|
class BidForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Bid
|
|
fields = ['truck', 'amount', 'comments']
|
|
widgets = {
|
|
'truck': forms.Select(attrs={'class': 'form-select'}),
|
|
'amount': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}),
|
|
'comments': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
user = kwargs.pop('user', None)
|
|
super().__init__(*args, **kwargs)
|
|
if user:
|
|
# Only allow bidding with approved trucks
|
|
self.fields['truck'].queryset = Truck.objects.filter(owner=user, is_approved=True)
|
|
if not self.fields['truck'].queryset.exists():
|
|
self.fields['truck'].help_text = _("You must have an approved truck to place a bid.")
|
|
|
|
class ShipperOfferForm(forms.Form):
|
|
description = forms.CharField(label=_('Goods Description'), widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3}))
|
|
weight = forms.CharField(label=_('Weight/Volume'), widget=forms.TextInput(attrs={'class': 'form-control'}))
|
|
required_truck_type_link = forms.ModelChoiceField(label=_('Required Truck Type'), queryset=TruckType.objects.all(), widget=forms.Select(attrs={'class': 'form-select'}))
|
|
|
|
origin_country = forms.ModelChoiceField(queryset=Country.objects.all(), widget=forms.Select(attrs={'class': 'form-select location-selector', 'data-type': 'origin'}))
|
|
origin_city = forms.ModelChoiceField(queryset=City.objects.all(), widget=forms.Select(attrs={'class': 'form-select'}))
|
|
destination_country = forms.ModelChoiceField(queryset=Country.objects.all(), widget=forms.Select(attrs={'class': 'form-select location-selector', 'data-type': 'destination'}))
|
|
destination_city = forms.ModelChoiceField(queryset=City.objects.all(), widget=forms.Select(attrs={'class': 'form-select'}))
|
|
|
|
delivery_date = forms.DateField(label=_('Requested Delivery Date'), widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}))
|
|
amount = forms.DecimalField(label=_('Offer Amount'), max_digits=10, decimal_places=2, widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}))
|
|
comments = forms.CharField(label=_('Comments'), required=False, widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 2})) |