This commit is contained in:
Flatlogic Bot 2026-01-23 12:14:40 +00:00
parent 1654496646
commit cdfcd5f4e8
11 changed files with 114 additions and 17 deletions

View File

@ -3,7 +3,7 @@ from .models import Profile, Truck, Shipment, Bid, Message, WhatsAppConfig
@admin.register(Profile)
class ProfileAdmin(admin.ModelAdmin):
list_display = ('user', 'role', 'phone_number')
list_display = ('user', 'role', 'country_code', 'phone_number')
list_filter = ('role',)
search_fields = ('user__username', 'phone_number')

View File

@ -8,6 +8,7 @@ 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'}))
class Meta(UserCreationForm.Meta):

View File

@ -0,0 +1,18 @@
# Generated by Django 5.2.7 on 2026-01-23 12:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0006_whatsappconfig'),
]
operations = [
migrations.AddField(
model_name='profile',
name='country_code',
field=models.CharField(blank=True, default='966', max_length=5),
),
]

View File

@ -13,8 +13,18 @@ class Profile(models.Model):
)
user = models.OneToOneField(User, on_delete=models.CASCADE)
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='SHIPPER')
country_code = models.CharField(max_length=5, blank=True, default="966")
phone_number = models.CharField(max_length=20, blank=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.user.username} - {self.role}"
@ -46,6 +56,15 @@ 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}"
@ -92,6 +111,15 @@ 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}"
@ -110,6 +138,15 @@ 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}"
@ -119,6 +156,15 @@ 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}"
@ -131,6 +177,15 @@ 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"))

View File

@ -22,18 +22,40 @@
{% endif %}
{% for field in form %}
<div class="mb-3">
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
{% if field.help_text %}
<div class="form-text text-muted small">{{ field.help_text|safe }}</div>
{% endif %}
{% if field.errors %}
{% for error in field.errors %}
<div class="text-danger small">{{ error }}</div>
{% endfor %}
{% endif %}
</div>
{% if field.name == 'country_code' %}
<div class="mb-3">
<label class="form-label">{% trans "Phone Number" %}</label>
<div class="input-group">
<span class="input-group-text">+</span>
<div style="width: 80px;">
{{ form.country_code }}
</div>
{{ form.phone_number }}
</div>
{% if form.phone_number.errors or form.country_code.errors %}
<div class="text-danger small">
{% for error in form.country_code.errors %}{{ error }} {% endfor %}
{% 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>
{% elif field.name == 'phone_number' %}
{# Handled above #}
{% else %}
<div class="mb-3">
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
{% if field.help_text %}
<div class="form-text text-muted small">{{ field.help_text|safe }}</div>
{% endif %}
{% if field.errors %}
{% for error in field.errors %}
<div class="text-danger small">{{ error }}</div>
{% endfor %}
{% endif %}
</div>
{% endif %}
{% endfor %}
<button type="submit" class="btn btn-primary w-100 py-2 mt-3">{% trans "Register" %}</button>
@ -47,4 +69,4 @@
</div>
</div>
</section>
{% endblock %}
{% endblock %}

View File

@ -25,6 +25,7 @@ def register(request):
profile = user.profile
profile.role = form.cleaned_data.get('role')
profile.phone_number = form.cleaned_data.get('phone_number')
profile.country_code = form.cleaned_data.get('country_code')
profile.save()
login(request, user)
messages.success(request, _("Registration successful. Welcome!"))
@ -116,7 +117,7 @@ def approve_truck(request, truck_id):
truck.save()
# Notify Truck Owner via WhatsApp
owner_phone = getattr(truck.owner.profile, 'phone_number', None)
owner_phone = getattr(truck.owner.profile, 'full_phone_number', None)
if owner_phone:
msg = f"Your truck ({truck.plate_no}) has been approved! You can now place bids on shipments."
send_whatsapp_message(owner_phone, msg)
@ -183,7 +184,7 @@ def place_bid(request, shipment_id):
bid.save()
# Notify Shipper via WhatsApp
shipper_phone = getattr(shipment.shipper.profile, 'phone_number', None)
shipper_phone = getattr(shipment.shipper.profile, 'full_phone_number', None)
if shipper_phone:
msg = f"New bid placed on your shipment from {shipment.origin} to {shipment.destination}! Amount: {bid.amount}"
send_whatsapp_message(shipper_phone, msg)
@ -227,7 +228,7 @@ def accept_bid(request, bid_id):
bid.shipment.save()
# Notify Truck Owner via WhatsApp
owner_phone = getattr(bid.truck_owner.profile, 'phone_number', None)
owner_phone = getattr(bid.truck_owner.profile, 'full_phone_number', None)
if owner_phone:
msg = f"Congratulations! Your bid for the shipment from {bid.shipment.origin} to {bid.shipment.destination} has been accepted."
send_whatsapp_message(owner_phone, msg)