update
This commit is contained in:
parent
27a71b658a
commit
d912313a27
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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',),
|
||||||
|
|||||||
@ -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):
|
||||||
|
|||||||
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
||||||
Binary file not shown.
@ -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):
|
||||||
|
|||||||
@ -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"> </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"> </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 %}
|
||||||
|
|||||||
@ -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):
|
||||||
|
|||||||
@ -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 %}
|
||||||
|
|
||||||
|
|||||||
0
hr/templatetags/__init__.py
Normal file
0
hr/templatetags/__init__.py
Normal file
BIN
hr/templatetags/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
hr/templatetags/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
hr/templatetags/__pycache__/hr_tags.cpython-312.pyc
Normal file
BIN
hr/templatetags/__pycache__/hr_tags.cpython-312.pyc
Normal file
Binary file not shown.
14
hr/templatetags/hr_tags.py
Normal file
14
hr/templatetags/hr_tags.py
Normal 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)
|
||||||
494
logs/django.log
494
logs/django.log
@ -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
|
||||||
|
|||||||
@ -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">
|
||||||
|
|||||||
@ -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"> </label>
|
{# <label class="form-check-label" for="appHeaderFixed"> </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"> </label>
|
{# <label class="form-check-label" for="appHeaderInverse"> </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"> </label>
|
{# <label class="form-check-label" for="appSidebarFixed"> </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"> </label>
|
{# <label class="form-check-label" for="appSidebarGrid"> </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"> </label>
|
{# <label class="form-check-label" for="appGradientEnabled"> </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 -->
|
||||||
Loading…
x
Reference in New Issue
Block a user