This commit is contained in:
Iliyan Angelov
2025-10-09 00:44:15 +03:00
parent 18ae8b9f88
commit dd8eb1c7aa
44 changed files with 3240 additions and 137 deletions

View File

@@ -12,16 +12,23 @@ class Command(BaseCommand):
def handle(self, *args, **options):
self.stdout.write('Creating sample about us data...')
# Clear existing data first
self.stdout.write('Clearing existing about data...')
AboutBanner.objects.all().delete()
AboutService.objects.all().delete()
AboutProcess.objects.all().delete()
AboutJourney.objects.all().delete()
# Create About Banner
banner, created = AboutBanner.objects.get_or_create(
title="Powering Enterprise Digital Transformation",
title="Enterprise Software Solutions for Mission-Critical Industries",
defaults={
'subtitle': "Leading Enterprise Software Solutions",
'description': "We are a leading enterprise software company that empowers Fortune 500 companies and growing businesses with cutting-edge technology solutions. Our mission is to accelerate digital transformation through innovative software platforms, cloud infrastructure, and data-driven insights.",
'subtitle': "GNX Soft Ltd - Your Trusted Enterprise Technology Partner",
'description': "GNX Soft Ltd is a leading Bulgarian enterprise software company delivering cutting-edge technology solutions to mission-critical industries worldwide. We empower organizations in Defense & Aerospace, Healthcare & Medical, Telecommunication, Banking, Public Sector, E-commerce, Food & Beverages, and Oil & Energy sectors with innovative, secure, and scalable software platforms that drive digital transformation and operational excellence.",
'badge_text': "Enterprise Software Solutions",
'badge_icon': "fa-solid fa-building",
'cta_text': "Discover Enterprise Solutions",
'cta_text': "Explore Enterprise Solutions",
'cta_link': "services",
'cta_icon': "fa-solid fa-arrow-trend-up",
'is_active': True
@@ -33,10 +40,10 @@ class Command(BaseCommand):
# Create Banner Stats
stats_data = [
{'number': '500+', 'label': 'Enterprise Clients', 'order': 1},
{'number': '8', 'label': 'Industry Verticals', 'order': 1},
{'number': '99.9%', 'label': 'Uptime SLA', 'order': 2},
{'number': '24/7', 'label': 'Enterprise Support', 'order': 3},
{'number': '15+', 'label': 'Years Experience', 'order': 4},
{'number': '2020', 'label': 'Founded', 'order': 4},
]
for stat_data in stats_data:
@@ -46,30 +53,30 @@ class Command(BaseCommand):
social_links_data = [
{
'platform': 'LinkedIn',
'url': 'https://www.linkedin.com/company/enterprisesoft-solutions',
'url': 'https://www.linkedin.com/company/gnxsoft',
'icon': 'fa-brands fa-linkedin-in',
'aria_label': 'Connect with us on LinkedIn',
'aria_label': 'Connect with GNX Soft on LinkedIn',
'order': 1
},
{
'platform': 'GitHub',
'url': 'https://github.com/enterprisesoft',
'url': 'https://github.com/gnxsoft',
'icon': 'fa-brands fa-github',
'aria_label': 'Follow us on GitHub',
'aria_label': 'Follow GNX Soft on GitHub',
'order': 2
},
{
'platform': 'Twitter',
'url': 'https://www.twitter.com/enterprisesoft',
'url': 'https://twitter.com/gnxsoft',
'icon': 'fa-brands fa-twitter',
'aria_label': 'Follow us on Twitter',
'aria_label': 'Follow GNX Soft on Twitter',
'order': 3
},
{
'platform': 'Stack Overflow',
'url': 'https://stackoverflow.com/teams/enterprisesoft',
'icon': 'fa-brands fa-stack-overflow',
'aria_label': 'Visit our Stack Overflow team',
'platform': 'Email',
'url': 'mailto:info@gnxsoft.com',
'icon': 'fa-solid fa-envelope',
'aria_label': 'Contact GNX Soft via email',
'order': 4
},
]
@@ -79,14 +86,14 @@ class Command(BaseCommand):
# Create About Service
service, created = AboutService.objects.get_or_create(
title="Enterprise Technology Leaders",
title="Enterprise Technology Excellence Across Critical Industries",
defaults={
'subtitle': "About Our Company",
'description': "Founded in 2008, EnterpriseSoft Solutions has emerged as a premier enterprise software company, serving Fortune 500 companies and innovative startups worldwide. Our team of 200+ engineers, architects, and consultants specializes in delivering mission-critical software solutions that drive digital transformation and business growth.",
'badge_text': "About Our Company",
'subtitle': "About GNX Soft Ltd",
'description': "Founded in 2020 and headquartered in Burgas, Bulgaria, GNX Soft Ltd is a premier enterprise software development company specializing in mission-critical solutions for highly regulated industries. Our expert team delivers secure, scalable, and compliant software solutions to Defense & Aerospace, Healthcare & Medical, Telecommunication, Banking & Finance, Public Sector, E-commerce, Food & Beverages, and Oil & Energy sectors. With EU-based infrastructure, we provide enterprise-grade solutions that meet the highest security and regulatory standards.",
'badge_text': "About GNX Soft Ltd",
'badge_icon': "fa-solid fa-users",
'cta_text': "Explore Our Solutions",
'cta_link': "service-single",
'cta_link': "services",
'is_active': True
}
)
@@ -97,27 +104,27 @@ class Command(BaseCommand):
# Create Service Features
features_data = [
{
'title': 'Enterprise Security',
'description': 'SOC 2 Type II Certified',
'icon': 'fa-solid fa-shield-halved',
'title': 'EU-Based Company',
'description': 'Headquartered in Bulgaria',
'icon': 'fa-solid fa-building',
'order': 1
},
{
'title': 'Cloud Native',
'description': 'AWS, Azure, GCP Partners',
'icon': 'fa-solid fa-cloud',
'title': 'EU Infrastructure',
'description': 'Bulgaria, Germany, Netherlands',
'icon': 'fa-solid fa-server',
'order': 2
},
{
'title': 'Certified Experts',
'description': 'Microsoft, AWS, Google Certified',
'icon': 'fa-solid fa-certificate',
'title': '8 Industry Verticals',
'description': 'Specialized Expertise',
'icon': 'fa-solid fa-industry',
'order': 3
},
{
'title': 'Global Reach',
'description': 'Offices in 5 Countries',
'icon': 'fa-solid fa-globe',
'title': '24/7 Support',
'description': 'Enterprise Support Team',
'icon': 'fa-solid fa-headset',
'order': 4
},
]
@@ -127,14 +134,14 @@ class Command(BaseCommand):
# Create About Process
process, created = AboutProcess.objects.get_or_create(
title="Enterprise Development Process",
title="Enterprise-Grade Development Methodology",
defaults={
'subtitle': "Our Methodology",
'description': "Our proven enterprise development methodology combines agile practices with enterprise-grade security, scalability, and compliance requirements. We follow industry best practices including DevOps, CI/CD, and microservices architecture to deliver robust, scalable solutions.",
'description': "GNX Soft Ltd employs a proven enterprise development methodology that combines agile practices with defense-grade security, regulatory compliance, and enterprise scalability. We follow industry best practices including DevOps, CI/CD, microservices architecture, and privacy-by-design principles to deliver robust, secure, and compliant solutions for highly regulated industries. Every project undergoes rigorous security assessments, Data Protection Impact Assessments (DPIAs), and compliance verification to meet the strictest industry standards.",
'badge_text': "Our Methodology",
'badge_icon': "fa-solid fa-cogs",
'cta_text': "View Our Services",
'cta_link': "service-single",
'cta_link': "services",
'is_active': True
}
)
@@ -146,26 +153,26 @@ class Command(BaseCommand):
steps_data = [
{
'step_number': '01',
'title': 'Discovery & Planning',
'description': 'Comprehensive analysis and architecture design',
'title': 'Discovery & Compliance',
'description': 'Requirements analysis, regulatory assessment, and DPIA',
'order': 1
},
{
'step_number': '02',
'title': 'Development & Testing',
'description': 'Agile development with continuous testing',
'title': 'Secure Development',
'description': 'Privacy-by-design, secure coding, continuous testing',
'order': 2
},
{
'step_number': '03',
'title': 'Deployment & Integration',
'description': 'Seamless deployment and system integration',
'description': 'EU infrastructure deployment and system integration',
'order': 3
},
{
'step_number': '04',
'title': 'Support & Maintenance',
'description': '24/7 enterprise support and maintenance',
'title': 'Support & Monitoring',
'description': '24/7 enterprise support with breach response',
'order': 4
},
]
@@ -175,10 +182,10 @@ class Command(BaseCommand):
# Create About Journey
journey, created = AboutJourney.objects.get_or_create(
title="From Startup to Enterprise Leader",
title="Building Enterprise Excellence Since 2020",
defaults={
'subtitle': "Our Journey",
'description': "Founded in 2008 by three visionary engineers, Itify Technologies began as a small startup with a big dream: to revolutionize how enterprises approach software development. What started as a passion project has grown into a global enterprise software company serving Fortune 500 clients worldwide.",
'description': "Founded in 2020 in Burgas, Bulgaria, GNX Soft Ltd was established with a clear mission: to deliver world-class enterprise software solutions for mission-critical industries while maintaining the highest standards of security, compliance, and data protection. From our inception, we focused exclusively on enterprise clients in highly regulated sectors including Defense & Aerospace, Healthcare & Medical, Banking, Public Sector, Telecommunication, E-commerce, Food & Beverages, and Oil & Energy. Our commitment to EU-based infrastructure and privacy-by-design principles has positioned us as a trusted technology partner for organizations that demand the highest levels of security and regulatory adherence.",
'badge_text': "Our Journey",
'badge_icon': "fa-solid fa-rocket",
'cta_text': "Explore Solutions",
@@ -193,23 +200,35 @@ class Command(BaseCommand):
# Create Journey Milestones
milestones_data = [
{
'year': '2008',
'year': '2020',
'title': 'Company Founded',
'description': 'Started with 3 engineers',
'description': 'GNX Soft Ltd established in Burgas, Bulgaria',
'order': 1
},
{
'year': '2015',
'title': 'Enterprise Focus',
'description': 'Pivoted to enterprise solutions',
'year': '2021',
'title': 'Industry Focus',
'description': 'Specialized in 8 mission-critical industries',
'order': 2
},
{
'year': '2020',
'title': 'Global Expansion',
'description': 'Opened offices in 5 countries',
'year': '2022',
'title': 'Industry Expansion',
'description': 'Expanded to 8 specialized industry verticals',
'order': 3
},
{
'year': '2023',
'title': 'EU Infrastructure',
'description': 'Deployed EU-wide data centers across 3 countries',
'order': 4
},
{
'year': '2024',
'title': 'Enterprise Leader',
'description': 'Recognized as leading Bulgarian enterprise software provider',
'order': 5
},
]
for milestone_data in milestones_data:

Binary file not shown.

View File

@@ -54,6 +54,7 @@ INSTALLED_APPS = [
'support',
'blog',
'case_studies',
'policies',
]
MIDDLEWARE = [

View File

@@ -53,6 +53,7 @@ urlpatterns = [
path('support/', include('support.urls')),
path('blog/', include('blog.urls')),
path('case-studies/', include('case_studies.urls')),
path('policies/', include('policies.urls')),
])),
]

File diff suppressed because it is too large Load Diff

View File

View File

@@ -0,0 +1,38 @@
from django.contrib import admin
from .models import Policy, PolicySection
class PolicySectionInline(admin.TabularInline):
model = PolicySection
extra = 1
fields = ['heading', 'content', 'order', 'is_active']
@admin.register(Policy)
class PolicyAdmin(admin.ModelAdmin):
list_display = ['title', 'type', 'version', 'last_updated', 'effective_date', 'is_active']
list_filter = ['type', 'is_active', 'last_updated']
search_fields = ['title', 'type', 'description']
prepopulated_fields = {'slug': ('type',)}
inlines = [PolicySectionInline]
fieldsets = (
('Basic Information', {
'fields': ('type', 'title', 'slug', 'description')
}),
('Version & Dates', {
'fields': ('version', 'effective_date', 'last_updated')
}),
('Status', {
'fields': ('is_active',)
}),
)
@admin.register(PolicySection)
class PolicySectionAdmin(admin.ModelAdmin):
list_display = ['policy', 'heading', 'order', 'is_active']
list_filter = ['policy__type', 'is_active']
search_fields = ['heading', 'content']
list_editable = ['order', 'is_active']

View File

@@ -0,0 +1,8 @@
from django.apps import AppConfig
class PoliciesConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'policies'
verbose_name = 'Policies Management'

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,54 @@
# Generated by Django 4.2.7 on 2025-10-08 13:54
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Policy',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('type', models.CharField(choices=[('privacy', 'Privacy Policy'), ('terms', 'Terms of Use'), ('support', 'Support Policy')], help_text='Type of policy document', max_length=50, unique=True)),
('title', models.CharField(help_text='Title of the policy', max_length=200)),
('slug', models.SlugField(blank=True, max_length=100, unique=True)),
('description', models.TextField(blank=True, help_text='Brief description of the policy')),
('last_updated', models.DateField(auto_now=True, help_text='Last update date')),
('version', models.CharField(default='1.0', help_text='Policy version number', max_length=20)),
('is_active', models.BooleanField(default=True, help_text='Whether this policy is currently active')),
('effective_date', models.DateField(help_text='Date when this policy becomes effective')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Policy',
'verbose_name_plural': 'Policies',
'ordering': ['type'],
},
),
migrations.CreateModel(
name='PolicySection',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('heading', models.CharField(help_text='Section heading', max_length=300)),
('content', models.TextField(help_text='Section content')),
('order', models.IntegerField(default=0, help_text='Display order of sections')),
('is_active', models.BooleanField(default=True, help_text='Whether this section is currently active')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('policy', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sections', to='policies.policy')),
],
options={
'verbose_name': 'Policy Section',
'verbose_name_plural': 'Policy Sections',
'ordering': ['policy', 'order'],
},
),
]

View File

@@ -0,0 +1,100 @@
from django.db import models
from django.utils.text import slugify
class Policy(models.Model):
"""
Model to store various policy documents (Privacy, Terms, Support, etc.)
"""
POLICY_TYPES = [
('privacy', 'Privacy Policy'),
('terms', 'Terms of Use'),
('support', 'Support Policy'),
]
type = models.CharField(
max_length=50,
choices=POLICY_TYPES,
unique=True,
help_text="Type of policy document"
)
title = models.CharField(
max_length=200,
help_text="Title of the policy"
)
slug = models.SlugField(
max_length=100,
unique=True,
blank=True
)
description = models.TextField(
blank=True,
help_text="Brief description of the policy"
)
last_updated = models.DateField(
auto_now=True,
help_text="Last update date"
)
version = models.CharField(
max_length=20,
default="1.0",
help_text="Policy version number"
)
is_active = models.BooleanField(
default=True,
help_text="Whether this policy is currently active"
)
effective_date = models.DateField(
help_text="Date when this policy becomes effective"
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = "Policy"
verbose_name_plural = "Policies"
ordering = ['type']
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.type)
super().save(*args, **kwargs)
def __str__(self):
return f"{self.get_type_display()} (v{self.version})"
class PolicySection(models.Model):
"""
Individual sections within a policy document
"""
policy = models.ForeignKey(
Policy,
on_delete=models.CASCADE,
related_name='sections'
)
heading = models.CharField(
max_length=300,
help_text="Section heading"
)
content = models.TextField(
help_text="Section content"
)
order = models.IntegerField(
default=0,
help_text="Display order of sections"
)
is_active = models.BooleanField(
default=True,
help_text="Whether this section is currently active"
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = "Policy Section"
verbose_name_plural = "Policy Sections"
ordering = ['policy', 'order']
def __str__(self):
return f"{self.policy.type} - {self.heading}"

View File

@@ -0,0 +1,47 @@
from rest_framework import serializers
from .models import Policy, PolicySection
class PolicySectionSerializer(serializers.ModelSerializer):
"""Serializer for policy sections"""
class Meta:
model = PolicySection
fields = ['id', 'heading', 'content', 'order']
class PolicySerializer(serializers.ModelSerializer):
"""Serializer for policies with their sections"""
sections = PolicySectionSerializer(many=True, read_only=True)
class Meta:
model = Policy
fields = [
'id',
'type',
'title',
'slug',
'description',
'last_updated',
'version',
'effective_date',
'sections'
]
class PolicyListSerializer(serializers.ModelSerializer):
"""Simplified serializer for policy listing"""
class Meta:
model = Policy
fields = [
'id',
'type',
'title',
'slug',
'description',
'last_updated',
'version'
]

View File

@@ -0,0 +1,4 @@
from django.test import TestCase
# Create your tests here.

View File

@@ -0,0 +1,11 @@
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import PolicyViewSet
router = DefaultRouter()
router.register(r'', PolicyViewSet, basename='policy')
urlpatterns = [
path('', include(router.urls)),
]

View File

@@ -0,0 +1,52 @@
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from django.shortcuts import get_object_or_404
from .models import Policy, PolicySection
from .serializers import PolicySerializer, PolicyListSerializer
class PolicyViewSet(viewsets.ReadOnlyModelViewSet):
"""
ViewSet for viewing policies.
Provides list and retrieve actions.
"""
queryset = Policy.objects.filter(is_active=True)
def get_serializer_class(self):
if self.action == 'list':
return PolicyListSerializer
return PolicySerializer
def get_queryset(self):
queryset = Policy.objects.filter(is_active=True)
policy_type = self.request.query_params.get('type', None)
if policy_type:
queryset = queryset.filter(type=policy_type)
return queryset
def retrieve(self, request, pk=None):
"""
Retrieve a policy by ID or type
"""
# Try to get by ID first
if pk.isdigit():
policy = get_object_or_404(Policy, pk=pk, is_active=True)
else:
# Otherwise try by type (slug)
policy = get_object_or_404(Policy, type=pk, is_active=True)
serializer = self.get_serializer(policy)
return Response(serializer.data)
@action(detail=False, methods=['get'], url_path='by-type/(?P<policy_type>[^/.]+)')
def by_type(self, request, policy_type=None):
"""
Get a specific policy by its type
"""
policy = get_object_or_404(Policy, type=policy_type, is_active=True)
serializer = PolicySerializer(policy)
return Response(serializer.data)