This commit is contained in:
Marwan Alwali 2025-11-02 16:03:03 +03:00
parent 27a71b658a
commit d912313a27
20 changed files with 1150 additions and 249 deletions

Binary file not shown.

View File

@ -9,6 +9,7 @@ from simple_history.admin import SimpleHistoryAdmin
from .models import ( from .models import (
Service, Service,
Package, Package,
PackageService,
Payer, Payer,
Invoice, Invoice,
InvoiceLineItem, InvoiceLineItem,
@ -45,6 +46,16 @@ class ServiceAdmin(admin.ModelAdmin):
) )
class PackageServiceInline(admin.TabularInline):
"""Inline admin for Package Services."""
model = PackageService
extra = 1
readonly_fields = ['id']
fields = ['service', 'sessions']
autocomplete_fields = ['service']
@admin.register(Package) @admin.register(Package)
class PackageAdmin(admin.ModelAdmin): class PackageAdmin(admin.ModelAdmin):
"""Admin interface for Package model.""" """Admin interface for Package model."""
@ -52,15 +63,15 @@ class PackageAdmin(admin.ModelAdmin):
list_display = ['name_en', 'total_sessions', 'price', 'validity_days', 'is_active', 'tenant'] list_display = ['name_en', 'total_sessions', 'price', 'validity_days', 'is_active', 'tenant']
list_filter = ['is_active', 'tenant'] list_filter = ['is_active', 'tenant']
search_fields = ['name_en', 'name_ar'] search_fields = ['name_en', 'name_ar']
readonly_fields = ['id', 'created_at', 'updated_at'] readonly_fields = ['id', 'total_sessions', 'created_at', 'updated_at']
filter_horizontal = ['services'] inlines = [PackageServiceInline]
fieldsets = ( fieldsets = (
(None, { (None, {
'fields': ('name_en', 'name_ar', 'tenant', 'is_active') 'fields': ('name_en', 'name_ar', 'tenant', 'is_active')
}), }),
(_('Package Details'), { (_('Package Details'), {
'fields': ('services', 'total_sessions', 'price', 'validity_days') 'fields': ('total_sessions', 'price', 'validity_days')
}), }),
(_('Description'), { (_('Description'), {
'fields': ('description',), 'fields': ('description',),

View File

@ -10,7 +10,7 @@ from django.utils.translation import gettext_lazy as _
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Fieldset, Row, Column, Submit, HTML from crispy_forms.layout import Layout, Fieldset, Row, Column, Submit, HTML
from .models import Invoice, InvoiceLineItem, Payment, Service, Package, PackagePurchase, Payer from .models import Invoice, InvoiceLineItem, Payment, Service, Package, PackageService, PackagePurchase, Payer
class InvoiceForm(forms.ModelForm): class InvoiceForm(forms.ModelForm):
@ -284,14 +284,11 @@ class PackageForm(forms.ModelForm):
model = Package model = Package
fields = [ fields = [
'name_en', 'name_ar', 'name_en', 'name_ar',
'services', 'total_sessions', 'price', 'price', 'validity_days', 'description', 'is_active',
'validity_days', 'description', 'is_active',
] ]
widgets = { widgets = {
'name_en': forms.TextInput(attrs={'class': 'form-control'}), 'name_en': forms.TextInput(attrs={'class': 'form-control'}),
'name_ar': forms.TextInput(attrs={'class': 'form-control'}), 'name_ar': forms.TextInput(attrs={'class': 'form-control'}),
'services': forms.CheckboxSelectMultiple(),
'total_sessions': forms.NumberInput(attrs={'class': 'form-control', 'min': '1'}),
'price': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01', 'min': '0'}), 'price': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01', 'min': '0'}),
'validity_days': forms.NumberInput(attrs={'class': 'form-control', 'min': '1'}), 'validity_days': forms.NumberInput(attrs={'class': 'form-control', 'min': '1'}),
'description': forms.Textarea(attrs={'rows': 3, 'class': 'form-control'}), 'description': forms.Textarea(attrs={'rows': 3, 'class': 'form-control'}),
@ -306,32 +303,45 @@ class PackageForm(forms.ModelForm):
if field_name == 'is_active': if field_name == 'is_active':
if 'class' not in field.widget.attrs: if 'class' not in field.widget.attrs:
field.widget.attrs['class'] = 'form-check-input' field.widget.attrs['class'] = 'form-check-input'
elif field_name != 'services': # services uses CheckboxSelectMultiple else:
if 'class' not in field.widget.attrs: if 'class' not in field.widget.attrs:
field.widget.attrs['class'] = 'form-control' field.widget.attrs['class'] = 'form-control'
class PackageServiceForm(forms.ModelForm):
"""
Form for package service items (service + session count).
"""
class Meta:
model = PackageService
fields = ['service', 'sessions']
widgets = {
'service': forms.Select(attrs={'class': 'form-control select2', 'data-placeholder': 'Select service'}),
'sessions': forms.NumberInput(attrs={'class': 'form-control', 'min': '1', 'value': '1'}),
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Filter to show only active services
self.fields['service'].queryset = Service.objects.filter(is_active=True)
self.helper = FormHelper() # Add CSS classes
self.helper.form_method = 'post' for field_name, field in self.fields.items():
self.helper.layout = Layout( if 'class' not in field.widget.attrs:
Fieldset( field.widget.attrs['class'] = 'form-control'
_('Package Information'),
Row(
Column('name_en', css_class='form-group col-md-6 mb-0'), # Inline formset for package services
Column('name_ar', css_class='form-group col-md-6 mb-0'), PackageServiceFormSet = inlineformset_factory(
css_class='form-row' Package,
), PackageService,
'services', form=PackageServiceForm,
Row( extra=0, # Start with 1 empty form
Column('total_sessions', css_class='form-group col-md-4 mb-0'), can_delete=True,
Column('price', css_class='form-group col-md-4 mb-0'), min_num=1,
Column('validity_days', css_class='form-group col-md-4 mb-0'), validate_min=True,
css_class='form-row' )
),
'description',
'is_active',
),
Submit('submit', _('Save Package'), css_class='btn btn-primary')
)
class PackagePurchaseForm(forms.ModelForm): class PackagePurchaseForm(forms.ModelForm):

View File

@ -0,0 +1,73 @@
# Generated by Django 5.2.3 on 2025-11-02 12:07
import django.db.models.deletion
import uuid
from django.db import migrations, models
def migrate_package_services(apps, schema_editor):
"""
Migrate existing package-service relationships to the new through model.
"""
Package = apps.get_model('finance', 'Package')
PackageService = apps.get_model('finance', 'PackageService')
# For each package, create PackageService entries for existing services
for package in Package.objects.all():
# Get existing services through the old M2M relationship
for service in package.services.all():
# Create a PackageService with default 1 session
PackageService.objects.create(
package=package,
service=service,
sessions=1
)
class Migration(migrations.Migration):
dependencies = [
('finance', '0004_csid'),
]
operations = [
# Step 1: Alter total_sessions field
migrations.AlterField(
model_name='package',
name='total_sessions',
field=models.PositiveIntegerField(default=0, help_text='Auto-calculated from service sessions', verbose_name='Total Sessions'),
),
# Step 2: Create the PackageService model
migrations.CreateModel(
name='PackageService',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, verbose_name='ID')),
('sessions', models.PositiveIntegerField(default=1, help_text='Number of sessions for this service in the package', verbose_name='Number of Sessions')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='finance.package', verbose_name='Package')),
('service', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='finance.service', verbose_name='Service')),
],
options={
'verbose_name': 'Package Service',
'verbose_name_plural': 'Package Services',
'ordering': ['package', 'service'],
'unique_together': {('package', 'service')},
},
),
# Step 3: Migrate existing data
migrations.RunPython(migrate_package_services, reverse_code=migrations.RunPython.noop),
# Step 4: Remove the old M2M field
migrations.RemoveField(
model_name='package',
name='services',
),
# Step 5: Add the new M2M field with through
migrations.AddField(
model_name='package',
name='services',
field=models.ManyToManyField(related_name='packages', through='finance.PackageService', to='finance.service', verbose_name='Services'),
),
]

View File

@ -89,11 +89,14 @@ class Package(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin):
) )
services = models.ManyToManyField( services = models.ManyToManyField(
Service, Service,
through='PackageService',
related_name='packages', related_name='packages',
verbose_name=_("Services") verbose_name=_("Services")
) )
total_sessions = models.PositiveIntegerField( total_sessions = models.PositiveIntegerField(
verbose_name=_("Total Sessions") default=0,
verbose_name=_("Total Sessions"),
help_text=_("Auto-calculated from service sessions")
) )
price = models.DecimalField( price = models.DecimalField(
max_digits=10, max_digits=10,
@ -122,6 +125,51 @@ class Package(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin):
def __str__(self): def __str__(self):
return f"{self.name_en} ({self.total_sessions} sessions)" return f"{self.name_en} ({self.total_sessions} sessions)"
def calculate_total_sessions(self):
"""Calculate total sessions from all package services."""
return sum(ps.sessions for ps in self.packageservice_set.all())
def save(self, *args, **kwargs):
"""Override save to auto-calculate total sessions."""
super().save(*args, **kwargs)
# Update total_sessions after save (when through relationships exist)
if self.pk:
self.total_sessions = self.calculate_total_sessions()
if self.total_sessions != self._state.fields_cache.get('total_sessions', 0):
Package.objects.filter(pk=self.pk).update(total_sessions=self.total_sessions)
class PackageService(UUIDPrimaryKeyMixin):
"""
Intermediate model linking packages to services with session counts.
Allows specifying how many sessions of each service are included in a package.
"""
package = models.ForeignKey(
Package,
on_delete=models.CASCADE,
verbose_name=_("Package")
)
service = models.ForeignKey(
Service,
on_delete=models.CASCADE,
verbose_name=_("Service")
)
sessions = models.PositiveIntegerField(
default=1,
verbose_name=_("Number of Sessions"),
help_text=_("Number of sessions for this service in the package")
)
class Meta:
verbose_name = _("Package Service")
verbose_name_plural = _("Package Services")
unique_together = [['package', 'service']]
ordering = ['package', 'service']
def __str__(self):
return f"{self.package.name_en} - {self.service.name_en} ({self.sessions} sessions)"
class Payer(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin): class Payer(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin):

View File

@ -25,15 +25,30 @@
.form-check-input { .form-check-input {
margin-top: 0.3rem; margin-top: 0.3rem;
} }
.select2-container--default .select2-selection--multiple { .select2-container--default .select2-selection--single {
border: 1px solid #dee2e6; border: 1px solid #dee2e6;
border-radius: 0.375rem; border-radius: 0.375rem;
min-height: 38px; min-height: 38px;
} }
.select2-container--default.select2-container--focus .select2-selection--multiple { .select2-container--default.select2-container--focus .select2-selection--single {
border-color: #007bff; border-color: #007bff;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
} }
.service-row {
background-color: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 0.375rem;
padding: 1rem;
margin-bottom: 0.75rem;
}
.service-row:hover {
background-color: #e9ecef;
}
.btn-remove-service {
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
}
</style> </style>
{% endblock %} {% endblock %}
@ -55,7 +70,7 @@
</div> </div>
</div> </div>
<form method="post"> <form method="post" id="packageForm">
{% csrf_token %} {% csrf_token %}
<div class="row"> <div class="row">
<div class="col-lg-8"> <div class="col-lg-8">
@ -69,42 +84,47 @@
<div class="mb-3"> <div class="mb-3">
<label class="form-label">{% trans "Name (English)" %} <span class="text-danger">*</span></label> <label class="form-label">{% trans "Name (English)" %} <span class="text-danger">*</span></label>
{{ form.name_en }} {{ form.name_en }}
{% if form.name_en.errors %}
<div class="text-danger small">{{ form.name_en.errors }}</div>
{% endif %}
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="mb-3"> <div class="mb-3">
<label class="form-label">{% trans "Name (Arabic)" %}</label> <label class="form-label">{% trans "Name (Arabic)" %}</label>
{{ form.name_ar }} {{ form.name_ar }}
{% if form.name_ar.errors %}
<div class="text-danger small">{{ form.name_ar.errors }}</div>
{% endif %}
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-6">
<div class="mb-3">
<label class="form-label">{% trans "Total Sessions" %} <span class="text-danger">*</span></label>
{{ form.total_sessions }}
</div>
</div>
<div class="col-md-4">
<div class="mb-3"> <div class="mb-3">
<label class="form-label">{% trans "Price" %} <span class="text-danger">*</span></label> <label class="form-label">{% trans "Price" %} <span class="text-danger">*</span></label>
{{ form.price }} {{ form.price }}
{% if form.price.errors %}
<div class="text-danger small">{{ form.price.errors }}</div>
{% endif %}
</div> </div>
</div> </div>
<div class="col-md-4"> <div class="col-md-6">
<div class="mb-3"> <div class="mb-3">
<label class="form-label">{% trans "Validity (days)" %} <span class="text-danger">*</span></label> <label class="form-label">{% trans "Validity (days)" %} <span class="text-danger">*</span></label>
{{ form.validity_days }} {{ form.validity_days }}
{% if form.validity_days.errors %}
<div class="text-danger small">{{ form.validity_days.errors }}</div>
{% endif %}
</div> </div>
</div> </div>
</div> </div>
<div class="mb-3">
<label class="form-label">{% trans "Services Included" %} <span class="text-danger">*</span></label>
{{ form.services }}
</div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label">{% trans "Description" %}</label> <label class="form-label">{% trans "Description" %}</label>
{{ form.description }} {{ form.description }}
{% if form.description.errors %}
<div class="text-danger small">{{ form.description.errors }}</div>
{% endif %}
</div> </div>
<div class="form-check"> <div class="form-check">
{{ form.is_active }} {{ form.is_active }}
@ -115,6 +135,56 @@
</div> </div>
</div> </div>
<div class="card mb-3">
<div class="card-header bg-success text-white d-flex justify-content-between align-items-center">
<h5 class="mb-0"><i class="fas fa-list me-2"></i>{% trans "Services Included" %}</h5>
<div>
<span class="me-2">{% trans "Total Sessions:" %}</span>
<span class="fw-bold fs-16px" id="totalSessionsDisplay">0</span>
</div>
</div>
<div class="card-body">
{{ service_formset.management_form }}
<div id="serviceRows">
{% for service_form in service_formset %}
<div class="service-row" data-form-index="{{ forloop.counter0 }}">
<div class="row align-items-center">
<div class="col-md-7">
<label class="form-label small">{% trans "Service" %} <span class="text-danger">*</span></label>
{{ service_form.service }}
{% if service_form.service.errors %}
<div class="text-danger small">{{ service_form.service.errors }}</div>
{% endif %}
</div>
<div class="col-md-3">
<label class="form-label small">{% trans "Sessions" %} <span class="text-danger">*</span></label>
{{ service_form.sessions }}
{% if service_form.sessions.errors %}
<div class="text-danger small">{{ service_form.sessions.errors }}</div>
{% endif %}
</div>
<div class="col-md-2 text-end">
<label class="form-label small d-block">&nbsp;</label>
{% if not service_form.instance.pk or service_formset.can_delete %}
<button type="button" class="btn btn-danger btn-sm btn-remove-service">
<i class="fas fa-trash"></i>
</button>
{% endif %}
{{ service_form.id }}
<div style="display: none;">{{ service_form.DELETE }}</div>
</div>
</div>
</div>
{% endfor %}
</div>
<button type="button" class="btn btn-outline-success btn-sm mt-2" id="addServiceBtn">
<i class="fas fa-plus me-1"></i>{% trans "Add Service" %}
</button>
</div>
</div>
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<button type="submit" class="btn btn-primary btn-lg"> <button type="submit" class="btn btn-primary btn-lg">
@ -136,8 +206,8 @@
<p class="small">{% trans "Create service packages for bundled pricing." %}</p> <p class="small">{% trans "Create service packages for bundled pricing." %}</p>
<ul class="small"> <ul class="small">
<li>{% trans "Set package name and price" %}</li> <li>{% trans "Set package name and price" %}</li>
<li>{% trans "Define number of sessions" %}</li> <li>{% trans "Add services and specify sessions for each" %}</li>
<li>{% trans "Select included services" %}</li> <li>{% trans "Total sessions are calculated automatically" %}</li>
<li>{% trans "Set validity period" %}</li> <li>{% trans "Set validity period" %}</li>
</ul> </ul>
</div> </div>
@ -146,16 +216,124 @@
</div> </div>
</form> </form>
</div> </div>
<!-- Empty form template for cloning -->
<script type="text/template" id="emptyFormTemplate">
<div class="service-row" data-form-index="__prefix__">
<div class="row align-items-center">
<div class="col-md-7">
<label class="form-label small">{% trans "Service" %} <span class="text-danger">*</span></label>
{{ service_formset.empty_form.service }}
</div>
<div class="col-md-3">
<label class="form-label small">{% trans "Sessions" %} <span class="text-danger">*</span></label>
{{ service_formset.empty_form.sessions }}
</div>
<div class="col-md-2 text-end">
<label class="form-label small d-block">&nbsp;</label>
<button type="button" class="btn btn-danger btn-sm btn-remove-service">
<i class="fas fa-trash"></i>
</button>
{{ service_formset.empty_form.id }}
<div style="display: none;">{{ service_formset.empty_form.DELETE }}</div>
</div>
</div>
</div>
</script>
{% endblock %} {% endblock %}
{% block js %} {% block js %}
<script src="{% static 'plugins/select2/dist/js/select2.min.js' %}"></script> <script src="{% static 'plugins/select2/dist/js/select2.min.js' %}"></script>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$('#id_services').select2({ let formIndex = {{ service_formset.total_form_count }};
placeholder: '{% trans "Select Services" %}',
allowClear: true // Initialize Select2 for existing service dropdowns
initializeSelect2();
// Calculate total sessions on page load
calculateTotalSessions();
// Add new service row
$('#addServiceBtn').click(function() {
// Get the template HTML and replace __prefix__
let templateHtml = $('#emptyFormTemplate').html();
templateHtml = templateHtml.replace(/__prefix__/g, formIndex);
// Create new row from the modified HTML
const newRow = $(templateHtml);
// Append to service rows
$('#serviceRows').append(newRow);
// Update form count
const totalForms = $('#id_packageservice_set-TOTAL_FORMS');
totalForms.val(parseInt(totalForms.val()) + 1);
// Initialize Select2 for the new dropdown
newRow.find('select[name$="-service"]').select2({
placeholder: '{% trans "Select Service" %}',
allowClear: true,
width: '100%'
}); });
formIndex++;
// Recalculate total sessions
calculateTotalSessions();
}); });
// Remove service row
$(document).on('click', '.btn-remove-service', function() {
const row = $(this).closest('.service-row');
const deleteCheckbox = row.find('input[name$="-DELETE"]');
if (deleteCheckbox.length > 0) {
// Mark for deletion if it's an existing record
deleteCheckbox.prop('checked', true);
row.hide();
} else {
// Remove from DOM if it's a new record
row.remove();
}
// Recalculate total sessions
calculateTotalSessions();
});
// Recalculate total sessions when session count changes
$(document).on('input change', 'input[name$="-sessions"]', function() {
calculateTotalSessions();
});
function initializeSelect2() {
$('select[name$="-service"]').each(function() {
if (!$(this).hasClass('select2-hidden-accessible')) {
$(this).select2({
placeholder: '{% trans "Select Service" %}',
allowClear: true,
width: '100%'
});
}
});
}
function calculateTotalSessions() {
let total = 0;
$('.service-row:visible').each(function() {
const deleteCheckbox = $(this).find('input[name$="-DELETE"]');
const isMarkedForDeletion = deleteCheckbox.length > 0 && deleteCheckbox.is(':checked');
if (!isMarkedForDeletion) {
const sessionsInput = $(this).find('input[name$="-sessions"]');
const sessions = parseInt(sessionsInput.val()) || 0;
total += sessions;
}
});
$('#totalSessionsDisplay').text(total);
}
});
</script> </script>
{% endblock %} {% endblock %}

