This commit is contained in:
Flatlogic Bot 2026-01-23 12:24:32 +00:00
parent cdfcd5f4e8
commit 53e281bd22
9 changed files with 65 additions and 55 deletions

View File

@ -1,5 +1,10 @@
from django.contrib import admin
from .models import Profile, Truck, Shipment, Bid, Message, WhatsAppConfig
from .models import Profile, Truck, Shipment, Bid, Message, WhatsAppConfig, Country
@admin.register(Country)
class CountryAdmin(admin.ModelAdmin):
list_display = ('name', 'code', 'is_default')
list_editable = ('is_default',)
@admin.register(Profile)
class ProfileAdmin(admin.ModelAdmin):
@ -37,4 +42,4 @@ class WhatsAppConfigAdmin(admin.ModelAdmin):
# Only allow one configuration record
if self.model.objects.exists():
return False
return super().has_add_permission(request)
return super().has_add_permission(request)

View File

@ -1,5 +1,5 @@
from django import forms
from .models import Truck, Shipment, Bid, Profile
from .models import Truck, Shipment, Bid, Profile, Country
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
@ -8,8 +8,8 @@ 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=Profile.ROLE_CHOICES, widget=forms.Select(attrs={'class': 'form-select'}))
country_code = forms.CharField(max_length=5, required=True, initial='966', widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '966'}))
phone_number = forms.CharField(max_length=20, required=False, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '+1234567890'}))
country_code = forms.ChoiceField(choices=[], widget=forms.Select(attrs={'class': 'form-select'}))
phone_number = forms.CharField(max_length=20, required=False, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '123456789'}))
class Meta(UserCreationForm.Meta):
model = User
@ -17,6 +17,18 @@ class UserRegistrationForm(UserCreationForm):
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'
for field in self.fields.values():
if not isinstance(field.widget, (forms.CheckboxInput, forms.Select)):
field.widget.attrs.update({'class': 'form-control'})
@ -86,4 +98,4 @@ class BidForm(forms.ModelForm):
# 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.")
self.fields['truck'].help_text = _("You must have an approved truck to place a bid.")

View File

@ -0,0 +1,26 @@
# Generated by Django 5.2.7 on 2026-01-23 12:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0007_profile_country_code'),
]
operations = [
migrations.CreateModel(
name='Country',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100, verbose_name='Country Name')),
('code', models.CharField(max_length=10, verbose_name='Country Code')),
('is_default', models.BooleanField(default=False, verbose_name='Is Default')),
],
options={
'verbose_name': 'Country',
'verbose_name_plural': 'Countries',
},
),
]

View File

@ -5,6 +5,18 @@ from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _
from django.utils.translation import get_language
class Country(models.Model):
name = models.CharField(_('Country Name'), max_length=100)
code = models.CharField(_('Country Code'), max_length=10)
is_default = models.BooleanField(_('Is Default'), default=False)
class Meta:
verbose_name = _('Country')
verbose_name_plural = _('Countries')
def __str__(self):
return f"{self.name} (+{self.code})"
class Profile(models.Model):
ROLE_CHOICES = (
('SHIPPER', _('Shipper (Need Goods Moved)')),
@ -56,15 +68,6 @@ class Truck(models.Model):
is_approved = models.BooleanField(_('Is Approved'), default=False)
created_at = models.DateTimeField(auto_now_add=True)
@property
def full_phone_number(self):
if not self.phone_number:
return ""
# Remove any existing leading + from country code and phone number
cc = str(self.country_code).replace("+", "").strip()
pn = str(self.phone_number).replace("+", "").strip()
return f"{cc}{pn}"
def __str__(self):
return f"{self.display_truck_type} - {self.plate_no}"
@ -111,15 +114,6 @@ class Shipment(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
@property
def full_phone_number(self):
if not self.phone_number:
return ""
# Remove any existing leading + from country code and phone number
cc = str(self.country_code).replace("+", "").strip()
pn = str(self.phone_number).replace("+", "").strip()
return f"{cc}{pn}"
def __str__(self):
return f"{self.origin} to {self.destination} - {self.status}"
@ -138,15 +132,6 @@ class Bid(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
@property
def full_phone_number(self):
if not self.phone_number:
return ""
# Remove any existing leading + from country code and phone number
cc = str(self.country_code).replace("+", "").strip()
pn = str(self.phone_number).replace("+", "").strip()
return f"{cc}{pn}"
def __str__(self):
return f"Bid by {self.truck_owner.username} for {self.shipment}"
@ -156,15 +141,6 @@ class Message(models.Model):
content = models.TextField()
timestamp = models.DateTimeField(auto_now_add=True)
@property
def full_phone_number(self):
if not self.phone_number:
return ""
# Remove any existing leading + from country code and phone number
cc = str(self.country_code).replace("+", "").strip()
pn = str(self.phone_number).replace("+", "").strip()
return f"{cc}{pn}"
def __str__(self):
return f"From {self.sender.username} at {self.timestamp}"
@ -177,15 +153,6 @@ class WhatsAppConfig(models.Model):
verbose_name = _('WhatsApp Configuration')
verbose_name_plural = _('WhatsApp Configuration')
@property
def full_phone_number(self):
if not self.phone_number:
return ""
# Remove any existing leading + from country code and phone number
cc = str(self.country_code).replace("+", "").strip()
pn = str(self.phone_number).replace("+", "").strip()
return f"{cc}{pn}"
def __str__(self):
return str(_("WhatsApp Configuration"))
@ -199,4 +166,4 @@ def save_user_profile(sender, instance, **kwargs):
if hasattr(instance, 'profile'):
instance.profile.save()
else:
Profile.objects.create(user=instance)
Profile.objects.create(user=instance)

View File

@ -27,7 +27,7 @@
<label class="form-label">{% trans "Phone Number" %}</label>
<div class="input-group">
<span class="input-group-text">+</span>
<div style="width: 80px;">
<div class="flex-grow-0" style="min-width: 150px;">
{{ form.country_code }}
</div>
{{ form.phone_number }}
@ -38,7 +38,7 @@
{% for error in form.phone_number.errors %}{{ error }} {% endfor %}
</div>
{% endif %}
<div class="form-text text-muted small">{% trans "Enter country code (e.g. 966) and phone number." %}</div>
<div class="form-text text-muted small">{% trans "Select country and enter phone number." %}</div>
</div>
{% elif field.name == 'phone_number' %}
{# Handled above #}
@ -69,4 +69,4 @@
</div>
</div>
</section>
{% endblock %}
{% endblock %}