adding profile
This commit is contained in:
parent
bae3510e83
commit
59f1cf28c3
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
from django.contrib import admin
|
||||
from .models import Profile, Parcel, Country, Governate, City
|
||||
from .models import Profile, Parcel, Country, Governate, City, PlatformProfile
|
||||
|
||||
@admin.register(Country)
|
||||
class CountryAdmin(admin.ModelAdmin):
|
||||
@ -29,4 +29,14 @@ class ParcelAdmin(admin.ModelAdmin):
|
||||
list_display = ('tracking_number', 'shipper', 'carrier', 'status', 'payment_status', 'created_at')
|
||||
list_filter = ('status', 'payment_status', 'pickup_country', 'delivery_country')
|
||||
search_fields = ('tracking_number', 'shipper__username', 'carrier__username', 'receiver_name')
|
||||
readonly_fields = ('tracking_number', 'created_at', 'updated_at')
|
||||
readonly_fields = ('tracking_number', 'created_at', 'updated_at')
|
||||
|
||||
@admin.register(PlatformProfile)
|
||||
class PlatformProfileAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'phone_number', 'registration_number')
|
||||
|
||||
def has_add_permission(self, request):
|
||||
# Allow adding only if no instance exists
|
||||
if self.model.objects.exists():
|
||||
return False
|
||||
return super().has_add_permission(request)
|
||||
|
||||
@ -31,6 +31,11 @@ class UserRegistrationForm(forms.ModelForm):
|
||||
|
||||
self.fields['country'].queryset = Country.objects.all().order_by(name_field)
|
||||
|
||||
# Default Country logic
|
||||
oman = Country.objects.filter(name_en='Oman').first()
|
||||
if oman:
|
||||
self.fields['country'].initial = oman
|
||||
|
||||
if 'country' in self.data:
|
||||
try:
|
||||
country_id = int(self.data.get('country'))
|
||||
@ -39,6 +44,8 @@ class UserRegistrationForm(forms.ModelForm):
|
||||
pass
|
||||
elif self.instance.pk and hasattr(self.instance, 'profile') and self.instance.profile.country:
|
||||
self.fields['governate'].queryset = self.instance.profile.country.governate_set.order_by(name_field)
|
||||
elif oman:
|
||||
self.fields['governate'].queryset = Governate.objects.filter(country=oman).order_by(name_field)
|
||||
|
||||
if 'governate' in self.data:
|
||||
try:
|
||||
@ -122,6 +129,12 @@ class ParcelForm(forms.ModelForm):
|
||||
# Set querysets for countries
|
||||
self.fields['pickup_country'].queryset = Country.objects.all().order_by(name_field)
|
||||
self.fields['delivery_country'].queryset = Country.objects.all().order_by(name_field)
|
||||
|
||||
# Default Country logic
|
||||
oman = Country.objects.filter(name_en='Oman').first()
|
||||
if oman:
|
||||
self.fields['pickup_country'].initial = oman
|
||||
self.fields['delivery_country'].initial = oman
|
||||
|
||||
# Pickup
|
||||
self.fields['pickup_governate'].queryset = Governate.objects.none()
|
||||
@ -133,6 +146,8 @@ class ParcelForm(forms.ModelForm):
|
||||
self.fields['pickup_governate'].queryset = Governate.objects.filter(country_id=country_id).order_by(name_field)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
elif oman:
|
||||
self.fields['pickup_governate'].queryset = Governate.objects.filter(country=oman).order_by(name_field)
|
||||
|
||||
if 'pickup_governate' in self.data:
|
||||
try:
|
||||
@ -151,10 +166,12 @@ class ParcelForm(forms.ModelForm):
|
||||
self.fields['delivery_governate'].queryset = Governate.objects.filter(country_id=country_id).order_by(name_field)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
elif oman:
|
||||
self.fields['delivery_governate'].queryset = Governate.objects.filter(country=oman).order_by(name_field)
|
||||
|
||||
if 'delivery_governate' in self.data:
|
||||
try:
|
||||
gov_id = int(self.data.get('delivery_governate'))
|
||||
self.fields['delivery_city'].queryset = City.objects.filter(governate_id=gov_id).order_by(name_field)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
pass
|
||||
30
core/migrations/0007_platformprofile.py
Normal file
30
core/migrations/0007_platformprofile.py
Normal file
@ -0,0 +1,30 @@
|
||||
# Generated by Django 5.2.7 on 2026-01-25 10:54
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0006_alter_city_name_ar_alter_city_name_en_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='PlatformProfile',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=100, verbose_name='Platform Name')),
|
||||
('logo', models.ImageField(blank=True, null=True, upload_to='platform_logos/', verbose_name='Logo')),
|
||||
('slogan', models.CharField(blank=True, max_length=255, verbose_name='Slogan')),
|
||||
('address', models.TextField(blank=True, verbose_name='Address')),
|
||||
('phone_number', models.CharField(blank=True, max_length=50, verbose_name='Phone Number')),
|
||||
('registration_number', models.CharField(blank=True, max_length=100, verbose_name='Registration Number')),
|
||||
('vat_number', models.CharField(blank=True, max_length=100, verbose_name='VAT Number')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Platform Profile',
|
||||
'verbose_name_plural': 'Platform Profile',
|
||||
},
|
||||
),
|
||||
]
|
||||
BIN
core/migrations/__pycache__/0007_platformprofile.cpython-311.pyc
Normal file
BIN
core/migrations/__pycache__/0007_platformprofile.cpython-311.pyc
Normal file
Binary file not shown.
@ -144,4 +144,20 @@ class Parcel(models.Model):
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Parcel')
|
||||
verbose_name_plural = _('Parcels')
|
||||
verbose_name_plural = _('Parcels')
|
||||
|
||||
class PlatformProfile(models.Model):
|
||||
name = models.CharField(_('Platform Name'), max_length=100)
|
||||
logo = models.ImageField(_('Logo'), upload_to='platform_logos/', blank=True, null=True)
|
||||
slogan = models.CharField(_('Slogan'), max_length=255, blank=True)
|
||||
address = models.TextField(_('Address'), blank=True)
|
||||
phone_number = models.CharField(_('Phone Number'), max_length=50, blank=True)
|
||||
registration_number = models.CharField(_('Registration Number'), max_length=100, blank=True)
|
||||
vat_number = models.CharField(_('VAT Number'), max_length=100, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Platform Profile')
|
||||
verbose_name_plural = _('Platform Profile')
|
||||
|
||||
@ -19,7 +19,11 @@
|
||||
{% endif %}
|
||||
|
||||
<!-- Bootstrap 5 -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
{% if lang.direction == 'rtl' %}
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.rtl.min.css">
|
||||
{% else %}
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
{% endif %}
|
||||
<!-- Bootstrap Icons -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
||||
|
||||
@ -28,20 +32,9 @@
|
||||
|
||||
{% if lang.direction == 'rtl' %}
|
||||
<style>
|
||||
/* Additional RTL overrides if needed */
|
||||
body {
|
||||
text-align: right;
|
||||
}
|
||||
.ms-auto {
|
||||
margin-right: auto !important;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
.me-auto {
|
||||
margin-left: auto !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
.dropdown-menu-end {
|
||||
left: 0 !important;
|
||||
right: auto !important;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* Example font suitable for Arabic */
|
||||
}
|
||||
</style>
|
||||
{% endif %}
|
||||
|
||||
@ -49,7 +49,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
citySelect.innerHTML = '<option value="">{% trans "Select City" %}</option>';
|
||||
|
||||
if (countryId) {
|
||||
fetch(`/ajax/get-governates/?country_id=${countryId}`)
|
||||
fetch(`{% url 'get_governates' %}?country_id=${countryId}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
data.forEach(gov => {
|
||||
@ -67,7 +67,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
citySelect.innerHTML = '<option value="">{% trans "Select City" %}</option>';
|
||||
|
||||
if (governateId) {
|
||||
fetch(`/ajax/get-cities/?governate_id=${governateId}`)
|
||||
fetch(`{% url 'get_cities' %}?governate_id=${governateId}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
data.forEach(city => {
|
||||
|
||||
@ -11,15 +11,114 @@
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
<div class="row g-3">
|
||||
{% for field in form %}
|
||||
<div class="{% if field.name == 'description' %}col-12{% else %}col-md-6{% endif %}">
|
||||
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||
{{ field }}
|
||||
{% if field.errors %}
|
||||
<div class="text-danger small">{{ field.errors }}</div>
|
||||
<!-- General Info -->
|
||||
<div class="col-12">
|
||||
<label class="form-label" for="{{ form.description.id_for_label }}">{{ form.description.label }}</label>
|
||||
{{ form.description }}
|
||||
{% if form.description.errors %}
|
||||
<div class="text-danger small">{{ form.description.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="{{ form.weight.id_for_label }}">{{ form.weight.label }}</label>
|
||||
{{ form.weight }}
|
||||
{% if form.weight.errors %}
|
||||
<div class="text-danger small">{{ form.weight.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="{{ form.price.id_for_label }}">{{ form.price.label }}</label>
|
||||
{{ form.price }}
|
||||
{% if form.price.errors %}
|
||||
<div class="text-danger small">{{ form.price.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Pickup Details -->
|
||||
<div class="col-12 mt-4">
|
||||
<h4 class="mb-3 text-secondary border-bottom pb-2">{% trans "Pickup Details" %}</h4>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="{{ form.pickup_country.id_for_label }}">{{ form.pickup_country.label }}</label>
|
||||
{{ form.pickup_country }}
|
||||
{% if form.pickup_country.errors %}
|
||||
<div class="text-danger small">{{ form.pickup_country.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="{{ form.pickup_governate.id_for_label }}">{{ form.pickup_governate.label }}</label>
|
||||
{{ form.pickup_governate }}
|
||||
{% if form.pickup_governate.errors %}
|
||||
<div class="text-danger small">{{ form.pickup_governate.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="{{ form.pickup_city.id_for_label }}">{{ form.pickup_city.label }}</label>
|
||||
{{ form.pickup_city }}
|
||||
{% if form.pickup_city.errors %}
|
||||
<div class="text-danger small">{{ form.pickup_city.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="{{ form.pickup_address.id_for_label }}">{{ form.pickup_address.label }}</label>
|
||||
{{ form.pickup_address }}
|
||||
{% if form.pickup_address.errors %}
|
||||
<div class="text-danger small">{{ form.pickup_address.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Delivery Details -->
|
||||
<div class="col-12 mt-4">
|
||||
<h4 class="mb-3 text-secondary border-bottom pb-2">{% trans "Delivery Details" %}</h4>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="{{ form.delivery_country.id_for_label }}">{{ form.delivery_country.label }}</label>
|
||||
{{ form.delivery_country }}
|
||||
{% if form.delivery_country.errors %}
|
||||
<div class="text-danger small">{{ form.delivery_country.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="{{ form.delivery_governate.id_for_label }}">{{ form.delivery_governate.label }}</label>
|
||||
{{ form.delivery_governate }}
|
||||
{% if form.delivery_governate.errors %}
|
||||
<div class="text-danger small">{{ form.delivery_governate.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="{{ form.delivery_city.id_for_label }}">{{ form.delivery_city.label }}</label>
|
||||
{{ form.delivery_city }}
|
||||
{% if form.delivery_city.errors %}
|
||||
<div class="text-danger small">{{ form.delivery_city.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="{{ form.delivery_address.id_for_label }}">{{ form.delivery_address.label }}</label>
|
||||
{{ form.delivery_address }}
|
||||
{% if form.delivery_address.errors %}
|
||||
<div class="text-danger small">{{ form.delivery_address.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Receiver Details -->
|
||||
<div class="col-12 mt-4">
|
||||
<h4 class="mb-3 text-secondary border-bottom pb-2">{% trans "Receiver Details" %}</h4>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="{{ form.receiver_name.id_for_label }}">{{ form.receiver_name.label }}</label>
|
||||
{{ form.receiver_name }}
|
||||
{% if form.receiver_name.errors %}
|
||||
<div class="text-danger small">{{ form.receiver_name.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="{{ form.receiver_phone.id_for_label }}">{{ form.receiver_phone.label }}</label>
|
||||
{{ form.receiver_phone }}
|
||||
{% if form.receiver_phone.errors %}
|
||||
<div class="text-danger small">{{ form.receiver_phone.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="col-12 mt-4">
|
||||
<button type="submit" class="btn btn-masarx-primary w-100 py-3">{% trans "Submit Request" %}</button>
|
||||
</div>
|
||||
@ -45,7 +144,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
citySelect.innerHTML = '<option value="">{% trans "Select City" %}</option>';
|
||||
|
||||
if (val) {
|
||||
fetch(`/ajax/get-governates/?country_id=${val}`)
|
||||
fetch(`{% url 'get_governates' %}?country_id=${val}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
data.forEach(item => {
|
||||
@ -63,7 +162,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
citySelect.innerHTML = '<option value="">{% trans "Select City" %}</option>';
|
||||
|
||||
if (val) {
|
||||
fetch(`/ajax/get-cities/?governate_id=${val}`)
|
||||
fetch(`{% url 'get_cities' %}?governate_id=${val}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
data.forEach(item => {
|
||||
@ -81,4 +180,4 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
setupDependentDropdowns('id_delivery_country', 'id_delivery_governate', 'id_delivery_city');
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
Binary file not shown.
@ -435,4 +435,54 @@ msgstr "لقد قبلت الشحنة!"
|
||||
|
||||
#: core/views.py:91
|
||||
msgid "Status updated successfully!"
|
||||
msgstr "تم تحديث الحالة بنجاح!"
|
||||
msgstr "تم تحديث الحالة بنجاح!"
|
||||
|
||||
#: core/templates/core/shipment_request.html:38
|
||||
msgid "Pickup Details"
|
||||
msgstr "تفاصيل الاستلام"
|
||||
|
||||
#: core/templates/core/shipment_request.html:64
|
||||
msgid "Delivery Details"
|
||||
msgstr "تفاصيل التوصيل"
|
||||
|
||||
#: core/templates/core/shipment_request.html:90
|
||||
msgid "Receiver Details"
|
||||
msgstr "تفاصيل المستلم"
|
||||
|
||||
#: core/templates/core/shipment_request.html:113
|
||||
msgid "Select Governate"
|
||||
msgstr "اختر المحافظة"
|
||||
|
||||
#: core/templates/core/shipment_request.html:114
|
||||
msgid "Select City"
|
||||
msgstr "اختر المدينة"
|
||||
|
||||
msgid "Shipping Price (OMR)"
|
||||
msgstr "سعر الشحن (ر.ع)"
|
||||
|
||||
msgid "Pickup Country"
|
||||
msgstr "دولة الاستلام"
|
||||
|
||||
msgid "Pickup Governate"
|
||||
msgstr "محافظة الاستلام"
|
||||
|
||||
msgid "Pickup City"
|
||||
msgstr "مدينة الاستلام"
|
||||
|
||||
msgid "Pickup Address (Street/Building)"
|
||||
msgstr "عنوان الاستلام (الشارع/المبنى)"
|
||||
|
||||
msgid "Delivery Country"
|
||||
msgstr "دولة التوصيل"
|
||||
|
||||
msgid "Delivery Governate"
|
||||
msgstr "محافظة التوصيل"
|
||||
|
||||
msgid "Delivery City"
|
||||
msgstr "مدينة التوصيل"
|
||||
|
||||
msgid "Delivery Address (Street/Building)"
|
||||
msgstr "عنوان التوصيل (الشارع/المبنى)"
|
||||
|
||||
msgid "Street/Building"
|
||||
msgstr "الشارع/المبنى"
|
||||
@ -1,3 +1,4 @@
|
||||
Django==5.2.7
|
||||
mysqlclient==2.2.7
|
||||
python-dotenv==1.1.1
|
||||
Pillow
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user