View File

@ -731,17 +731,52 @@ class PackageCreateView(LoginRequiredMixin, RolePermissionMixin, AuditLogMixin,
success_url = reverse_lazy('finance:package_list') success_url = reverse_lazy('finance:package_list')
allowed_roles = [User.Role.ADMIN, User.Role.FINANCE] allowed_roles = [User.Role.ADMIN, User.Role.FINANCE]
def form_valid(self, form):
"""Set tenant."""
form.instance.tenant = self.request.user.tenant
return super().form_valid(form)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
"""Add form title.""" """Add form title and service formset."""
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context['form_title'] = 'Create New Package' context['form_title'] = 'Create New Package'
context['submit_text'] = 'Create Package' context['submit_text'] = 'Create Package'
# Add package service formset
if self.request.POST:
context['service_formset'] = PackageServiceFormSet(
self.request.POST,
instance=self.object
)
else:
context['service_formset'] = PackageServiceFormSet(
instance=self.object
)
return context return context
def form_valid(self, form):
"""Set tenant and save formset."""
form.instance.tenant = self.request.user.tenant
# Save package first
self.object = form.save()
# Get and validate formset
formset = PackageServiceFormSet(
self.request.POST,
instance=self.object
)
if formset.is_valid():
# Save package services
formset.save()
# Update total sessions
self.object.total_sessions = self.object.calculate_total_sessions()
self.object.save()
messages.success(self.request, self.success_message)
return redirect(self.get_success_url())
else:
# If formset is invalid, delete the package and show errors
self.object.delete()
return self.form_invalid(form)
class PackageUpdateView(LoginRequiredMixin, RolePermissionMixin, TenantFilterMixin, class PackageUpdateView(LoginRequiredMixin, RolePermissionMixin, TenantFilterMixin,
@ -761,11 +796,48 @@ class PackageUpdateView(LoginRequiredMixin, RolePermissionMixin, TenantFilterMix
allowed_roles = [User.Role.ADMIN, User.Role.FINANCE] allowed_roles = [User.Role.ADMIN, User.Role.FINANCE]
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
"""Add form title.""" """Add form title and service formset."""
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context['form_title'] = f'Update Package: {self.object.name_en}' context['form_title'] = f'Update Package: {self.object.name_en}'
context['submit_text'] = 'Update Package' context['submit_text'] = 'Update Package'
# Add package service formset
if self.request.POST:
context['service_formset'] = PackageServiceFormSet(
self.request.POST,
instance=self.object
)
else:
context['service_formset'] = PackageServiceFormSet(
instance=self.object
)
return context return context
def form_valid(self, form):
"""Save package and formset."""
# Save package
self.object = form.save()
# Get and validate formset
formset = PackageServiceFormSet(
self.request.POST,
instance=self.object
)
if formset.is_valid():
# Save package services
formset.save()
# Update total sessions
self.object.total_sessions = self.object.calculate_total_sessions()
self.object.save()
messages.success(self.request, self.success_message)
return redirect(self.get_success_url())
else:
# If formset is invalid, show errors
return self.form_invalid(form)
class PayerListView(LoginRequiredMixin, TenantFilterMixin, PaginationMixin, ListView): class PayerListView(LoginRequiredMixin, TenantFilterMixin, PaginationMixin, ListView):

View File

@ -1,5 +1,5 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n static %} {% load i18n static hr_tags %}
{% block title %}{% trans "Schedule Grid" %} - {{ block.super }}{% endblock %} {% block title %}{% trans "Schedule Grid" %} - {{ block.super }}{% endblock %}

View File

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,14 @@
from django import template
register = template.Library()
@register.filter
def get_item(dictionary, key):
"""
Template filter to get an item from a dictionary using a variable key.
Usage: {{ mydict|get_item:key_variable }}
"""
if dictionary is None:
return None
return dictionary.get(key)

View File

@ -72455,3 +72455,497 @@ INFO 2025-11-02 14:30:00,006 tasks 16180 8648941888 Radiology results sync compl
INFO 2025-11-02 14:30:00,012 tasks 16180 8648941888 Lab results sync started INFO 2025-11-02 14:30:00,012 tasks 16180 8648941888 Lab results sync started
INFO 2025-11-02 14:30:00,012 tasks 16180 8648941888 Lab results sync completed: {'status': 'success', 'new_results': 0, 'updated_results': 0, 'errors': 0, 'timestamp': '2025-11-02 11:30:00.012252+00:00'} INFO 2025-11-02 14:30:00,012 tasks 16180 8648941888 Lab results sync completed: {'status': 'success', 'new_results': 0, 'updated_results': 0, 'errors': 0, 'timestamp': '2025-11-02 11:30:00.012252+00:00'}
ERROR 2025-11-02 14:34:02,219 tasks 16180 8648941888 Appointment 8f028c27-4142-489c-91a8-417fa19038bf not found ERROR 2025-11-02 14:34:02,219 tasks 16180 8648941888 Appointment 8f028c27-4142-489c-91a8-417fa19038bf not found
ERROR 2025-11-02 14:47:58,725 tasks 16172 8648941888 Appointment a754db19-dbcb-40e9-a03e-742e2c13ea83 not found
ERROR 2025-11-02 14:47:58,725 tasks 16181 8648941888 Appointment 7d208dcb-490f-4f66-97e0-807f7a4cc9d4 not found
ERROR 2025-11-02 14:47:58,725 tasks 16180 8648941888 Appointment 4e16bbd2-83d1-46e7-a439-b2f3d06fc35a not found
ERROR 2025-11-02 14:47:58,725 tasks 16173 8648941888 Appointment 80157786-4d02-4e2a-960f-8ff0acdb443b not found
INFO 2025-11-02 14:47:59,225 basehttp 18386 6198079488 "GET / HTTP/1.1" 302 0
INFO 2025-11-02 14:47:59,298 basehttp 18386 6214905856 "GET /en/ HTTP/1.1" 200 56415
ERROR 2025-11-02 14:51:13,535 tasks 16172 8648941888 Appointment 1ba52899-1a8e-4bce-93bd-d1d643bb7b69 not found
ERROR 2025-11-02 14:51:13,535 tasks 16180 8648941888 Appointment 84999784-a5ac-4385-82c0-6beee6a870fe not found
ERROR 2025-11-02 14:52:08,315 tasks 16180 8648941888 Appointment 77bb0820-19c1-473f-a574-3cb8845eb3f9 not found
INFO 2025-11-02 14:52:49,872 basehttp 18386 6198079488 "GET /en/hr/schedules/ HTTP/1.1" 200 101408
ERROR 2025-11-02 14:52:59,587 log 18386 6198079488 Internal Server Error: /en/hr/schedules/grid/
Traceback (most recent call last):
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
response = response.render()
^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
self.content = self.rendered_content
^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/response.py", line 90, in rendered_content
template = self.resolve_template(self.template_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/response.py", line 72, in resolve_template
return select_template(template, using=self.using)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/loader.py", line 42, in select_template
return engine.get_template(template_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 79, in get_template
return Template(self.engine.get_template(template_name), self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/engine.py", line 177, in get_template
template, origin = self.find_template(template_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/engine.py", line 159, in find_template
template = loader.get_template(name, skip=skip)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/loaders/cached.py", line 57, in get_template
template = super().get_template(template_name, skip)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/loaders/base.py", line 28, in get_template
return Template(
^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 154, in __init__
self.nodelist = self.compile_nodelist()
^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 196, in compile_nodelist
nodelist = parser.parse()
^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
raise self.error(token, e)
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
compiled_result = compile_func(self, token)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 299, in do_extends
nodelist = parser.parse()
^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
raise self.error(token, e)
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
compiled_result = compile_func(self, token)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 234, in do_block
nodelist = parser.parse(("endblock",))
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
raise self.error(token, e)
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
compiled_result = compile_func(self, token)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 962, in do_if
nodelist = parser.parse(("elif", "else", "endif"))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
raise self.error(token, e)
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
compiled_result = compile_func(self, token)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 862, in do_for
nodelist_loop = parser.parse(
^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
raise self.error(token, e)
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
compiled_result = compile_func(self, token)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 862, in do_for
nodelist_loop = parser.parse(
^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
raise self.error(token, e)
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
compiled_result = compile_func(self, token)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 962, in do_if
nodelist = parser.parse(("elif", "else", "endif"))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
raise self.error(token, e)
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
compiled_result = compile_func(self, token)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 1531, in do_with
extra_context = token_kwargs(remaining_bits, parser, support_legacy=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 1127, in token_kwargs
kwargs[key] = parser.compile_filter(value)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 609, in compile_filter
return FilterExpression(token, self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 705, in __init__
filter_func = parser.find_filter(filter_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 615, in find_filter
raise TemplateSyntaxError("Invalid filter: '%s'" % filter_name)
django.template.exceptions.TemplateSyntaxError: Invalid filter: 'get_item'
ERROR 2025-11-02 14:52:59,689 basehttp 18386 6198079488 "GET /en/hr/schedules/grid/ HTTP/1.1" 500 333280
ERROR 2025-11-02 14:56:54,423 tasks 16180 8648941888 Appointment 84999784-a5ac-4385-82c0-6beee6a870fe not found
ERROR 2025-11-02 14:56:54,423 tasks 16172 8648941888 Appointment 1ba52899-1a8e-4bce-93bd-d1d643bb7b69 not found
ERROR 2025-11-02 14:57:39,019 log 18386 6198079488 Internal Server Error: /en/hr/schedules/grid/
Traceback (most recent call last):
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
response = response.render()
^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
self.content = self.rendered_content
^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/response.py", line 90, in rendered_content
template = self.resolve_template(self.template_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/response.py", line 72, in resolve_template
return select_template(template, using=self.using)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/loader.py", line 42, in select_template
return engine.get_template(template_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 79, in get_template
return Template(self.engine.get_template(template_name), self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/engine.py", line 177, in get_template
template, origin = self.find_template(template_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/engine.py", line 159, in find_template
template = loader.get_template(name, skip=skip)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/loaders/cached.py", line 57, in get_template
template = super().get_template(template_name, skip)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/loaders/base.py", line 28, in get_template
return Template(
^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 154, in __init__
self.nodelist = self.compile_nodelist()
^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 196, in compile_nodelist
nodelist = parser.parse()
^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
raise self.error(token, e)
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
compiled_result = compile_func(self, token)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 299, in do_extends
nodelist = parser.parse()
^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
raise self.error(token, e)
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
compiled_result = compile_func(self, token)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 234, in do_block
nodelist = parser.parse(("endblock",))
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
raise self.error(token, e)
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
compiled_result = compile_func(self, token)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 962, in do_if
nodelist = parser.parse(("elif", "else", "endif"))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
raise self.error(token, e)
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
compiled_result = compile_func(self, token)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 862, in do_for
nodelist_loop = parser.parse(
^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
raise self.error(token, e)
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
compiled_result = compile_func(self, token)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 862, in do_for
nodelist_loop = parser.parse(
^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
raise self.error(token, e)
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
compiled_result = compile_func(self, token)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 962, in do_if
nodelist = parser.parse(("elif", "else", "endif"))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
raise self.error(token, e)
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
compiled_result = compile_func(self, token)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 1531, in do_with
extra_context = token_kwargs(remaining_bits, parser, support_legacy=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 1127, in token_kwargs
kwargs[key] = parser.compile_filter(value)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 609, in compile_filter
return FilterExpression(token, self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 705, in __init__
filter_func = parser.find_filter(filter_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/marwanalwali/AgdarCentre/.venv/lib/python3.12/site-packages/django/template/base.py", line 615, in find_filter
raise TemplateSyntaxError("Invalid filter: '%s'" % filter_name)
django.template.exceptions.TemplateSyntaxError: Invalid filter: 'get_item'
ERROR 2025-11-02 14:57:39,104 basehttp 18386 6198079488 "GET /en/hr/schedules/grid/ HTTP/1.1" 500 333401
INFO 2025-11-02 14:57:44,128 autoreload 58250 8648941888 Watching for file changes with StatReloader
INFO 2025-11-02 14:57:45,995 basehttp 58250 6137393152 "GET /en/hr/schedules/grid/ HTTP/1.1" 200 161820
INFO 2025-11-02 14:57:55,893 basehttp 58250 6137393152 "GET /en/hr/schedules/cf7163b9-672c-44f1-b48f-b39d8a24b6dc/ HTTP/1.1" 200 34704
INFO 2025-11-02 14:58:01,898 basehttp 58250 6137393152 "GET /en/hr/schedules/cf7163b9-672c-44f1-b48f-b39d8a24b6dc/update/ HTTP/1.1" 200 36723
INFO 2025-11-02 14:58:12,857 basehttp 58250 6137393152 "GET /en/hr/schedules/grid/ HTTP/1.1" 200 161818
INFO 2025-11-02 14:58:14,328 basehttp 58250 6137393152 "GET /en/hr/schedules/create/ HTTP/1.1" 200 36648
INFO 2025-11-02 14:58:30,834 basehttp 58250 6137393152 "GET / HTTP/1.1" 302 0
INFO 2025-11-02 14:58:30,916 basehttp 58250 6154219520 "GET /en/ HTTP/1.1" 200 56415
INFO 2025-11-02 14:58:42,299 basehttp 58250 6154219520 "GET /en/finance/packages/ HTTP/1.1" 200 40594
INFO 2025-11-02 14:58:45,783 basehttp 58250 6154219520 "GET /en/finance/packages/fb821bd4-d545-4c4c-9fbf-8f3597489cf4/update/ HTTP/1.1" 200 44132
ERROR 2025-11-02 14:58:54,055 tasks 16181 8648941888 Appointment 310d15a7-8bf3-4742-9d66-ea672cb4ff53 not found
ERROR 2025-11-02 14:58:54,055 tasks 16180 8648941888 Appointment 35bc0ce1-174a-41ad-bc93-fb7d92e34947 not found
ERROR 2025-11-02 14:58:54,055 tasks 16172 8648941888 Appointment bf8645b9-dc70-43b2-a756-a1cbc04a2bae not found
WARNING 2025-11-02 14:58:56,664 basehttp 58250 6137393152 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 14:58:56,689 basehttp 58250 6137393152 "GET /static/css/default/app.min.css.map HTTP/1.1" 200 2154602
WARNING 2025-11-02 14:58:56,711 log 58250 6154219520 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 14:58:56,711 basehttp 58250 6154219520 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 14:59:18,356 log 58250 6154219520 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 14:59:18,356 basehttp 58250 6154219520 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 14:59:18,417 log 58250 6154219520 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 14:59:18,417 basehttp 58250 6154219520 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
INFO 2025-11-02 14:59:20,557 basehttp 58250 6154219520 "GET /en/finance/packages/create/ HTTP/1.1" 200 43961
WARNING 2025-11-02 14:59:20,629 log 58250 6154219520 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 14:59:20,629 basehttp 58250 6154219520 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 14:59:20,650 basehttp 58250 6154219520 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:00:00,002 tasks 16180 8648941888 Radiology results sync started
INFO 2025-11-02 15:00:00,003 tasks 16180 8648941888 Radiology results sync completed: {'status': 'success', 'new_studies': 0, 'new_reports': 0, 'errors': 0, 'timestamp': '2025-11-02 12:00:00.003104+00:00'}
INFO 2025-11-02 15:00:00,007 tasks 16172 8648941888 Lab results sync started
INFO 2025-11-02 15:00:00,007 tasks 16172 8648941888 Lab results sync completed: {'status': 'success', 'new_results': 0, 'updated_results': 0, 'errors': 0, 'timestamp': '2025-11-02 12:00:00.007361+00:00'}
ERROR 2025-11-02 15:00:00,009 tasks 16180 8648941888 Appointment 7d8e8281-f28e-47b2-bae6-04647dd5204d not found
ERROR 2025-11-02 15:01:03,106 tasks 16172 8648941888 Appointment f3cf1889-ed7b-4416-8f02-ea8113a8b650 not found
ERROR 2025-11-02 15:01:03,106 tasks 16180 8648941888 Appointment 6f4fe326-9e43-4b30-bae0-619526511ee5 not found
INFO 2025-11-02 15:01:49,025 autoreload 58250 8648941888 /Users/marwanalwali/AgdarCentre/finance/forms.py changed, reloading.
INFO 2025-11-02 15:01:49,407 autoreload 60273 8648941888 Watching for file changes with StatReloader
INFO 2025-11-02 15:02:00,876 basehttp 60273 6161133568 "GET /en/finance/packages/create/ HTTP/1.1" 200 41737
WARNING 2025-11-02 15:02:00,958 log 60273 6161133568 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:02:00,958 basehttp 60273 6161133568 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:02:00,987 basehttp 60273 6161133568 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
ERROR 2025-11-02 15:02:03,838 tasks 16180 8648941888 Appointment e494458f-a5fd-481b-97a3-c14466b6f1a1 not found
ERROR 2025-11-02 15:02:04,122 tasks 16180 8648941888 Appointment e494458f-a5fd-481b-97a3-c14466b6f1a1 not found
ERROR 2025-11-02 15:03:35,012 tasks 16181 8648941888 Appointment 0ff795b3-68a3-44e3-ad35-9b50b6e098a8 not found
ERROR 2025-11-02 15:03:35,012 tasks 16172 8648941888 Appointment 642dc474-cd97-4dc0-8924-b2b832eeaea1 not found
ERROR 2025-11-02 15:03:35,012 tasks 16180 8648941888 Appointment 251d4c8d-ad19-44b7-a10b-3b3ff3951257 not found
ERROR 2025-11-02 15:04:52,071 tasks 16172 8648941888 Appointment 6f4fe326-9e43-4b30-bae0-619526511ee5 not found
ERROR 2025-11-02 15:04:52,071 tasks 16180 8648941888 Appointment f3cf1889-ed7b-4416-8f02-ea8113a8b650 not found
ERROR 2025-11-02 15:06:13,808 tasks 16180 8648941888 Appointment d3a1ced0-c9ad-46e7-8c9c-28d5a9e39178 not found
ERROR 2025-11-02 15:06:13,812 tasks 16172 8648941888 Appointment d3a1ced0-c9ad-46e7-8c9c-28d5a9e39178 not found
ERROR 2025-11-02 15:06:13,818 tasks 16180 8648941888 Appointment d3a1ced0-c9ad-46e7-8c9c-28d5a9e39178 not found
ERROR 2025-11-02 15:06:13,927 tasks 16180 8648941888 Appointment d3a1ced0-c9ad-46e7-8c9c-28d5a9e39178 not found
ERROR 2025-11-02 15:06:13,935 tasks 16180 8648941888 Appointment d3a1ced0-c9ad-46e7-8c9c-28d5a9e39178 not found
ERROR 2025-11-02 15:07:00,671 tasks 16180 8648941888 Appointment d3a1ced0-c9ad-46e7-8c9c-28d5a9e39178 not found
INFO 2025-11-02 15:07:10,323 autoreload 60273 8648941888 /Users/marwanalwali/AgdarCentre/finance/models.py changed, reloading.
INFO 2025-11-02 15:07:10,686 autoreload 63004 8648941888 Watching for file changes with StatReloader
INFO 2025-11-02 15:07:49,337 autoreload 63004 8648941888 /Users/marwanalwali/AgdarCentre/finance/admin.py changed, reloading.
INFO 2025-11-02 15:07:49,687 autoreload 63420 8648941888 Watching for file changes with StatReloader
ERROR 2025-11-02 15:08:01,336 tasks 16180 8648941888 Appointment d3a1ced0-c9ad-46e7-8c9c-28d5a9e39178 not found
ERROR 2025-11-02 15:08:58,551 tasks 16172 8648941888 Appointment 1ba52899-1a8e-4bce-93bd-d1d643bb7b69 not found
ERROR 2025-11-02 15:08:58,551 tasks 16180 8648941888 Appointment 84999784-a5ac-4385-82c0-6beee6a870fe not found
INFO 2025-11-02 15:09:25,294 autoreload 63420 8648941888 /Users/marwanalwali/AgdarCentre/finance/forms.py changed, reloading.
INFO 2025-11-02 15:09:25,624 autoreload 64288 8648941888 Watching for file changes with StatReloader
INFO 2025-11-02 15:09:41,782 autoreload 64288 8648941888 /Users/marwanalwali/AgdarCentre/finance/forms.py changed, reloading.
INFO 2025-11-02 15:09:42,069 autoreload 64395 8648941888 Watching for file changes with StatReloader
INFO 2025-11-02 15:10:12,304 autoreload 64395 8648941888 /Users/marwanalwali/AgdarCentre/finance/views.py changed, reloading.
INFO 2025-11-02 15:10:12,618 autoreload 64676 8648941888 Watching for file changes with StatReloader
INFO 2025-11-02 15:11:58,836 autoreload 65634 8648941888 Watching for file changes with StatReloader
INFO 2025-11-02 15:12:01,831 basehttp 65634 6189592576 "GET /en/finance/packages/create/ HTTP/1.1" 200 57459
WARNING 2025-11-02 15:12:01,933 log 65634 6189592576 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:12:01,933 basehttp 65634 6189592576 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:12:01,934 basehttp 65634 6206418944 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:13:10,989 basehttp 65634 13170143232 "GET /en/finance/packages/create/ HTTP/1.1" 200 57538
WARNING 2025-11-02 15:13:11,064 log 65634 13170143232 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:13:11,064 basehttp 65634 13170143232 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:13:11,090 basehttp 65634 13170143232 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:13:59,288 autoreload 65634 8648941888 /Users/marwanalwali/AgdarCentre/finance/forms.py changed, reloading.
INFO 2025-11-02 15:13:59,607 autoreload 66715 8648941888 Watching for file changes with StatReloader
INFO 2025-11-02 15:14:03,144 basehttp 66715 6163656704 "GET /en/finance/packages/create/ HTTP/1.1" 200 57540
WARNING 2025-11-02 15:14:03,247 basehttp 66715 13304360960 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
WARNING 2025-11-02 15:14:03,303 log 66715 6163656704 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:14:03,303 basehttp 66715 6163656704 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16670
INFO 2025-11-02 15:14:04,873 basehttp 66715 6163656704 "GET /en/finance/packages/create/ HTTP/1.1" 200 57538
WARNING 2025-11-02 15:14:04,948 log 66715 6163656704 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:14:04,948 basehttp 66715 6163656704 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:14:04,961 basehttp 66715 6163656704 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:14:13,430 autoreload 66860 8648941888 Watching for file changes with StatReloader
INFO 2025-11-02 15:14:15,779 basehttp 66860 6197473280 "GET /en/finance/packages/create/ HTTP/1.1" 200 57540
WARNING 2025-11-02 15:14:15,892 basehttp 66860 6214299648 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
WARNING 2025-11-02 15:14:15,898 log 66860 6197473280 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:14:15,898 basehttp 66860 6197473280 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16670
ERROR 2025-11-02 15:17:58,789 tasks 16180 8648941888 Appointment b00eedde-1f8d-4556-bef4-07369f144d4e not found
ERROR 2025-11-02 15:17:58,789 tasks 16181 8648941888 Appointment a0aed854-c98c-4d7a-b0d3-981bd7efb97f not found
ERROR 2025-11-02 15:17:58,790 tasks 16173 8648941888 Appointment 7221c9b8-2318-4410-8548-141cae6b9132 not found
ERROR 2025-11-02 15:17:58,791 tasks 16172 8648941888 Appointment d51ff4c0-8550-419f-bc72-c743e6c7098d not found
ERROR 2025-11-02 15:17:58,792 tasks 16182 8648941888 Appointment d1318b1d-29af-448b-a49d-4747e962b336 not found
ERROR 2025-11-02 15:18:44,536 tasks 16180 8648941888 Appointment d3a1ced0-c9ad-46e7-8c9c-28d5a9e39178 not found
ERROR 2025-11-02 15:21:11,927 tasks 16180 8648941888 Appointment d3a1ced0-c9ad-46e7-8c9c-28d5a9e39178 not found
ERROR 2025-11-02 15:21:12,182 tasks 16180 8648941888 Appointment d3a1ced0-c9ad-46e7-8c9c-28d5a9e39178 not found
ERROR 2025-11-02 15:21:40,631 tasks 16180 8648941888 Appointment 4b81a2bd-b651-4c74-96ca-f624d7506c25 not found
ERROR 2025-11-02 15:22:08,369 tasks 16173 8648941888 Appointment 70b4da76-44f5-42a8-92c2-a8915a849a3a not found
ERROR 2025-11-02 15:22:08,369 tasks 16172 8648941888 Appointment 800db3b9-d5ac-452d-8bb4-c046e1b066d7 not found
ERROR 2025-11-02 15:22:08,369 tasks 16181 8648941888 Appointment 0a8e9bd3-9c80-4e96-a583-3159f209047d not found
ERROR 2025-11-02 15:22:08,369 tasks 16182 8648941888 Appointment ec4c2b50-b176-4fb2-b6cb-77b1271cae77 not found
ERROR 2025-11-02 15:22:08,369 tasks 16180 8648941888 Appointment 8b124918-494c-44bb-967a-7a96e1cc2642 not found
ERROR 2025-11-02 15:24:51,817 tasks 16180 8648941888 Appointment 7d8e8281-f28e-47b2-bae6-04647dd5204d not found
ERROR 2025-11-02 15:28:53,975 tasks 16172 8648941888 Appointment b0c1c980-442f-4adc-ac76-2cd181929efd not found
ERROR 2025-11-02 15:28:53,975 tasks 16180 8648941888 Appointment 07419aca-aaed-4f2f-9af3-680578504323 not found
ERROR 2025-11-02 15:29:59,924 tasks 16172 8648941888 Appointment 01e64bc4-bb55-4589-ade8-2d684af8679f not found
ERROR 2025-11-02 15:29:59,924 tasks 16180 8648941888 Appointment 7046f839-aede-4d5e-86f6-716893505439 not found
INFO 2025-11-02 15:30:00,010 tasks 16180 8648941888 Radiology results sync started
INFO 2025-11-02 15:30:00,010 tasks 16180 8648941888 Radiology results sync completed: {'status': 'success', 'new_studies': 0, 'new_reports': 0, 'errors': 0, 'timestamp': '2025-11-02 12:30:00.010630+00:00'}
INFO 2025-11-02 15:30:00,017 tasks 16180 8648941888 Lab results sync started
INFO 2025-11-02 15:30:00,017 tasks 16180 8648941888 Lab results sync completed: {'status': 'success', 'new_results': 0, 'updated_results': 0, 'errors': 0, 'timestamp': '2025-11-02 12:30:00.017207+00:00'}
ERROR 2025-11-02 15:31:03,023 tasks 16181 8648941888 Appointment 642dc474-cd97-4dc0-8924-b2b832eeaea1 not found
ERROR 2025-11-02 15:31:03,024 tasks 16180 8648941888 Appointment 0ff795b3-68a3-44e3-ad35-9b50b6e098a8 not found
ERROR 2025-11-02 15:31:03,023 tasks 16172 8648941888 Appointment 251d4c8d-ad19-44b7-a10b-3b3ff3951257 not found
ERROR 2025-11-02 15:32:03,753 tasks 16180 8648941888 Appointment 8f028c27-4142-489c-91a8-417fa19038bf not found
ERROR 2025-11-02 15:32:04,031 tasks 16180 8648941888 Appointment 8f028c27-4142-489c-91a8-417fa19038bf not found
ERROR 2025-11-02 15:34:51,981 tasks 16180 8648941888 Appointment 251d4c8d-ad19-44b7-a10b-3b3ff3951257 not found
ERROR 2025-11-02 15:34:51,981 tasks 16172 8648941888 Appointment 0ff795b3-68a3-44e3-ad35-9b50b6e098a8 not found
ERROR 2025-11-02 15:34:51,981 tasks 16181 8648941888 Appointment 642dc474-cd97-4dc0-8924-b2b832eeaea1 not found
INFO 2025-11-02 15:36:10,655 basehttp 66860 6197473280 "GET /en/finance/packages/create/ HTTP/1.1" 200 57540
WARNING 2025-11-02 15:36:10,740 basehttp 66860 6214299648 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
WARNING 2025-11-02 15:36:10,741 log 66860 6197473280 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:36:10,741 basehttp 66860 6197473280 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
INFO 2025-11-02 15:36:15,168 basehttp 66860 6197473280 "GET /en/finance/packages/create/ HTTP/1.1" 200 57538
WARNING 2025-11-02 15:36:15,247 log 66860 6197473280 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:36:15,248 basehttp 66860 6197473280 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:36:15,267 basehttp 66860 6197473280 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:36:42,110 basehttp 66860 6214299648 "GET /en/finance/packages/create/ HTTP/1.1" 200 57982
WARNING 2025-11-02 15:36:42,182 log 66860 6214299648 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:36:42,183 basehttp 66860 6214299648 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:36:42,220 basehttp 66860 6214299648 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:37:25,764 autoreload 66860 8648941888 /Users/marwanalwali/AgdarCentre/finance/forms.py changed, reloading.
INFO 2025-11-02 15:37:26,230 autoreload 77901 8648941888 Watching for file changes with StatReloader
WARNING 2025-11-02 15:37:26,923 basehttp 77901 6157529088 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
WARNING 2025-11-02 15:37:27,014 log 77901 12901707776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:37:27,014 basehttp 77901 12901707776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:37:27,074 log 77901 12901707776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:37:27,075 basehttp 77901 12901707776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
INFO 2025-11-02 15:37:28,916 basehttp 77901 12901707776 "GET /en/finance/packages/create/ HTTP/1.1" 200 52910
WARNING 2025-11-02 15:37:28,986 log 77901 12901707776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:37:28,986 basehttp 77901 12901707776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:37:29,020 basehttp 77901 12901707776 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
ERROR 2025-11-02 15:40:24,595 tasks 16180 8648941888 Appointment f3cf1889-ed7b-4416-8f02-ea8113a8b650 not found
ERROR 2025-11-02 15:40:24,594 tasks 16172 8648941888 Appointment 6f4fe326-9e43-4b30-bae0-619526511ee5 not found
INFO 2025-11-02 15:40:34,026 basehttp 77901 6157529088 "GET /en/finance/packages/create/ HTTP/1.1" 200 52555
WARNING 2025-11-02 15:40:34,116 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:40:34,116 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:40:34,124 basehttp 77901 6157529088 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:42:11,603 basehttp 77901 6157529088 "GET /en/finance/packages/create/ HTTP/1.1" 200 52557
WARNING 2025-11-02 15:42:11,706 basehttp 77901 12901707776 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
WARNING 2025-11-02 15:42:11,711 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:42:11,712 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16669
INFO 2025-11-02 15:43:59,095 basehttp 77901 6157529088 "GET /en/finance/packages/create/ HTTP/1.1" 200 52429
WARNING 2025-11-02 15:43:59,171 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:43:59,171 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:43:59,187 basehttp 77901 6157529088 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:44:19,576 basehttp 77901 12901707776 "GET /en/finance/packages/create/ HTTP/1.1" 200 52434
WARNING 2025-11-02 15:44:19,649 log 77901 12901707776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:44:19,649 basehttp 77901 12901707776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:44:19,692 basehttp 77901 12901707776 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:44:20,778 basehttp 77901 6157529088 "GET /en/finance/packages/create/ HTTP/1.1" 200 52434
WARNING 2025-11-02 15:44:20,850 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:44:20,850 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:44:20,876 basehttp 77901 6157529088 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:44:33,112 basehttp 77901 12901707776 "GET /en/finance/packages/create/ HTTP/1.1" 200 52437
WARNING 2025-11-02 15:44:33,189 log 77901 12901707776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:44:33,190 basehttp 77901 12901707776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:44:33,227 basehttp 77901 12901707776 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:44:43,111 basehttp 77901 6157529088 "GET /en/finance/packages/create/ HTTP/1.1" 200 52437
WARNING 2025-11-02 15:44:43,188 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:44:43,188 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:44:43,209 basehttp 77901 6157529088 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:47:37,234 basehttp 77901 6157529088 "POST /en/finance/packages/create/ HTTP/1.1" 302 0
INFO 2025-11-02 15:47:37,304 basehttp 77901 6157529088 "GET /en/finance/packages/ HTTP/1.1" 200 42734
WARNING 2025-11-02 15:47:37,388 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:47:37,388 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:47:37,400 basehttp 77901 6157529088 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:47:47,853 basehttp 77901 12901707776 "GET /en/finance/packages/7b83fae1-71b3-4360-b10f-54955d640db1/update/ HTTP/1.1" 200 62819
WARNING 2025-11-02 15:47:47,926 log 77901 12901707776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:47:47,926 basehttp 77901 12901707776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:47:47,955 basehttp 77901 12901707776 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:47:52,703 basehttp 77901 6157529088 "GET /en/finance/packages/ HTTP/1.1" 200 42414
WARNING 2025-11-02 15:47:52,780 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:47:52,781 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:47:52,791 basehttp 77901 6157529088 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:47:55,809 basehttp 77901 12901707776 "GET /en/ HTTP/1.1" 200 56418
WARNING 2025-11-02 15:47:55,882 log 77901 12901707776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:47:55,882 basehttp 77901 12901707776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:47:55,909 basehttp 77901 12901707776 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
ERROR 2025-11-02 15:47:58,764 tasks 16180 8648941888 Appointment 77bb0820-19c1-473f-a574-3cb8845eb3f9 not found
INFO 2025-11-02 15:48:21,205 basehttp 77901 6157529088 "GET /en/finance/reports/ HTTP/1.1" 200 45947
WARNING 2025-11-02 15:48:21,286 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:48:21,287 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:48:21,330 basehttp 77901 6157529088 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
WARNING 2025-11-02 15:49:26,985 basehttp 77901 6157529088 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
WARNING 2025-11-02 15:49:27,092 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:49:27,092 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16669
WARNING 2025-11-02 15:49:27,194 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:49:27,194 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16669
INFO 2025-11-02 15:51:26,953 basehttp 77901 6157529088 "GET /en/ HTTP/1.1" 200 57783
WARNING 2025-11-02 15:51:27,027 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:51:27,027 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:51:27,073 basehttp 77901 6157529088 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
ERROR 2025-11-02 15:51:40,611 tasks 16180 8648941888 Appointment a754db19-dbcb-40e9-a03e-742e2c13ea83 not found
ERROR 2025-11-02 15:51:40,611 tasks 16181 8648941888 Appointment 80157786-4d02-4e2a-960f-8ff0acdb443b not found
ERROR 2025-11-02 15:51:40,612 tasks 16172 8648941888 Appointment 4e16bbd2-83d1-46e7-a439-b2f3d06fc35a not found
ERROR 2025-11-02 15:51:40,612 tasks 16173 8648941888 Appointment 7d208dcb-490f-4f66-97e0-807f7a4cc9d4 not found
ERROR 2025-11-02 15:52:08,345 tasks 16180 8648941888 Appointment 35bc0ce1-174a-41ad-bc93-fb7d92e34947 not found
ERROR 2025-11-02 15:52:08,345 tasks 16172 8648941888 Appointment bf8645b9-dc70-43b2-a756-a1cbc04a2bae not found
ERROR 2025-11-02 15:52:08,345 tasks 16181 8648941888 Appointment 310d15a7-8bf3-4742-9d66-ea672cb4ff53 not found
INFO 2025-11-02 15:52:48,840 basehttp 77901 6157529088 "GET /en/ HTTP/1.1" 200 56671
WARNING 2025-11-02 15:52:48,912 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:52:48,912 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:52:48,963 basehttp 77901 6157529088 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:53:51,042 basehttp 77901 6157529088 "GET /en/ HTTP/1.1" 200 56804
WARNING 2025-11-02 15:53:51,120 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:53:51,121 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:53:51,161 basehttp 77901 6157529088 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:54:13,667 basehttp 77901 12901707776 "GET /en/ HTTP/1.1" 200 56793
WARNING 2025-11-02 15:54:13,741 log 77901 12901707776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:54:13,741 basehttp 77901 12901707776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:54:13,790 basehttp 77901 12901707776 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
ERROR 2025-11-02 15:54:51,782 tasks 16180 8648941888 Appointment 01e64bc4-bb55-4589-ade8-2d684af8679f not found
ERROR 2025-11-02 15:54:51,782 tasks 16172 8648941888 Appointment 7046f839-aede-4d5e-86f6-716893505439 not found
INFO 2025-11-02 15:55:58,320 basehttp 77901 6157529088 "GET /en/ HTTP/1.1" 200 57146
WARNING 2025-11-02 15:55:58,395 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:55:58,395 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:55:58,443 basehttp 77901 6157529088 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:56:23,634 basehttp 77901 12901707776 "GET /en/ HTTP/1.1" 200 57137
WARNING 2025-11-02 15:56:23,709 log 77901 12901707776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:56:23,709 basehttp 77901 12901707776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:56:23,750 basehttp 77901 12901707776 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 15:58:01,008 basehttp 77901 6157529088 "GET /en/ HTTP/1.1" 200 56508
WARNING 2025-11-02 15:58:01,081 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 15:58:01,082 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 15:58:01,133 basehttp 77901 6157529088 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
ERROR 2025-11-02 15:58:53,924 tasks 16180 8648941888 Appointment e494458f-a5fd-481b-97a3-c14466b6f1a1 not found
INFO 2025-11-02 16:00:00,006 tasks 16180 8648941888 Radiology results sync started
INFO 2025-11-02 16:00:00,007 tasks 16180 8648941888 Radiology results sync completed: {'status': 'success', 'new_studies': 0, 'new_reports': 0, 'errors': 0, 'timestamp': '2025-11-02 13:00:00.007287+00:00'}
INFO 2025-11-02 16:00:00,013 tasks 16180 8648941888 Lab results sync started
INFO 2025-11-02 16:00:00,013 tasks 16180 8648941888 Lab results sync completed: {'status': 'success', 'new_results': 0, 'updated_results': 0, 'errors': 0, 'timestamp': '2025-11-02 13:00:00.013790+00:00'}
INFO 2025-11-02 16:00:00,201 basehttp 77901 6157529088 "GET /en/ HTTP/1.1" 200 51718
WARNING 2025-11-02 16:00:00,272 log 77901 6157529088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 16:00:00,272 basehttp 77901 6157529088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 16:00:00,327 basehttp 77901 6157529088 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
INFO 2025-11-02 16:00:35,311 basehttp 77901 12901707776 "GET /en/ HTTP/1.1" 200 47869
WARNING 2025-11-02 16:00:35,384 log 77901 12901707776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-11-02 16:00:35,385 basehttp 77901 12901707776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 16668
WARNING 2025-11-02 16:00:35,429 basehttp 77901 12901707776 "GET /static/plugins/toastr/toastr.js.map HTTP/1.1" 404 2011
ERROR 2025-11-02 16:02:03,710 tasks 16172 8648941888 Appointment 1ba52899-1a8e-4bce-93bd-d1d643bb7b69 not found
ERROR 2025-11-02 16:02:03,710 tasks 16180 8648941888 Appointment 84999784-a5ac-4385-82c0-6beee6a870fe not found
ERROR 2025-11-02 16:02:03,983 tasks 16180 8648941888 Appointment 84999784-a5ac-4385-82c0-6beee6a870fe not found
ERROR 2025-11-02 16:02:03,983 tasks 16172 8648941888 Appointment 1ba52899-1a8e-4bce-93bd-d1d643bb7b69 not found
INFO 2025-11-02 16:02:12,288 basehttp 77901 6157529088 "GET /en/ HTTP/1.1" 200 47781
INFO 2025-11-02 16:02:22,838 basehttp 77901 6157529088 "GET /en/switch_language/?language=ar HTTP/1.1" 302 0
INFO 2025-11-02 16:02:22,917 basehttp 77901 6157529088 "GET / HTTP/1.1" 302 0
INFO 2025-11-02 16:02:22,996 basehttp 77901 12901707776 "GET /ar/ HTTP/1.1" 200 49014
INFO 2025-11-02 16:02:23,008 basehttp 77901 6157529088 "GET /static/css/rtl-fixes.css HTTP/1.1" 200 1420
INFO 2025-11-02 16:02:23,010 basehttp 77901 12901707776 "GET /static/css/default/app-rtl.min.css HTTP/1.1" 200 1020811
INFO 2025-11-02 16:02:33,341 basehttp 77901 12901707776 "GET /ar/switch_language/?language=en HTTP/1.1" 302 0
INFO 2025-11-02 16:02:33,401 basehttp 77901 12901707776 "GET / HTTP/1.1" 302 0
INFO 2025-11-02 16:02:33,495 basehttp 77901 6157529088 "GET /en/ HTTP/1.1" 200 47778

View File

@ -37,6 +37,7 @@
</div> </div>
</div> </div>
<!-- User Menu - Only visible when authenticated --> <!-- User Menu - Only visible when authenticated -->
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<div class="navbar-item navbar-user dropdown"> <div class="navbar-item navbar-user dropdown">

View File

@ -41,194 +41,194 @@
</div> </div>
</div> </div>
<div class="theme-panel-divider"></div> {# <div class="theme-panel-divider"></div>#}
{# #}
<!-- BEGIN theme-switch --> {# <!-- BEGIN theme-switch -->#}
<div class="row mt-10px align-items-center"> {# <div class="row mt-10px align-items-center">#}
<div class="col-8 control-label text-body fw-bold">Header Fixed</div> {# <div class="col-8 control-label text-body fw-bold">Header Fixed</div>#}
<div class="col-4 d-flex"> {# <div class="col-4 d-flex">#}
<div class="form-check form-switch ms-auto mb-0"> {# <div class="form-check form-switch ms-auto mb-0">#}
<input type="checkbox" class="form-check-input" name="app-header-fixed" id="appHeaderFixed" value="1" checked /> {# <input type="checkbox" class="form-check-input" name="app-header-fixed" id="appHeaderFixed" value="1" checked />#}
<label class="form-check-label" for="appHeaderFixed">&nbsp;</label> {# <label class="form-check-label" for="appHeaderFixed">&nbsp;</label>#}
</div> {# </div>#}
</div> {# </div>#}
</div> {# </div>#}
<div class="row mt-10px align-items-center"> {# <div class="row mt-10px align-items-center">#}
<div class="col-8 control-label text-body fw-bold">Header Inverse</div> {# <div class="col-8 control-label text-body fw-bold">Header Inverse</div>#}
<div class="col-4 d-flex"> {# <div class="col-4 d-flex">#}
<div class="form-check form-switch ms-auto mb-0"> {# <div class="form-check form-switch ms-auto mb-0">#}
<input type="checkbox" class="form-check-input" name="app-header-inverse" id="appHeaderInverse" value="1" /> {# <input type="checkbox" class="form-check-input" name="app-header-inverse" id="appHeaderInverse" value="1" />#}
<label class="form-check-label" for="appHeaderInverse">&nbsp;</label> {# <label class="form-check-label" for="appHeaderInverse">&nbsp;</label>#}
</div> {# </div>#}
</div> {# </div>#}
</div> {# </div>#}
<div class="row mt-10px align-items-center"> {# <div class="row mt-10px align-items-center">#}
<div class="col-8 control-label text-body fw-bold">Sidebar Fixed</div> {# <div class="col-8 control-label text-body fw-bold">Sidebar Fixed</div>#}
<div class="col-4 d-flex"> {# <div class="col-4 d-flex">#}
<div class="form-check form-switch ms-auto mb-0"> {# <div class="form-check form-switch ms-auto mb-0">#}
<input type="checkbox" class="form-check-input" name="app-sidebar-fixed" id="appSidebarFixed" value="1" checked /> {# <input type="checkbox" class="form-check-input" name="app-sidebar-fixed" id="appSidebarFixed" value="1" checked />#}
<label class="form-check-label" for="appSidebarFixed">&nbsp;</label> {# <label class="form-check-label" for="appSidebarFixed">&nbsp;</label>#}
</div> {# </div>#}
</div> {# </div>#}
</div> {# </div>#}
<div class="row mt-10px align-items-center"> {# <div class="row mt-10px align-items-center">#}
<div class="col-8 control-label text-body fw-bold">Sidebar Grid</div> {# <div class="col-8 control-label text-body fw-bold">Sidebar Grid</div>#}
<div class="col-4 d-flex"> {# <div class="col-4 d-flex">#}
<div class="form-check form-switch ms-auto mb-0"> {# <div class="form-check form-switch ms-auto mb-0">#}
<input type="checkbox" class="form-check-input" name="app-sidebar-grid" id="appSidebarGrid" value="1" /> {# <input type="checkbox" class="form-check-input" name="app-sidebar-grid" id="appSidebarGrid" value="1" />#}
<label class="form-check-label" for="appSidebarGrid">&nbsp;</label> {# <label class="form-check-label" for="appSidebarGrid">&nbsp;</label>#}
</div> {# </div>#}
</div> {# </div>#}
</div> {# </div>#}
<div class="row mt-10px align-items-center"> {# <div class="row mt-10px align-items-center">#}
<div class="col-8 control-label text-body fw-bold">Gradient Enabled</div> {# <div class="col-8 control-label text-body fw-bold">Gradient Enabled</div>#}
<div class="col-4 d-flex"> {# <div class="col-4 d-flex">#}
<div class="form-check form-switch ms-auto mb-0"> {# <div class="form-check form-switch ms-auto mb-0">#}
<input type="checkbox" class="form-check-input" name="app-gradient-enabled" id="appGradientEnabled" value="1" /> {# <input type="checkbox" class="form-check-input" name="app-gradient-enabled" id="appGradientEnabled" value="1" />#}
<label class="form-check-label" for="appGradientEnabled">&nbsp;</label> {# <label class="form-check-label" for="appGradientEnabled">&nbsp;</label>#}
</div> {# </div>#}
</div> {# </div>#}
</div> {# </div>#}
<!-- END theme-switch --> {# <!-- END theme-switch -->#}
{# #}
<div class="theme-panel-divider"></div> {# <div class="theme-panel-divider"></div>#}
{# #}
<h5>Admin Design (6)</h5> {# <h5>Admin Design (6)</h5>#}
<!-- BEGIN theme-version --> {# <!-- BEGIN theme-version -->#}
<div class="theme-version"> {# <div class="theme-version">#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/admin/html/index_v2.html" class="theme-version-link active"> {# <a href="https://seantheme.com/color-admin/admin/html/index_v2.html" class="theme-version-link active">#}
<span style="background-image: url({% static 'img/theme/default.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/theme/default.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/admin/transparent/index_v2.html" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/admin/transparent/index_v2.html" class="theme-version-link">#}
<span style="background-image: url({% static 'img/theme/transparent.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/theme/transparent.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/admin/apple/index_v2.html" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/admin/apple/index_v2.html" class="theme-version-link">#}
<span style="background-image: url({% static 'img/theme/apple.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/theme/apple.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/admin/material/index_v2.html" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/admin/material/index_v2.html" class="theme-version-link">#}
<span style="background-image: url({% static 'img/theme/material.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/theme/material.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/admin/facebook/index_v2.html" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/admin/facebook/index_v2.html" class="theme-version-link">#}
<span style="background-image: url({% static 'img/theme/facebook.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/theme/facebook.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/admin/google/index_v2.html" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/admin/google/index_v2.html" class="theme-version-link">#}
<span style="background-image: url({% static 'img/theme/google.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/theme/google.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
</div> {# </div>#}
<!-- END theme-version --> {# <!-- END theme-version -->#}
{# #}
<div class="theme-panel-divider"></div> {# <div class="theme-panel-divider"></div>#}
{##}
<h5>Language Version (9)</h5> {# <h5>Language Version (9)</h5>#}
<!-- BEGIN theme-version --> {# <!-- BEGIN theme-version -->#}
<div class="theme-version"> {# <div class="theme-version">#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/admin/html/" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/admin/html/" class="theme-version-link">#}
<span style="background-image: url({% static 'img/version/html.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/version/html.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/admin/ajax/" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/admin/ajax/" class="theme-version-link">#}
<span style="background-image: url({% static 'img/version/ajax.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/version/ajax.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/admin/angularjs/" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/admin/angularjs/" class="theme-version-link">#}
<span style="background-image: url({% static 'img/version/angular1x.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/version/angular1x.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/admin/angularjs19/" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/admin/angularjs19/" class="theme-version-link">#}
<span style="background-image: url({% static 'img/version/angular10x.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/version/angular10x.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/admin/svelte/" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/admin/svelte/" class="theme-version-link">#}
<span style="background-image: url({% static 'img/version/svelte.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/version/svelte.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="javascript:alert('Laravel Version only available in downloaded version.');" class="theme-version-link"> {# <a href="javascript:alert('Laravel Version only available in downloaded version.');" class="theme-version-link">#}
<span style="background-image: url({% static 'img/version/laravel.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/version/laravel.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="javascript:alert('Django Version only available in downloaded version.');" class="theme-version-link active"> {# <a href="javascript:alert('Django Version only available in downloaded version.');" class="theme-version-link active">#}
<span style="background-image: url({% static 'img/version/django.jpg' %});" class="theme-version-cover "></span> {# <span style="background-image: url({% static 'img/version/django.jpg' %});" class="theme-version-cover "></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/admin/vue3/" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/admin/vue3/" class="theme-version-link">#}
<span style="background-image: url({% static 'img/version/vuejs.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/version/vuejs.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/admin/react/" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/admin/react/" class="theme-version-link">#}
<span style="background-image: url({% static 'img/version/reactjs.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/version/reactjs.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="javascript:alert('.NET Core MVC Version only available in downloaded version.');" class="theme-version-link"> {# <a href="javascript:alert('.NET Core MVC Version only available in downloaded version.');" class="theme-version-link">#}
<span style="background-image: url({% static 'img/version/dotnet.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/version/dotnet.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/admin/nextjs/" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/admin/nextjs/" class="theme-version-link">#}
<span style="background-image: url({% static 'img/version/nextjs.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/version/nextjs.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
</div> {# </div>#}
<!-- END theme-version --> {# <!-- END theme-version -->#}
{##}
<div class="theme-panel-divider"></div> {# <div class="theme-panel-divider"></div>#}
{##}
<h5>Frontend Design (5)</h5> {# <h5>Frontend Design (5)</h5>#}
<!-- BEGIN theme-version --> {# <!-- BEGIN theme-version -->#}
<div class="theme-version"> {# <div class="theme-version">#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/frontend/one-page-parallax/" target="blank" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/frontend/one-page-parallax/" target="blank" class="theme-version-link">#}
<span style="background-image: url({% static 'img/theme/one-page-parallax.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/theme/one-page-parallax.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/frontend/e-commerce/" target="blank" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/frontend/e-commerce/" target="blank" class="theme-version-link">#}
<span style="background-image: url({% static 'img/theme/e-commerce.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/theme/e-commerce.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/frontend/blog/" target="blank" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/frontend/blog/" target="blank" class="theme-version-link">#}
<span style="background-image: url({% static 'img/theme/blog.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/theme/blog.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/frontend/forum/" target="blank" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/frontend/forum/" target="blank" class="theme-version-link">#}
<span style="background-image: url({% static 'img/theme/forum.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/theme/forum.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
<div class="theme-version-item"> {# <div class="theme-version-item">#}
<a href="https://seantheme.com/color-admin/frontend/corporate/" target="blank" class="theme-version-link"> {# <a href="https://seantheme.com/color-admin/frontend/corporate/" target="blank" class="theme-version-link">#}
<span style="background-image: url({% static 'img/theme/corporate.jpg' %});" class="theme-version-cover"></span> {# <span style="background-image: url({% static 'img/theme/corporate.jpg' %});" class="theme-version-cover"></span>#}
</a> {# </a>#}
</div> {# </div>#}
</div> {# </div>#}
<!-- END theme-version --> {# <!-- END theme-version -->#}
{##}
<div class="theme-panel-divider"></div> {# <div class="theme-panel-divider"></div>#}
{##}
<a href="https://seantheme.com/color-admin/documentation/" class="btn btn-dark d-block w-100 rounded-pill mb-10px" target="_blank"><b>Documentation</b></a> {# <a href="https://seantheme.com/color-admin/documentation/" class="btn btn-dark d-block w-100 rounded-pill mb-10px" target="_blank"><b>Documentation</b></a>#}
<a href="javascript:;" class="btn btn-default d-block w-100 rounded-pill" data-toggle="reset-local-storage"><b>Reset Local Storage</b></a> {# <a href="javascript:;" class="btn btn-default d-block w-100 rounded-pill" data-toggle="reset-local-storage"><b>Reset Local Storage</b></a>#}
</div> </div>
</div> </div>
<!-- END theme-panel --> <!-- END theme-panel -->