Merge branch '16-popraviti-validaciju' into 'master'

dodata provera za email i orgnaziation name

Closes #16

See merge request kbr4/riskletpy!19
This commit was merged in pull request #68.
This commit is contained in:
2025-05-06 17:06:15 +00:00
6 changed files with 85 additions and 9 deletions

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.1.3 on 2025-05-06 16:56
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0013_alter_organization_change_rate_and_more'),
]
operations = [
migrations.AlterField(
model_name='organization',
name='customer_base',
field=models.CharField(blank=True, help_text='How would you characterize your customer base distribution?', max_length=255, null=True),
),
]

View File

@@ -57,7 +57,7 @@ class Organization(models.Model):
third_party_vendor_access = models.CharField(max_length=20, help_text="How many third-party vendors have access to your systems?")
internal_software_development = models.CharField(max_length=20, help_text="What is the extent of your internal software development activities?")
geographic_scope = models.CharField(max_length=20, null=True, blank=True, help_text="What is your organization's geographic operational scope?")
customer_base = models.CharField(max_length=20, null=True, blank=True, help_text="How would you characterize your customer base distribution?")
customer_base = models.CharField(max_length=255, null=True, blank=True, help_text="How would you characterize your customer base distribution?")
customer_type = models.CharField(max_length=20, null=True, blank=True, help_text="What is your primary customer type?")
product_portfolio = models.CharField(max_length=20, null=True, blank=True, help_text="How diversified is your product/service portfolio?")
supplier_base = models.CharField(max_length=20, null=True, blank=True, help_text="What is your supplier base structure?")

View File

@@ -73,13 +73,13 @@ function setUpNavigation() {
// check if next button should be enabled on every input, checkbox and radio button bellow class of .question change
const inputs = document.querySelectorAll('.question input, .question select, .question textarea');
inputs.forEach(input => {
input.addEventListener('change', setNextButtonAvailability);
input.addEventListener('change',()=> setNextButtonAvailability());
input.addEventListener('blur', () => setNextButtonAvailability());
});
}
function setNextButtonAvailability() {
async function setNextButtonAvailability() {
console.log('Setting next button availability');
// check if current question is answered
// and then enable the next button, disable it otherwise
@@ -91,8 +91,14 @@ function setNextButtonAvailability() {
if (document.currentQuestion === 0) {
const name = document.getElementById('name');
const email = document.getElementById('email');
const errorDiv = document.getElementById('org-email-error');
if (name && email && name.value.trim() && email.value.trim()) {
nextEnabled = true;
nextEnabled = await validateFormFields(nextButton, errorDiv);
}else{
nextButton.disabled = true;
if (errorDiv) errorDiv.textContent = '';
return
}
} else {
const inputs = currentQuestion.querySelectorAll('input, select, textarea');
@@ -181,4 +187,23 @@ function setButtonVisiblity(buttonId, visible) {
}
}
async function validateFormFields(nextBtn, errorDiv) {
const nameInput = document.getElementById('name');
const emailInput = document.getElementById('email');
const name = nameInput.value.trim();
const email = emailInput.value.trim();
const resp = await fetch(`/api/validate_form_fields/?name=${name}&email=${email}`);
const data = await resp.json();
if (data.errors && (data.errors.name || data.errors.email)) {
errorDiv.textContent = (data.errors.name || '') + ' ' + (data.errors.email || '');
nextBtn.disabled = true;
return false;
} else {
errorDiv.textContent = '';
nextBtn.disabled = false;
return true;
}
}

View File

@@ -11,7 +11,16 @@
<form method="post">
{% if form.errors %}
<div class="alert alert-danger">
{{ form.errors }}
<ul class="mb-0">
{% for field in form %}
{% for error in field.errors %}
<li><strong>{{ field.label }}:</strong> {{ error }}</li>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% csrf_token %}
@@ -27,6 +36,7 @@
<small class="form-text text-muted py-3">
Enter the organization name and your email address. Both fields are required to continue.
</small>
<div id="org-email-error" class="text-danger py-2"></div>
</div>
<!-- Employee Headcount -->

View File

@@ -13,4 +13,5 @@ urlpatterns = [
path('preview/<str:name>/', v.template_preview, name='template_preview'),
path("payment/", v.payment_page, name="payment_page"),
path('pdf/<uuid:document_id>/', v.pdf_view, name='pdf_view'),
path('api/validate_form_fields/', v.validate_form_fields, name='validate_form_fields'),
]

View File

@@ -3,14 +3,17 @@ import yaml
from django.shortcuts import render, redirect , get_object_or_404
from .forms import OrganizationForm
from .models import Organization,Document, DocumentTemplate,DocumentRiskControl,Risk
from .models import Organization,Document, DocumentTemplate
from backend.accounts.utils import send_confirmation_email, send_document_email
from django.contrib.admin.views.decorators import staff_member_required
from .utils import generate_pdf, map_weight_to_impact_likelihood, calculate_aggregate_weight, calculate_aggregate_likelihood, generate_risk_graph
from .utils import generate_pdf, generate_risk_graph
from .tables import risk_matrix_table ,get_risk_table
from django.conf import settings
site_domain = settings.SITE_DOMAIN
from .processors import render_template
from django.http import JsonResponse
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
@@ -45,6 +48,25 @@ def signup(request):
return render(request, 'signup.html', {'form': form})
def validate_form_fields(request):
name = request.GET.get('name', '').strip()
email = request.GET.get('email', '').strip()
errors = {}
if name and Organization.objects.filter(name__iexact=name).exists():
errors['name'] = 'Organization with this name already exists.'
if email:
try:
validate_email(email)
except ValidationError:
errors['email'] = 'Please enter a valid email address.'
else:
if Organization.objects.filter(email__iexact=email).exists():
errors['email'] = 'This email is already registered.'
return JsonResponse({'errors': errors})
def thankyou(request):
return render(request, 'thankyou.html')