adding subscription fee
This commit is contained in:
parent
081f578fb5
commit
9726a81f0c
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -25,8 +25,8 @@ class TruckTypeAdmin(admin.ModelAdmin):
|
||||
|
||||
@admin.register(Profile)
|
||||
class ProfileAdmin(admin.ModelAdmin):
|
||||
list_display = ('user', 'role', 'country_code', 'phone_number')
|
||||
list_filter = ('role',)
|
||||
list_display = ('user', 'role', 'country_code', 'phone_number', 'subscription_plan', 'is_subscription_active')
|
||||
list_filter = ('role', 'subscription_plan', 'is_subscription_active')
|
||||
search_fields = ('user__username', 'phone_number')
|
||||
|
||||
@admin.register(Truck)
|
||||
@ -90,7 +90,13 @@ class WhatsAppConfigAdmin(admin.ModelAdmin):
|
||||
|
||||
@admin.register(AppSetting)
|
||||
class AppSettingAdmin(admin.ModelAdmin):
|
||||
list_display = ('app_name', 'contact_phone', 'contact_email')
|
||||
list_display = ('app_name', 'contact_phone', 'contact_email', 'subscription_enabled')
|
||||
fieldsets = (
|
||||
(None, {'fields': ('app_name', 'logo', 'slogan')}),
|
||||
(_('Contact Information'), {'fields': ('contact_phone', 'contact_email', 'contact_address')}),
|
||||
(_('Legal'), {'fields': ('registration_number', 'tax_number', 'terms_of_service', 'privacy_policy')}),
|
||||
(_('Subscription'), {'fields': ('subscription_enabled', 'monthly_fee', 'annual_fee')}),
|
||||
)
|
||||
|
||||
def has_add_permission(self, request):
|
||||
# Only allow one configuration record
|
||||
@ -109,4 +115,4 @@ class HomeSectionAdmin(admin.ModelAdmin):
|
||||
list_display = ('title', 'section_type', 'order', 'is_active')
|
||||
list_editable = ('order', 'is_active')
|
||||
list_filter = ('section_type', 'is_active', 'background_color')
|
||||
search_fields = ('title', 'title_ar', 'subtitle', 'subtitle_ar', 'content', 'content_ar')
|
||||
search_fields = ('title', 'title_ar', 'subtitle', 'subtitle_ar', 'content', 'content_ar')
|
||||
@ -1,5 +1,5 @@
|
||||
from django import forms
|
||||
from .models import Truck, Shipment, Bid, Profile, Country, OTPCode, City, TruckType
|
||||
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
|
||||
@ -10,6 +10,8 @@ class UserRegistrationForm(UserCreationForm):
|
||||
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
|
||||
@ -29,6 +31,16 @@ class UserRegistrationForm(UserCreationForm):
|
||||
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'})
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
# Generated by Django 5.2.7 on 2026-01-24 03:28
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0016_homesection'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='appsetting',
|
||||
name='annual_fee',
|
||||
field=models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='Annual Fee'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='appsetting',
|
||||
name='monthly_fee',
|
||||
field=models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='Monthly Fee'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='appsetting',
|
||||
name='subscription_enabled',
|
||||
field=models.BooleanField(default=False, verbose_name='Enable Subscription Fee'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='profile',
|
||||
name='is_subscription_active',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='profile',
|
||||
name='subscription_expiry',
|
||||
field=models.DateField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='profile',
|
||||
name='subscription_plan',
|
||||
field=models.CharField(choices=[('MONTHLY', 'Monthly'), ('ANNUAL', 'Annual'), ('NONE', 'None')], default='NONE', max_length=20),
|
||||
),
|
||||
]
|
||||
Binary file not shown.
@ -53,6 +53,14 @@ class Profile(models.Model):
|
||||
)
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='SHIPPER')
|
||||
SUBSCRIPTION_CHOICES = (
|
||||
('MONTHLY', _('Monthly')),
|
||||
('ANNUAL', _('Annual')),
|
||||
('NONE', _('None')),
|
||||
)
|
||||
subscription_plan = models.CharField(max_length=20, choices=SUBSCRIPTION_CHOICES, default='NONE')
|
||||
subscription_expiry = models.DateField(null=True, blank=True)
|
||||
is_subscription_active = models.BooleanField(default=False)
|
||||
country_code = models.CharField(max_length=5, blank=True, default="966")
|
||||
phone_number = models.CharField(max_length=20, unique=True, null=True) # Changed to unique and nullable for migration safety
|
||||
|
||||
@ -240,6 +248,9 @@ class AppSetting(models.Model):
|
||||
contact_address = models.TextField(_('Contact Address'), blank=True)
|
||||
terms_of_service = models.TextField(_('Terms of Service'), blank=True)
|
||||
privacy_policy = models.TextField(_('Privacy Policy'), blank=True)
|
||||
subscription_enabled = models.BooleanField(_('Enable Subscription Fee'), default=False)
|
||||
monthly_fee = models.DecimalField(_('Monthly Fee'), max_digits=10, decimal_places=2, default=0.00)
|
||||
annual_fee = models.DecimalField(_('Annual Fee'), max_digits=10, decimal_places=2, default=0.00)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('App Setting')
|
||||
|
||||
@ -47,6 +47,33 @@
|
||||
</div>
|
||||
{% elif field.name == 'phone_number' %}
|
||||
{# Handled above #}
|
||||
{% elif field.name == 'subscription_plan' %}
|
||||
{% if subscription_enabled %}
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||
{{ field }}
|
||||
{% if field.errors %}
|
||||
{% for error in field.errors %}
|
||||
<div class="text-danger small">{{ error }}</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% elif field.name == 'accept_terms' %}
|
||||
<div class="mb-3 form-check">
|
||||
{{ field }}
|
||||
<label class="form-check-label small" for="{{ field.id_for_label }}">
|
||||
{% trans "I have read and agree to the" %}
|
||||
<a href="{% url 'terms_of_service' %}" target="_blank">{% trans "Terms of Service" %}</a>
|
||||
{% trans "and" %}
|
||||
<a href="{% url 'privacy_policy' %}" target="_blank">{% trans "Privacy Policy" %}</a>
|
||||
</label>
|
||||
{% if field.errors %}
|
||||
{% for error in field.errors %}
|
||||
<div class="text-danger small">{{ error }}</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||
|
||||
@ -23,6 +23,8 @@ def home(request):
|
||||
return render(request, "core/index.html", context)
|
||||
|
||||
def register(request):
|
||||
app_settings = AppSetting.objects.first()
|
||||
subscription_enabled = app_settings.subscription_enabled if app_settings else False
|
||||
if request.method == 'POST':
|
||||
form = UserRegistrationForm(request.POST)
|
||||
if form.is_valid():
|
||||
@ -34,6 +36,7 @@ def register(request):
|
||||
'role': form.cleaned_data['role'],
|
||||
'phone_number': form.cleaned_data['phone_number'],
|
||||
'country_code': form.cleaned_data['country_code'],
|
||||
'subscription_plan': form.cleaned_data.get('subscription_plan', 'NONE'),
|
||||
}
|
||||
request.session['registration_data'] = registration_data
|
||||
|
||||
@ -50,7 +53,7 @@ def register(request):
|
||||
messages.error(request, _("Please correct the errors below."))
|
||||
else:
|
||||
form = UserRegistrationForm()
|
||||
return render(request, 'registration/register.html', {'form': form})
|
||||
return render(request, 'registration/register.html', {'form': form, 'subscription_enabled': subscription_enabled})
|
||||
|
||||
def verify_otp_registration(request):
|
||||
registration_data = request.session.get('registration_data')
|
||||
@ -78,6 +81,9 @@ def verify_otp_registration(request):
|
||||
profile.role = registration_data['role']
|
||||
profile.phone_number = registration_data['phone_number']
|
||||
profile.country_code = registration_data['country_code']
|
||||
profile.subscription_plan = registration_data.get('subscription_plan', 'NONE')
|
||||
if profile.subscription_plan != 'NONE':
|
||||
profile.is_subscription_active = True
|
||||
profile.save()
|
||||
|
||||
login(request, user)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user