Payment
-- Click the button below to securely pay and access your document. -
-diff --git a/backend/core/admin.py b/backend/core/admin.py index 2a366f5..e9c1e27 100644 --- a/backend/core/admin.py +++ b/backend/core/admin.py @@ -1,8 +1,11 @@ from django.contrib import admin -from .models import Document, DocumentSegment, Organization, Risk, Control, DocumentTemplate, DocumentRiskControl +from .models import Document, DocumentSegment, Organization, Risk, Control, DocumentTemplate, DocumentRiskControl, PaymentCode from django.urls import reverse from django.utils.html import format_html - +from .utils import generate_payment_code +from django.urls import path +from django.shortcuts import render, redirect +from .forms import GenerateCodesForm class DocumentSegmentInline(admin.StackedInline): model = DocumentSegment @@ -41,6 +44,37 @@ class ControlAdmin(admin.ModelAdmin): class DocumentRiskControlAdmin(admin.ModelAdmin): list_display = ('document', 'risk', 'control', 'weight','likelihood') +class PaymentCodeAdmin(admin.ModelAdmin): + + list_display = ('code', 'created_at', 'used', 'company', 'used_at') + change_list_template = "admin/paymentcode_changelist.html" + + def get_urls(self): + urls = super().get_urls() + custom_urls = [ + path('generate-codes/', self.admin_site.admin_view(self.generate_codes_view), name='generate-codes'), + ] + return custom_urls + urls + + def generate_codes_view(self, request): + if request.method == 'POST': + form = GenerateCodesForm(request.POST) + if form.is_valid(): + count = form.cleaned_data['count'] + created = 0 + for _ in range(count): + while True: + code = generate_payment_code() + if not PaymentCode.objects.filter(code=code).exists(): + PaymentCode.objects.create(code=code) + created += 1 + break + self.message_user(request, f"{created} codes generated.") + return redirect('..') + else: + form = GenerateCodesForm() + return render(request, 'admin/generate_codes.html', {'form': form}) + admin.site.register(Document, DocumentAdmin) admin.site.register(Organization, OrganizationAdmin) @@ -48,3 +82,4 @@ admin.site.register(Risk ,RiskAdmin) admin.site.register(Control, ControlAdmin) admin.site.register(DocumentTemplate, DocumentTemplateAdmin) admin.site.register(DocumentRiskControl, DocumentRiskControlAdmin) +admin.site.register(PaymentCode, PaymentCodeAdmin) diff --git a/backend/core/forms.py b/backend/core/forms.py index ad26651..92bf720 100644 --- a/backend/core/forms.py +++ b/backend/core/forms.py @@ -47,3 +47,7 @@ class OrganizationForm(forms.ModelForm): cleaned_data['sensitive_data_types'] = types return cleaned_data + + +class GenerateCodesForm(forms.Form): + count = forms.IntegerField(label="How many codes to generate?", min_value=1, max_value=1000) diff --git a/backend/core/migrations/0016_paymentcode.py b/backend/core/migrations/0016_paymentcode.py new file mode 100644 index 0000000..c694900 --- /dev/null +++ b/backend/core/migrations/0016_paymentcode.py @@ -0,0 +1,25 @@ +# Generated by Django 5.1.3 on 2025-06-19 18:42 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0015_control_description_control_safeguard_id'), + ] + + operations = [ + migrations.CreateModel( + name='PaymentCode', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('code', models.CharField(max_length=10, unique=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('used', models.BooleanField(default=False)), + ('used_at', models.DateTimeField(blank=True, null=True)), + ('company', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='core.organization')), + ], + ), + ] diff --git a/backend/core/models.py b/backend/core/models.py index 75cc0a4..09b1288 100644 --- a/backend/core/models.py +++ b/backend/core/models.py @@ -171,4 +171,15 @@ class DocumentRiskControl(models.Model): likelihood = models.IntegerField(null=True, blank=True) class Meta: - unique_together = ('document', 'risk', 'control') \ No newline at end of file + unique_together = ('document', 'risk', 'control') + + +class PaymentCode(models.Model): + code = models.CharField(max_length=10, unique=True) + created_at = models.DateTimeField(auto_now_add=True) + used = models.BooleanField(default=False) + used_at = models.DateTimeField(null=True, blank=True) + company = models.ForeignKey(Organization, null=True, blank=True, on_delete=models.SET_NULL) + + def __str__(self): + return (f"{self.code} - {'Used' if self.used else 'Available'}") diff --git a/backend/core/templates/admin/generate_codes.html b/backend/core/templates/admin/generate_codes.html new file mode 100644 index 0000000..69afabd --- /dev/null +++ b/backend/core/templates/admin/generate_codes.html @@ -0,0 +1,11 @@ +{% extends "admin/base_site.html" %} + +{% block content %} +
- Click the button below to securely pay and access your document. -
-