demo13
This commit is contained in:
parent
1654496646
commit
cdfcd5f4e8
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -3,7 +3,7 @@ from .models import Profile, Truck, Shipment, Bid, Message, WhatsAppConfig
|
|||||||
|
|
||||||
@admin.register(Profile)
|
@admin.register(Profile)
|
||||||
class ProfileAdmin(admin.ModelAdmin):
|
class ProfileAdmin(admin.ModelAdmin):
|
||||||
list_display = ('user', 'role', 'phone_number')
|
list_display = ('user', 'role', 'country_code', 'phone_number')
|
||||||
list_filter = ('role',)
|
list_filter = ('role',)
|
||||||
search_fields = ('user__username', 'phone_number')
|
search_fields = ('user__username', 'phone_number')
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@ class UserRegistrationForm(UserCreationForm):
|
|||||||
email = forms.EmailField(required=True, widget=forms.EmailInput(attrs={'class': 'form-control'}))
|
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"))
|
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'}))
|
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'}))
|
phone_number = forms.CharField(max_length=20, required=False, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '+1234567890'}))
|
||||||
|
|
||||||
class Meta(UserCreationForm.Meta):
|
class Meta(UserCreationForm.Meta):
|
||||||
|
|||||||
18
core/migrations/0007_profile_country_code.py
Normal file
18
core/migrations/0007_profile_country_code.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
||||||
Binary file not shown.
@ -13,8 +13,18 @@ class Profile(models.Model):
|
|||||||
)
|
)
|
||||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||||
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='SHIPPER')
|
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)
|
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):
|
def __str__(self):
|
||||||
return f"{self.user.username} - {self.role}"
|
return f"{self.user.username} - {self.role}"
|
||||||
|
|
||||||
@ -46,6 +56,15 @@ class Truck(models.Model):
|
|||||||
is_approved = models.BooleanField(_('Is Approved'), default=False)
|
is_approved = models.BooleanField(_('Is Approved'), default=False)
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
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):
|
def __str__(self):
|
||||||
return f"{self.display_truck_type} - {self.plate_no}"
|
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)
|
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):
|
def __str__(self):
|
||||||
return f"{self.origin} to {self.destination} - {self.status}"
|
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)
|
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):
|
def __str__(self):
|
||||||
return f"Bid by {self.truck_owner.username} for {self.shipment}"
|
return f"Bid by {self.truck_owner.username} for {self.shipment}"
|
||||||
|
|
||||||
@ -119,6 +156,15 @@ class Message(models.Model):
|
|||||||
content = models.TextField()
|
content = models.TextField()
|
||||||
timestamp = models.DateTimeField(auto_now_add=True)
|
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):
|
def __str__(self):
|
||||||
return f"From {self.sender.username} at {self.timestamp}"
|
return f"From {self.sender.username} at {self.timestamp}"
|
||||||
|
|
||||||
@ -131,6 +177,15 @@ class WhatsAppConfig(models.Model):
|
|||||||
verbose_name = _('WhatsApp Configuration')
|
verbose_name = _('WhatsApp Configuration')
|
||||||
verbose_name_plural = _('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):
|
def __str__(self):
|
||||||
return str(_("WhatsApp Configuration"))
|
return str(_("WhatsApp Configuration"))
|
||||||
|
|
||||||
|
|||||||
@ -22,18 +22,40 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% for field in form %}
|
{% for field in form %}
|
||||||
<div class="mb-3">
|
{% if field.name == 'country_code' %}
|
||||||
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
<div class="mb-3">
|
||||||
{{ field }}
|
<label class="form-label">{% trans "Phone Number" %}</label>
|
||||||
{% if field.help_text %}
|
<div class="input-group">
|
||||||
<div class="form-text text-muted small">{{ field.help_text|safe }}</div>
|
<span class="input-group-text">+</span>
|
||||||
{% endif %}
|
<div style="width: 80px;">
|
||||||
{% if field.errors %}
|
{{ form.country_code }}
|
||||||
{% for error in field.errors %}
|
</div>
|
||||||
<div class="text-danger small">{{ error }}</div>
|
{{ form.phone_number }}
|
||||||
{% endfor %}
|
</div>
|
||||||
{% endif %}
|
{% if form.phone_number.errors or form.country_code.errors %}
|
||||||
</div>
|
<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 %}
|
{% endfor %}
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary w-100 py-2 mt-3">{% trans "Register" %}</button>
|
<button type="submit" class="btn btn-primary w-100 py-2 mt-3">{% trans "Register" %}</button>
|
||||||
@ -47,4 +69,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -25,6 +25,7 @@ def register(request):
|
|||||||
profile = user.profile
|
profile = user.profile
|
||||||
profile.role = form.cleaned_data.get('role')
|
profile.role = form.cleaned_data.get('role')
|
||||||
profile.phone_number = form.cleaned_data.get('phone_number')
|
profile.phone_number = form.cleaned_data.get('phone_number')
|
||||||
|
profile.country_code = form.cleaned_data.get('country_code')
|
||||||
profile.save()
|
profile.save()
|
||||||
login(request, user)
|
login(request, user)
|
||||||
messages.success(request, _("Registration successful. Welcome!"))
|
messages.success(request, _("Registration successful. Welcome!"))
|
||||||
@ -116,7 +117,7 @@ def approve_truck(request, truck_id):
|
|||||||
truck.save()
|
truck.save()
|
||||||
|
|
||||||
# Notify Truck Owner via WhatsApp
|
# 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:
|
if owner_phone:
|
||||||
msg = f"Your truck ({truck.plate_no}) has been approved! You can now place bids on shipments."
|
msg = f"Your truck ({truck.plate_no}) has been approved! You can now place bids on shipments."
|
||||||
send_whatsapp_message(owner_phone, msg)
|
send_whatsapp_message(owner_phone, msg)
|
||||||
@ -183,7 +184,7 @@ def place_bid(request, shipment_id):
|
|||||||
bid.save()
|
bid.save()
|
||||||
|
|
||||||
# Notify Shipper via WhatsApp
|
# 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:
|
if shipper_phone:
|
||||||
msg = f"New bid placed on your shipment from {shipment.origin} to {shipment.destination}! Amount: {bid.amount}"
|
msg = f"New bid placed on your shipment from {shipment.origin} to {shipment.destination}! Amount: {bid.amount}"
|
||||||
send_whatsapp_message(shipper_phone, msg)
|
send_whatsapp_message(shipper_phone, msg)
|
||||||
@ -227,7 +228,7 @@ def accept_bid(request, bid_id):
|
|||||||
bid.shipment.save()
|
bid.shipment.save()
|
||||||
|
|
||||||
# Notify Truck Owner via WhatsApp
|
# 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:
|
if owner_phone:
|
||||||
msg = f"Congratulations! Your bid for the shipment from {bid.shipment.origin} to {bid.shipment.destination} has been accepted."
|
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)
|
send_whatsapp_message(owner_phone, msg)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user