Compare commits
3 Commits
0ce441336f
...
d68e6ea5fe
Author | SHA1 | Date | |
---|---|---|---|
d68e6ea5fe | |||
c1af9850e1 | |||
029b4dff28 |
@ -96,6 +96,7 @@ TIME_ZONE = "America/New_York"
|
|||||||
USE_I18N = False
|
USE_I18N = False
|
||||||
USE_L10N = True
|
USE_L10N = True
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
USE_DEPRECATED_PYTZ = False
|
||||||
|
|
||||||
|
|
||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
|
63
doorcontrol/tables.py
Normal file
63
doorcontrol/tables.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import calendar
|
||||||
|
|
||||||
|
import django_tables2 as tables
|
||||||
|
|
||||||
|
from .models import HIDEvent
|
||||||
|
|
||||||
|
|
||||||
|
class UnitTimeTable(tables.Table):
|
||||||
|
members = tables.columns.Column()
|
||||||
|
members_delta = tables.columns.TemplateColumn(
|
||||||
|
"{{ value|floatformat:2}}%", verbose_name="Δ Members"
|
||||||
|
)
|
||||||
|
access_count = tables.columns.Column()
|
||||||
|
access_count_delta = tables.columns.TemplateColumn(
|
||||||
|
"{{ value|floatformat:2}}%", verbose_name="Δ Access Count"
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
fields = ("members", "members_delta", "access_count", "access_count_delta")
|
||||||
|
|
||||||
|
|
||||||
|
class DeniedAccessTable(tables.Table):
|
||||||
|
name = tables.TemplateColumn(
|
||||||
|
"{{ record.forename|default:'' }} {{ record.surname|default:'' }}"
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = HIDEvent
|
||||||
|
|
||||||
|
fields = (
|
||||||
|
"timestamp",
|
||||||
|
"door",
|
||||||
|
"event_type",
|
||||||
|
"name",
|
||||||
|
"raw_card_number",
|
||||||
|
"decoded_card_number",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class MostActiveMembersTable(tables.Table):
|
||||||
|
name = tables.Column()
|
||||||
|
access_count = tables.Column()
|
||||||
|
|
||||||
|
|
||||||
|
class DetailByDayTable(tables.Table):
|
||||||
|
timestamp__date = tables.DateColumn(verbose_name="Date")
|
||||||
|
name = tables.Column()
|
||||||
|
access_count = tables.Column()
|
||||||
|
|
||||||
|
|
||||||
|
class BusiestDayOfWeekTable(tables.Table):
|
||||||
|
timestamp__week_day = tables.Column("Week Day")
|
||||||
|
events = tables.Column()
|
||||||
|
members = tables.Column()
|
||||||
|
|
||||||
|
def render_timestamp__week_day(self, value):
|
||||||
|
return calendar.day_name[(value - 2) % 7]
|
||||||
|
|
||||||
|
|
||||||
|
class BusiestTimeOfDayTable(tables.Table):
|
||||||
|
timestamp__hour = tables.TemplateColumn("{{ value }}:00", verbose_name="Hour")
|
||||||
|
events = tables.Column()
|
||||||
|
members = tables.Column()
|
@ -1,4 +1,3 @@
|
|||||||
import calendar
|
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||||
@ -19,6 +18,14 @@ from django_tables2 import SingleTableMixin
|
|||||||
from django_tables2.export.views import ExportMixin
|
from django_tables2.export.views import ExportMixin
|
||||||
|
|
||||||
from .models import Door, HIDEvent
|
from .models import Door, HIDEvent
|
||||||
|
from .tables import (
|
||||||
|
BusiestDayOfWeekTable,
|
||||||
|
BusiestTimeOfDayTable,
|
||||||
|
DeniedAccessTable,
|
||||||
|
DetailByDayTable,
|
||||||
|
MostActiveMembersTable,
|
||||||
|
UnitTimeTable,
|
||||||
|
)
|
||||||
|
|
||||||
REPORTS = []
|
REPORTS = []
|
||||||
|
|
||||||
@ -96,20 +103,6 @@ class BaseAccessReport(
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class UnitTimeTable(tables.Table):
|
|
||||||
members = tables.columns.Column()
|
|
||||||
members_delta = tables.columns.TemplateColumn(
|
|
||||||
"{{ value|floatformat:2}}%", verbose_name="Δ Members"
|
|
||||||
)
|
|
||||||
access_count = tables.columns.Column()
|
|
||||||
access_count_delta = tables.columns.TemplateColumn(
|
|
||||||
"{{ value|floatformat:2}}%", verbose_name="Δ Access Count"
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
fields = ("members", "members_delta", "access_count", "access_count_delta")
|
|
||||||
|
|
||||||
|
|
||||||
@register_report
|
@register_report
|
||||||
class AccessPerUnitTime(BaseAccessReport):
|
class AccessPerUnitTime(BaseAccessReport):
|
||||||
table_class = UnitTimeTable
|
table_class = UnitTimeTable
|
||||||
@ -209,24 +202,6 @@ class AccessPerUnitTime(BaseAccessReport):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class DeniedAccessTable(tables.Table):
|
|
||||||
name = tables.TemplateColumn(
|
|
||||||
"{{ record.forename|default:'' }} {{ record.surname|default:'' }}"
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = HIDEvent
|
|
||||||
|
|
||||||
fields = (
|
|
||||||
"timestamp",
|
|
||||||
"door",
|
|
||||||
"event_type",
|
|
||||||
"name",
|
|
||||||
"raw_card_number",
|
|
||||||
"decoded_card_number",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@register_report
|
@register_report
|
||||||
class DeniedAccess(BaseAccessReport):
|
class DeniedAccess(BaseAccessReport):
|
||||||
_report_name = "Denied Access"
|
_report_name = "Denied Access"
|
||||||
@ -244,11 +219,6 @@ class DeniedAccess(BaseAccessReport):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class MostActiveMembersTable(tables.Table):
|
|
||||||
name = tables.Column()
|
|
||||||
access_count = tables.Column()
|
|
||||||
|
|
||||||
|
|
||||||
@register_report
|
@register_report
|
||||||
class MostActiveMembers(BaseAccessReport):
|
class MostActiveMembers(BaseAccessReport):
|
||||||
_report_name = "Most Active Members"
|
_report_name = "Most Active Members"
|
||||||
@ -271,12 +241,6 @@ class MostActiveMembers(BaseAccessReport):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class DetailByDayTable(tables.Table):
|
|
||||||
timestamp__date = tables.DateColumn(verbose_name="Date")
|
|
||||||
name = tables.Column()
|
|
||||||
access_count = tables.Column()
|
|
||||||
|
|
||||||
|
|
||||||
@register_report
|
@register_report
|
||||||
class DetailByDay(BaseAccessReport):
|
class DetailByDay(BaseAccessReport):
|
||||||
_report_name = "Detail by Day"
|
_report_name = "Detail by Day"
|
||||||
@ -299,15 +263,6 @@ class DetailByDay(BaseAccessReport):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class BusiestDayOfWeekTable(tables.Table):
|
|
||||||
timestamp__week_day = tables.Column("Week Day")
|
|
||||||
events = tables.Column()
|
|
||||||
members = tables.Column()
|
|
||||||
|
|
||||||
def render_timestamp__week_day(self, value):
|
|
||||||
return calendar.day_name[(value - 2) % 7]
|
|
||||||
|
|
||||||
|
|
||||||
@register_report
|
@register_report
|
||||||
class BusiestDayOfWeek(BaseAccessReport):
|
class BusiestDayOfWeek(BaseAccessReport):
|
||||||
_report_name = "Busiest Day of the Week"
|
_report_name = "Busiest Day of the Week"
|
||||||
@ -326,12 +281,6 @@ class BusiestDayOfWeek(BaseAccessReport):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class BusiestTimeOfDayTable(tables.Table):
|
|
||||||
timestamp__hour = tables.TemplateColumn("{{ value }}:00", verbose_name="Hour")
|
|
||||||
events = tables.Column()
|
|
||||||
members = tables.Column()
|
|
||||||
|
|
||||||
|
|
||||||
@register_report
|
@register_report
|
||||||
class BusiestTimeOfDay(BaseAccessReport):
|
class BusiestTimeOfDay(BaseAccessReport):
|
||||||
_report_name = "Busiest Time of Day"
|
_report_name = "Busiest Time of Day"
|
||||||
|
168
membershipworks/tables.py
Normal file
168
membershipworks/tables.py
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from django.template.defaultfilters import floatformat
|
||||||
|
from django.utils.html import format_html
|
||||||
|
from django.utils.safestring import SafeString
|
||||||
|
|
||||||
|
import django_tables2 as tables
|
||||||
|
|
||||||
|
from .models import EventAttendee, EventExt, Member
|
||||||
|
|
||||||
|
|
||||||
|
class DurationColumn(tables.Column):
|
||||||
|
def render(self, value: timedelta):
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
return floatformat(value.total_seconds() / 60 / 60, -2)
|
||||||
|
|
||||||
|
def value(self, value: timedelta):
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
return value.total_seconds() / 60 / 60
|
||||||
|
|
||||||
|
|
||||||
|
class EventTable(tables.Table):
|
||||||
|
title = tables.TemplateColumn(
|
||||||
|
template_code=(
|
||||||
|
'<a title="MembershipWorks" href="https://membershipworks.com/admin/#!event/admin/{{ record.url }}">{{ value }}</a> '
|
||||||
|
'<a title="Admin" href="{% url "admin:membershipworks_eventext_change" record.pk %}"><i class="bi bi-pencil-square"></i></a> '
|
||||||
|
'<a title="Details" href="{% url "membershipworks:event-detail" record.pk %}"><i class="bi bi-receipt"></i></a> '
|
||||||
|
),
|
||||||
|
accessor="unescaped_title",
|
||||||
|
)
|
||||||
|
occurred = tables.BooleanColumn(visible=False)
|
||||||
|
start = tables.DateColumn("N d, Y")
|
||||||
|
duration = DurationColumn()
|
||||||
|
person_hours = DurationColumn()
|
||||||
|
meetings = tables.Column()
|
||||||
|
gross_revenue = tables.Column()
|
||||||
|
total_due_to_instructor = tables.Column()
|
||||||
|
net_revenue = tables.Column()
|
||||||
|
invoice__date_submitted = tables.DateColumn(verbose_name="Invoice Submitted")
|
||||||
|
invoice__date_paid = tables.DateColumn(verbose_name="Invoice Paid")
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = EventExt
|
||||||
|
fields = (
|
||||||
|
"title",
|
||||||
|
"occurred",
|
||||||
|
"start",
|
||||||
|
"instructor",
|
||||||
|
"category",
|
||||||
|
"count",
|
||||||
|
"cap",
|
||||||
|
"meetings",
|
||||||
|
"duration",
|
||||||
|
"person_hours",
|
||||||
|
"gross_revenue",
|
||||||
|
"total_due_to_instructor",
|
||||||
|
"net_revenue",
|
||||||
|
)
|
||||||
|
row_attrs = {
|
||||||
|
"class": lambda record: (
|
||||||
|
"" if record.occurred else "text-decoration-line-through table-danger"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class EventSummaryTable(tables.Table):
|
||||||
|
event_count = tables.Column("Events")
|
||||||
|
canceled_event_count = tables.Column("Canceled Events")
|
||||||
|
count__sum = tables.Column("Tickets")
|
||||||
|
instructor__count = tables.Column("Unique Instructors")
|
||||||
|
meetings__sum = tables.Column("Meetings")
|
||||||
|
duration__sum = DurationColumn("Class Hours")
|
||||||
|
person_hours__sum = DurationColumn("Person Hours")
|
||||||
|
gross_revenue__sum = tables.Column("Gross Revenue")
|
||||||
|
total_due_to_instructor__sum = tables.Column("Total Due to Instructor")
|
||||||
|
net_revenue__sum = tables.Column("Net Revenue")
|
||||||
|
|
||||||
|
|
||||||
|
class UserEventTable(EventTable):
|
||||||
|
title = tables.Column(linkify=True, accessor="unescaped_title")
|
||||||
|
instructor = None
|
||||||
|
person_hours = None
|
||||||
|
gross_revenue = None
|
||||||
|
net_revenue = None
|
||||||
|
|
||||||
|
|
||||||
|
class InvoiceMoneyColumn(tables.columns.Column):
|
||||||
|
def render(self, value):
|
||||||
|
return f"${super().render(value):.2f}"
|
||||||
|
|
||||||
|
|
||||||
|
class InvoiceMoneyFooterColumn(InvoiceMoneyColumn):
|
||||||
|
def render_footer(self, bound_column, table):
|
||||||
|
value = getattr(table.event, bound_column.accessor)
|
||||||
|
if value is not None:
|
||||||
|
return f"${value:.2f}"
|
||||||
|
else:
|
||||||
|
return bound_column.default
|
||||||
|
|
||||||
|
|
||||||
|
class InvoiceTable(tables.Table):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.event = kwargs.pop("event")
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _math_header(name: str, formula: str) -> SafeString:
|
||||||
|
return format_html(
|
||||||
|
'{} <div class="text-nowrap font-monospace fw-light">[{}]</div>',
|
||||||
|
name,
|
||||||
|
formula,
|
||||||
|
)
|
||||||
|
|
||||||
|
label = tables.Column("Ticket Type", footer="Subtotals")
|
||||||
|
list_price = InvoiceMoneyColumn("Ticket Price")
|
||||||
|
actual_price = InvoiceMoneyColumn(_math_header("Actual Price", "P"))
|
||||||
|
quantity = tables.Column(
|
||||||
|
_math_header("Quantity", "Q"),
|
||||||
|
footer=lambda table: table.event.quantity,
|
||||||
|
)
|
||||||
|
amount = InvoiceMoneyFooterColumn(_math_header("Amount", "A=P*Q"))
|
||||||
|
materials = InvoiceMoneyFooterColumn(
|
||||||
|
_math_header("CMS Collected Materials Fee", "M=m*Q")
|
||||||
|
)
|
||||||
|
amount_without_materials = InvoiceMoneyFooterColumn(
|
||||||
|
_math_header("Event Revenue Base", "B=A-M")
|
||||||
|
)
|
||||||
|
instructor_revenue = InvoiceMoneyFooterColumn(
|
||||||
|
_math_header("Instructor Percentage Revenue", "R=B*I")
|
||||||
|
)
|
||||||
|
instructor_amount = InvoiceMoneyFooterColumn(
|
||||||
|
_math_header("Amount Due to Instructor", "R+M")
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
attrs = {
|
||||||
|
"class": "table table-sm mx-auto w-auto",
|
||||||
|
"tbody": {"class": "table-group-divider"},
|
||||||
|
"tfoot": {"class": "table-group-divider"},
|
||||||
|
}
|
||||||
|
orderable = False
|
||||||
|
|
||||||
|
|
||||||
|
class EventAttendeeTable(tables.Table):
|
||||||
|
class Meta:
|
||||||
|
model = EventAttendee
|
||||||
|
fields = ("name", "email")
|
||||||
|
|
||||||
|
|
||||||
|
class MissingPaperworkTable(tables.Table):
|
||||||
|
policy_agreement = tables.BooleanColumn()
|
||||||
|
authorize_charge = tables.BooleanColumn()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Member
|
||||||
|
fields = [
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"membership",
|
||||||
|
"billing_method",
|
||||||
|
"join_date",
|
||||||
|
"membership_agreement_signed_and_on_file_date",
|
||||||
|
"waiver_form_signed_and_on_file_date",
|
||||||
|
"policy_agreement",
|
||||||
|
"authorize_charge",
|
||||||
|
]
|
@ -1,5 +1,5 @@
|
|||||||
import uuid
|
import uuid
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -15,12 +15,9 @@ from django.db.models import OuterRef, Q, Subquery
|
|||||||
from django.db.models.functions import TruncMonth, TruncYear
|
from django.db.models.functions import TruncMonth, TruncYear
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.template.defaultfilters import floatformat
|
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.html import format_html
|
|
||||||
from django.utils.safestring import SafeString
|
|
||||||
from django.views.generic import DetailView, ListView
|
from django.views.generic import DetailView, ListView
|
||||||
from django.views.generic.dates import (
|
from django.views.generic.dates import (
|
||||||
ArchiveIndexView,
|
ArchiveIndexView,
|
||||||
@ -46,6 +43,14 @@ from membershipworks.membershipworks_api import MembershipWorks
|
|||||||
from .forms import EventInvoiceForm
|
from .forms import EventInvoiceForm
|
||||||
from .invoice_email import make_invoice_emails
|
from .invoice_email import make_invoice_emails
|
||||||
from .models import EventAttendee, EventExt, EventInvoice, Member
|
from .models import EventAttendee, EventExt, EventInvoice, Member
|
||||||
|
from .tables import (
|
||||||
|
EventAttendeeTable,
|
||||||
|
EventSummaryTable,
|
||||||
|
EventTable,
|
||||||
|
InvoiceTable,
|
||||||
|
MissingPaperworkTable,
|
||||||
|
UserEventTable,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class MemberAutocomplete(autocomplete.Select2QuerySetView):
|
class MemberAutocomplete(autocomplete.Select2QuerySetView):
|
||||||
@ -138,75 +143,6 @@ def upcoming_events(request):
|
|||||||
return render(request, "membershipworks/upcoming_events.dj.html", context)
|
return render(request, "membershipworks/upcoming_events.dj.html", context)
|
||||||
|
|
||||||
|
|
||||||
class DurationColumn(tables.Column):
|
|
||||||
def render(self, value: timedelta):
|
|
||||||
if value is None:
|
|
||||||
return None
|
|
||||||
return floatformat(value.total_seconds() / 60 / 60, -2)
|
|
||||||
|
|
||||||
def value(self, value: timedelta):
|
|
||||||
if value is None:
|
|
||||||
return None
|
|
||||||
return value.total_seconds() / 60 / 60
|
|
||||||
|
|
||||||
|
|
||||||
class EventTable(tables.Table):
|
|
||||||
title = tables.TemplateColumn(
|
|
||||||
template_code=(
|
|
||||||
'<a title="MembershipWorks" href="https://membershipworks.com/admin/#!event/admin/{{ record.url }}">{{ value }}</a> '
|
|
||||||
'<a title="Admin" href="{% url "admin:membershipworks_eventext_change" record.pk %}"><i class="bi bi-pencil-square"></i></a> '
|
|
||||||
'<a title="Details" href="{% url "membershipworks:event-detail" record.pk %}"><i class="bi bi-receipt"></i></a> '
|
|
||||||
),
|
|
||||||
accessor="unescaped_title",
|
|
||||||
)
|
|
||||||
occurred = tables.BooleanColumn(visible=False)
|
|
||||||
start = tables.DateColumn("N d, Y")
|
|
||||||
duration = DurationColumn()
|
|
||||||
person_hours = DurationColumn()
|
|
||||||
meetings = tables.Column()
|
|
||||||
gross_revenue = tables.Column()
|
|
||||||
total_due_to_instructor = tables.Column()
|
|
||||||
net_revenue = tables.Column()
|
|
||||||
invoice__date_submitted = tables.DateColumn(verbose_name="Invoice Submitted")
|
|
||||||
invoice__date_paid = tables.DateColumn(verbose_name="Invoice Paid")
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = EventExt
|
|
||||||
fields = (
|
|
||||||
"title",
|
|
||||||
"occurred",
|
|
||||||
"start",
|
|
||||||
"instructor",
|
|
||||||
"category",
|
|
||||||
"count",
|
|
||||||
"cap",
|
|
||||||
"meetings",
|
|
||||||
"duration",
|
|
||||||
"person_hours",
|
|
||||||
"gross_revenue",
|
|
||||||
"total_due_to_instructor",
|
|
||||||
"net_revenue",
|
|
||||||
)
|
|
||||||
row_attrs = {
|
|
||||||
"class": lambda record: (
|
|
||||||
"" if record.occurred else "text-decoration-line-through table-danger"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class EventSummaryTable(tables.Table):
|
|
||||||
event_count = tables.Column("Events")
|
|
||||||
canceled_event_count = tables.Column("Canceled Events")
|
|
||||||
count__sum = tables.Column("Tickets")
|
|
||||||
instructor__count = tables.Column("Unique Instructors")
|
|
||||||
meetings__sum = tables.Column("Meetings")
|
|
||||||
duration__sum = DurationColumn("Class Hours")
|
|
||||||
person_hours__sum = DurationColumn("Person Hours")
|
|
||||||
gross_revenue__sum = tables.Column("Gross Revenue")
|
|
||||||
total_due_to_instructor__sum = tables.Column("Total Due to Instructor")
|
|
||||||
net_revenue__sum = tables.Column("Net Revenue")
|
|
||||||
|
|
||||||
|
|
||||||
class EventIndexReport(
|
class EventIndexReport(
|
||||||
ExportMixin, SingleTableMixin, PermissionRequiredMixin, ArchiveIndexView
|
ExportMixin, SingleTableMixin, PermissionRequiredMixin, ArchiveIndexView
|
||||||
):
|
):
|
||||||
@ -303,14 +239,6 @@ class EventMonthReport(
|
|||||||
return f"mw_events_{self.get_year()}-{self.get_month():02}.{export_format}"
|
return f"mw_events_{self.get_year()}-{self.get_month():02}.{export_format}"
|
||||||
|
|
||||||
|
|
||||||
class UserEventTable(EventTable):
|
|
||||||
title = tables.Column(linkify=True, accessor="unescaped_title")
|
|
||||||
instructor = None
|
|
||||||
person_hours = None
|
|
||||||
gross_revenue = None
|
|
||||||
net_revenue = None
|
|
||||||
|
|
||||||
|
|
||||||
class UserEventView(SingleTableMixin, ListView):
|
class UserEventView(SingleTableMixin, ListView):
|
||||||
model = EventExt
|
model = EventExt
|
||||||
table_class = UserEventTable
|
table_class = UserEventTable
|
||||||
@ -339,63 +267,6 @@ class UserEventView(SingleTableMixin, ListView):
|
|||||||
return f"my_events_{self.member.uid if self.member is not None else 'no-uid'}.{export_format}"
|
return f"my_events_{self.member.uid if self.member is not None else 'no-uid'}.{export_format}"
|
||||||
|
|
||||||
|
|
||||||
class InvoiceMoneyColumn(tables.columns.Column):
|
|
||||||
def render(self, value):
|
|
||||||
return f"${super().render(value):.2f}"
|
|
||||||
|
|
||||||
|
|
||||||
class InvoiceMoneyFooterColumn(InvoiceMoneyColumn):
|
|
||||||
def render_footer(self, bound_column, table):
|
|
||||||
value = getattr(table.event, bound_column.accessor)
|
|
||||||
if value is not None:
|
|
||||||
return f"${value:.2f}"
|
|
||||||
else:
|
|
||||||
return bound_column.default
|
|
||||||
|
|
||||||
|
|
||||||
class InvoiceTable(tables.Table):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
self.event = kwargs.pop("event")
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _math_header(name: str, formula: str) -> SafeString:
|
|
||||||
return format_html(
|
|
||||||
'{} <div class="text-nowrap font-monospace fw-light">[{}]</div>',
|
|
||||||
name,
|
|
||||||
formula,
|
|
||||||
)
|
|
||||||
|
|
||||||
label = tables.Column("Ticket Type", footer="Subtotals")
|
|
||||||
list_price = InvoiceMoneyColumn("Ticket Price")
|
|
||||||
actual_price = InvoiceMoneyColumn(_math_header("Actual Price", "P"))
|
|
||||||
quantity = tables.Column(
|
|
||||||
_math_header("Quantity", "Q"),
|
|
||||||
footer=lambda table: table.event.quantity,
|
|
||||||
)
|
|
||||||
amount = InvoiceMoneyFooterColumn(_math_header("Amount", "A=P*Q"))
|
|
||||||
materials = InvoiceMoneyFooterColumn(
|
|
||||||
_math_header("CMS Collected Materials Fee", "M=m*Q")
|
|
||||||
)
|
|
||||||
amount_without_materials = InvoiceMoneyFooterColumn(
|
|
||||||
_math_header("Event Revenue Base", "B=A-M")
|
|
||||||
)
|
|
||||||
instructor_revenue = InvoiceMoneyFooterColumn(
|
|
||||||
_math_header("Instructor Percentage Revenue", "R=B*I")
|
|
||||||
)
|
|
||||||
instructor_amount = InvoiceMoneyFooterColumn(
|
|
||||||
_math_header("Amount Due to Instructor", "R+M")
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
attrs = {
|
|
||||||
"class": "table table-sm mx-auto w-auto",
|
|
||||||
"tbody": {"class": "table-group-divider"},
|
|
||||||
"tfoot": {"class": "table-group-divider"},
|
|
||||||
}
|
|
||||||
orderable = False
|
|
||||||
|
|
||||||
|
|
||||||
class EventDetailView(
|
class EventDetailView(
|
||||||
SingleTableMixin, FormMixin, AccessMixin, DetailView, ProcessFormView
|
SingleTableMixin, FormMixin, AccessMixin, DetailView, ProcessFormView
|
||||||
):
|
):
|
||||||
@ -527,12 +398,6 @@ class EventInvoicePDFView(AccessMixin, BaseDetailView):
|
|||||||
return self.handle_no_permission()
|
return self.handle_no_permission()
|
||||||
|
|
||||||
|
|
||||||
class EventAttendeeTable(tables.Table):
|
|
||||||
class Meta:
|
|
||||||
model = EventAttendee
|
|
||||||
fields = ("name", "email")
|
|
||||||
|
|
||||||
|
|
||||||
class EventAttendeeFilters(django_filters.FilterSet):
|
class EventAttendeeFilters(django_filters.FilterSet):
|
||||||
new_since = django_filters.DateFilter(
|
new_since = django_filters.DateFilter(
|
||||||
field_name="event__start", method="filter_new_since"
|
field_name="event__start", method="filter_new_since"
|
||||||
@ -560,25 +425,6 @@ class EventAttendeeListView(
|
|||||||
return super().get_table_data().values("name", "email").distinct()
|
return super().get_table_data().values("name", "email").distinct()
|
||||||
|
|
||||||
|
|
||||||
class MissingPaperworkTable(tables.Table):
|
|
||||||
policy_agreement = tables.BooleanColumn()
|
|
||||||
authorize_charge = tables.BooleanColumn()
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = Member
|
|
||||||
fields = [
|
|
||||||
"first_name",
|
|
||||||
"last_name",
|
|
||||||
"membership",
|
|
||||||
"billing_method",
|
|
||||||
"join_date",
|
|
||||||
"membership_agreement_signed_and_on_file_date",
|
|
||||||
"waiver_form_signed_and_on_file_date",
|
|
||||||
"policy_agreement",
|
|
||||||
"authorize_charge",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class MissingPaperworkReport(
|
class MissingPaperworkReport(
|
||||||
ExportMixin,
|
ExportMixin,
|
||||||
SingleTableMixin,
|
SingleTableMixin,
|
||||||
|
92
paperwork/tables.py
Normal file
92
paperwork/tables.py
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
import django_tables2 as tables
|
||||||
|
|
||||||
|
from .models import (
|
||||||
|
InstructorOrVendor,
|
||||||
|
Waiver,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class WarnEmptyColumn(tables.Column):
|
||||||
|
attrs = {
|
||||||
|
"td": {
|
||||||
|
"class": lambda value, bound_column: (
|
||||||
|
"table-danger" if value == bound_column.default else ""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class WaiverReportTable(tables.Table):
|
||||||
|
emergency_contact_name = WarnEmptyColumn()
|
||||||
|
emergency_contact_number = WarnEmptyColumn()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Waiver
|
||||||
|
fields = [
|
||||||
|
"name",
|
||||||
|
"date",
|
||||||
|
"emergency_contact_name",
|
||||||
|
"emergency_contact_number",
|
||||||
|
"waiver_version",
|
||||||
|
"guardian_name",
|
||||||
|
"guardian_relation",
|
||||||
|
"guardian_date",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class InstructorOrVendorTable(tables.Table):
|
||||||
|
instructor_agreement_date = WarnEmptyColumn(
|
||||||
|
"Instructor Agreement Date(s)", default="Missing"
|
||||||
|
)
|
||||||
|
w9_date = WarnEmptyColumn(default="Missing")
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = InstructorOrVendor
|
||||||
|
fields = [
|
||||||
|
"name",
|
||||||
|
"instructor_agreement_date",
|
||||||
|
"w9_date",
|
||||||
|
"phone",
|
||||||
|
"email_address",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ShopAccessErrorColumn(tables.Column):
|
||||||
|
def td_class(value):
|
||||||
|
if value.startswith("Has access but"):
|
||||||
|
return "table-danger"
|
||||||
|
elif value.startswith("Has cert but"):
|
||||||
|
return "table-warning"
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
attrs = {"td": {"class": td_class}}
|
||||||
|
|
||||||
|
|
||||||
|
class AccessVerificationTable(tables.Table):
|
||||||
|
account_name = tables.Column()
|
||||||
|
access_card = tables.Column()
|
||||||
|
billing_method = tables.Column()
|
||||||
|
join_date = tables.DateColumn()
|
||||||
|
renewal_date = tables.DateColumn()
|
||||||
|
access_front_door = tables.BooleanColumn(verbose_name="Front Door")
|
||||||
|
access_studio_space = tables.BooleanColumn(verbose_name="Studio Space")
|
||||||
|
wood_shop_error = ShopAccessErrorColumn()
|
||||||
|
metal_shop_error = ShopAccessErrorColumn()
|
||||||
|
extended_hours_error = ShopAccessErrorColumn()
|
||||||
|
extended_hours_shops_error = ShopAccessErrorColumn()
|
||||||
|
storage_closet_error = ShopAccessErrorColumn()
|
||||||
|
|
||||||
|
|
||||||
|
class CertifiersTable(tables.Table):
|
||||||
|
certified_by = tables.Column()
|
||||||
|
certification_version__definition__name = tables.Column("Certification")
|
||||||
|
certification_version__definition__department__name = tables.Column("Department")
|
||||||
|
number_issued_on_this_tool = tables.Column()
|
||||||
|
last_issued_certification_date = tables.Column()
|
||||||
|
|
||||||
|
|
||||||
|
class CertificationCountTable(tables.Table):
|
||||||
|
certification_version__definition__name = tables.Column("Certification")
|
||||||
|
certification_version__definition__department__name = tables.Column("Department")
|
||||||
|
total_issued = tables.Column()
|
@ -19,7 +19,6 @@ from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseNotFou
|
|||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
from django.views.generic import ListView
|
from django.views.generic import ListView
|
||||||
|
|
||||||
import django_tables2 as tables
|
|
||||||
import requests
|
import requests
|
||||||
import weasyprint
|
import weasyprint
|
||||||
from django_mysql.models import GroupConcat
|
from django_mysql.models import GroupConcat
|
||||||
@ -35,6 +34,13 @@ from .models import (
|
|||||||
InstructorOrVendor,
|
InstructorOrVendor,
|
||||||
Waiver,
|
Waiver,
|
||||||
)
|
)
|
||||||
|
from .tables import (
|
||||||
|
AccessVerificationTable,
|
||||||
|
CertificationCountTable,
|
||||||
|
CertifiersTable,
|
||||||
|
InstructorOrVendorTable,
|
||||||
|
WaiverReportTable,
|
||||||
|
)
|
||||||
|
|
||||||
WIKI_URL = settings.WIKI_URL
|
WIKI_URL = settings.WIKI_URL
|
||||||
|
|
||||||
@ -120,34 +126,6 @@ def certification_pdf(request, cert_name):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class WarnEmptyColumn(tables.Column):
|
|
||||||
attrs = {
|
|
||||||
"td": {
|
|
||||||
"class": lambda value, bound_column: "table-danger"
|
|
||||||
if value == bound_column.default
|
|
||||||
else ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class WaiverReportTable(tables.Table):
|
|
||||||
emergency_contact_name = WarnEmptyColumn()
|
|
||||||
emergency_contact_number = WarnEmptyColumn()
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = Waiver
|
|
||||||
fields = [
|
|
||||||
"name",
|
|
||||||
"date",
|
|
||||||
"emergency_contact_name",
|
|
||||||
"emergency_contact_number",
|
|
||||||
"waiver_version",
|
|
||||||
"guardian_name",
|
|
||||||
"guardian_relation",
|
|
||||||
"guardian_date",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class WaiverReport(ExportMixin, SingleTableMixin, PermissionRequiredMixin, ListView):
|
class WaiverReport(ExportMixin, SingleTableMixin, PermissionRequiredMixin, ListView):
|
||||||
permission_required = "paperwork.view_waiver"
|
permission_required = "paperwork.view_waiver"
|
||||||
template_name = "paperwork/waiver_report.dj.html"
|
template_name = "paperwork/waiver_report.dj.html"
|
||||||
@ -156,23 +134,6 @@ class WaiverReport(ExportMixin, SingleTableMixin, PermissionRequiredMixin, ListV
|
|||||||
table_pagination = False
|
table_pagination = False
|
||||||
|
|
||||||
|
|
||||||
class InstructorOrVendorTable(tables.Table):
|
|
||||||
instructor_agreement_date = WarnEmptyColumn(
|
|
||||||
"Instructor Agreement Date(s)", default="Missing"
|
|
||||||
)
|
|
||||||
w9_date = WarnEmptyColumn(default="Missing")
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = InstructorOrVendor
|
|
||||||
fields = [
|
|
||||||
"name",
|
|
||||||
"instructor_agreement_date",
|
|
||||||
"w9_date",
|
|
||||||
"phone",
|
|
||||||
"email_address",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class InstructorOrVendorReport(
|
class InstructorOrVendorReport(
|
||||||
ExportMixin,
|
ExportMixin,
|
||||||
SingleTableMixin,
|
SingleTableMixin,
|
||||||
@ -203,33 +164,6 @@ class InstructorOrVendorReport(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ShopAccessErrorColumn(tables.Column):
|
|
||||||
def td_class(value):
|
|
||||||
if value.startswith("Has access but"):
|
|
||||||
return "table-danger"
|
|
||||||
elif value.startswith("Has cert but"):
|
|
||||||
return "table-warning"
|
|
||||||
else:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
attrs = {"td": {"class": td_class}}
|
|
||||||
|
|
||||||
|
|
||||||
class AccessVerificationTable(tables.Table):
|
|
||||||
account_name = tables.Column()
|
|
||||||
access_card = tables.Column()
|
|
||||||
billing_method = tables.Column()
|
|
||||||
join_date = tables.DateColumn()
|
|
||||||
renewal_date = tables.DateColumn()
|
|
||||||
access_front_door = tables.BooleanColumn(verbose_name="Front Door")
|
|
||||||
access_studio_space = tables.BooleanColumn(verbose_name="Studio Space")
|
|
||||||
wood_shop_error = ShopAccessErrorColumn()
|
|
||||||
metal_shop_error = ShopAccessErrorColumn()
|
|
||||||
extended_hours_error = ShopAccessErrorColumn()
|
|
||||||
extended_hours_shops_error = ShopAccessErrorColumn()
|
|
||||||
storage_closet_error = ShopAccessErrorColumn()
|
|
||||||
|
|
||||||
|
|
||||||
class AccessVerificationReport(
|
class AccessVerificationReport(
|
||||||
ExportMixin,
|
ExportMixin,
|
||||||
SingleTableMixin,
|
SingleTableMixin,
|
||||||
@ -317,14 +251,6 @@ class AccessVerificationReport(
|
|||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
class CertifiersTable(tables.Table):
|
|
||||||
certified_by = tables.Column()
|
|
||||||
certification_version__definition__name = tables.Column("Certification")
|
|
||||||
certification_version__definition__department__name = tables.Column("Department")
|
|
||||||
number_issued_on_this_tool = tables.Column()
|
|
||||||
last_issued_certification_date = tables.Column()
|
|
||||||
|
|
||||||
|
|
||||||
class CertifiersReport(
|
class CertifiersReport(
|
||||||
ExportMixin,
|
ExportMixin,
|
||||||
SingleTableMixin,
|
SingleTableMixin,
|
||||||
@ -356,12 +282,6 @@ class CertifiersReport(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class CertificationCountTable(tables.Table):
|
|
||||||
certification_version__definition__name = tables.Column("Certification")
|
|
||||||
certification_version__definition__department__name = tables.Column("Department")
|
|
||||||
total_issued = tables.Column()
|
|
||||||
|
|
||||||
|
|
||||||
class CertificationCountReport(
|
class CertificationCountReport(
|
||||||
ExportMixin,
|
ExportMixin,
|
||||||
SingleTableMixin,
|
SingleTableMixin,
|
||||||
|
209
pdm.lock
209
pdm.lock
@ -5,7 +5,7 @@
|
|||||||
groups = ["default", "debug", "lint", "server", "typing", "dev"]
|
groups = ["default", "debug", "lint", "server", "typing", "dev"]
|
||||||
strategy = ["cross_platform"]
|
strategy = ["cross_platform"]
|
||||||
lock_version = "4.4.1"
|
lock_version = "4.4.1"
|
||||||
content_hash = "sha256:8d03a3352b70059a88842e3f316ee61450b7690e39a4516b7ce8ebf22aaae5b2"
|
content_hash = "sha256:d2a8240d2754416c9c2c277832f3b8a2401eae3b56bda6e412aaf285c1c3b955"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiohttp"
|
name = "aiohttp"
|
||||||
@ -451,7 +451,7 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "django"
|
name = "django"
|
||||||
version = "5.0.3"
|
version = "5.0.4"
|
||||||
requires_python = ">=3.10"
|
requires_python = ">=3.10"
|
||||||
summary = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
|
summary = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
|
||||||
dependencies = [
|
dependencies = [
|
||||||
@ -460,8 +460,8 @@ dependencies = [
|
|||||||
"tzdata; sys_platform == \"win32\"",
|
"tzdata; sys_platform == \"win32\"",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "Django-5.0.3-py3-none-any.whl", hash = "sha256:5c7d748ad113a81b2d44750ccc41edc14e933f56581683db548c9257e078cc83"},
|
{file = "Django-5.0.4-py3-none-any.whl", hash = "sha256:916423499d75d62da7aa038d19aef23d23498d8df229775eb0a6309ee1013775"},
|
||||||
{file = "Django-5.0.3.tar.gz", hash = "sha256:5fb37580dcf4a262f9258c1f4373819aacca906431f505e4688e37f3a99195df"},
|
{file = "Django-5.0.4.tar.gz", hash = "sha256:4bd01a8c830bb77a8a3b0e7d8b25b887e536ad17a81ba2dce5476135c73312bd"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -479,7 +479,7 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "django-auth-ldap"
|
name = "django-auth-ldap"
|
||||||
version = "4.7.0"
|
version = "4.8.0"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Django LDAP authentication backend"
|
summary = "Django LDAP authentication backend"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
@ -487,8 +487,8 @@ dependencies = [
|
|||||||
"python-ldap>=3.1",
|
"python-ldap>=3.1",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "django-auth-ldap-4.7.0.tar.gz", hash = "sha256:8dea65376b8b2fa1beee52348760e3082e642939a5038cbe881a5e6381b65b8a"},
|
{file = "django-auth-ldap-4.8.0.tar.gz", hash = "sha256:604250938ddc9fda619f247c7a59b0b2f06e53a7d3f46a156f28aa30dd71a738"},
|
||||||
{file = "django_auth_ldap-4.7.0-py3-none-any.whl", hash = "sha256:de02c36e9f9025be9242cd40b5617403a886c72e3c5e0dd489b9b3db996dc875"},
|
{file = "django_auth_ldap-4.8.0-py3-none-any.whl", hash = "sha256:4b4b944f3c28bce362f33fb6e8db68429ed8fd8f12f0c0c4b1a4344a7ef225ce"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -504,15 +504,15 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "django-bootstrap5"
|
name = "django-bootstrap5"
|
||||||
version = "23.4"
|
version = "24.1"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Bootstrap 5 for Django"
|
summary = "Bootstrap 5 for Django"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Django>=3.2",
|
"Django>=3.2",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "django-bootstrap5-23.4.tar.gz", hash = "sha256:fbf9942a17e1f48b4142e78df9e85afb65e4066a20e38ec7c497d36ae5ef7256"},
|
{file = "django-bootstrap5-24.1.tar.gz", hash = "sha256:fc272b5bb218690fe6f32d52b23c155ebb46fbc5a2856c84eb353c1bf5fc49ea"},
|
||||||
{file = "django_bootstrap5-23.4-py3-none-any.whl", hash = "sha256:5181bf1e97afae6211e963f28f48d4a90c937a3b036b3f752f52260f0029f3bc"},
|
{file = "django_bootstrap5-24.1-py3-none-any.whl", hash = "sha256:c42b4f6e673d35af847486733da77104e1e98e7fd5caecc6d56f32a96cc77479"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1018,7 +1018,7 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hypothesis"
|
name = "hypothesis"
|
||||||
version = "6.99.13"
|
version = "6.100.1"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "A library for property-based testing"
|
summary = "A library for property-based testing"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
@ -1026,23 +1026,23 @@ dependencies = [
|
|||||||
"sortedcontainers<3.0.0,>=2.1.0",
|
"sortedcontainers<3.0.0,>=2.1.0",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "hypothesis-6.99.13-py3-none-any.whl", hash = "sha256:b538df1d22365df84f94c38fb2d9c41a222373594c2a910cc8f4ddc68240a62f"},
|
{file = "hypothesis-6.100.1-py3-none-any.whl", hash = "sha256:3dacf6ec90e8d14aaee02cde081ac9a17d5b70105e45e6ac822db72052c0195b"},
|
||||||
{file = "hypothesis-6.99.13.tar.gz", hash = "sha256:e425e8a3f1912e44f62ff3e2768dca19c79f46d43ec70fa56e96e2d7194ccd2d"},
|
{file = "hypothesis-6.100.1.tar.gz", hash = "sha256:ebff09d7fa4f1fb6a855a812baf17e578b4481b7b70ec6d96496210d1a4c6c35"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hypothesis"
|
name = "hypothesis"
|
||||||
version = "6.99.13"
|
version = "6.100.1"
|
||||||
extras = ["django"]
|
extras = ["django"]
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "A library for property-based testing"
|
summary = "A library for property-based testing"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"django>=3.2",
|
"django>=3.2",
|
||||||
"hypothesis==6.99.13",
|
"hypothesis==6.100.1",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "hypothesis-6.99.13-py3-none-any.whl", hash = "sha256:b538df1d22365df84f94c38fb2d9c41a222373594c2a910cc8f4ddc68240a62f"},
|
{file = "hypothesis-6.100.1-py3-none-any.whl", hash = "sha256:3dacf6ec90e8d14aaee02cde081ac9a17d5b70105e45e6ac822db72052c0195b"},
|
||||||
{file = "hypothesis-6.99.13.tar.gz", hash = "sha256:e425e8a3f1912e44f62ff3e2768dca19c79f46d43ec70fa56e96e2d7194ccd2d"},
|
{file = "hypothesis-6.100.1.tar.gz", hash = "sha256:ebff09d7fa4f1fb6a855a812baf17e578b4481b7b70ec6d96496210d1a4c6c35"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1057,7 +1057,7 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipython"
|
name = "ipython"
|
||||||
version = "8.22.2"
|
version = "8.23.0"
|
||||||
requires_python = ">=3.10"
|
requires_python = ">=3.10"
|
||||||
summary = "IPython: Productive Interactive Computing"
|
summary = "IPython: Productive Interactive Computing"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
@ -1070,10 +1070,11 @@ dependencies = [
|
|||||||
"pygments>=2.4.0",
|
"pygments>=2.4.0",
|
||||||
"stack-data",
|
"stack-data",
|
||||||
"traitlets>=5.13.0",
|
"traitlets>=5.13.0",
|
||||||
|
"typing-extensions; python_version < \"3.12\"",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "ipython-8.22.2-py3-none-any.whl", hash = "sha256:3c86f284c8f3d8f2b6c662f885c4889a91df7cd52056fd02b7d8d6195d7f56e9"},
|
{file = "ipython-8.23.0-py3-none-any.whl", hash = "sha256:07232af52a5ba146dc3372c7bf52a0f890a23edf38d77caef8d53f9cdc2584c1"},
|
||||||
{file = "ipython-8.22.2.tar.gz", hash = "sha256:2dcaad9049f9056f1fef63514f176c7d41f930daa78d05b82a176202818f2c14"},
|
{file = "ipython-8.23.0.tar.gz", hash = "sha256:7468edaf4f6de3e1b912e57f66c241e6fd3c7099f2ec2136e239e142e800274d"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1112,41 +1113,77 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lxml"
|
name = "lxml"
|
||||||
version = "5.1.1"
|
version = "5.2.1"
|
||||||
requires_python = ">=3.6"
|
requires_python = ">=3.6"
|
||||||
summary = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API."
|
summary = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API."
|
||||||
files = [
|
files = [
|
||||||
{file = "lxml-5.1.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:906966babd374fdfe46e130fc656488003f0d0d63b7cba612aa5a796c8804283"},
|
{file = "lxml-5.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:70ac664a48aa64e5e635ae5566f5227f2ab7f66a3990d67566d9907edcbbf867"},
|
||||||
{file = "lxml-5.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9c03f3715c68fc707d9383d56e482d95d198ba07cb3dad4aee9e5a5ca06b2536"},
|
{file = "lxml-5.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1ae67b4e737cddc96c99461d2f75d218bdf7a0c3d3ad5604d1f5e7464a2f9ffe"},
|
||||||
{file = "lxml-5.1.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d26243d994d4077a50056e9008848e5b421be0c6f0fd4e932a9463e1d89fc42b"},
|
{file = "lxml-5.2.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f18a5a84e16886898e51ab4b1d43acb3083c39b14c8caeb3589aabff0ee0b270"},
|
||||||
{file = "lxml-5.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2de00750318ae6869b9dfa6429a4f82b8ecad043049414547474d09db549c2ee"},
|
{file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6f2c8372b98208ce609c9e1d707f6918cc118fea4e2c754c9f0812c04ca116d"},
|
||||||
{file = "lxml-5.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29b2771b4eec4e85063f10294facdd9829d010e6cc9668040d0cf936dc56733a"},
|
{file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:394ed3924d7a01b5bd9a0d9d946136e1c2f7b3dc337196d99e61740ed4bc6fe1"},
|
||||||
{file = "lxml-5.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d9358f7268c161dc0a1c3216018f26c04954b5dd47ba6dead79da6598f4725d4"},
|
{file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d077bc40a1fe984e1a9931e801e42959a1e6598edc8a3223b061d30fbd26bbc"},
|
||||||
{file = "lxml-5.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8a943826e7a9254eed661a7134fcde3c832a9fecd989d0f47c6e08c7b769cb2c"},
|
{file = "lxml-5.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:764b521b75701f60683500d8621841bec41a65eb739b8466000c6fdbc256c240"},
|
||||||
{file = "lxml-5.1.1-cp311-cp311-win32.whl", hash = "sha256:74d0967c6f91eec6fe91159f9e8ccb3720fa0fbf9f462109c7bef62550df397c"},
|
{file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:3a6b45da02336895da82b9d472cd274b22dc27a5cea1d4b793874eead23dd14f"},
|
||||||
{file = "lxml-5.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:26974096654241df08a30dc2eb0e139c1ad5653660aa4b2ced66000230e96c14"},
|
{file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:5ea7b6766ac2dfe4bcac8b8595107665a18ef01f8c8343f00710b85096d1b53a"},
|
||||||
{file = "lxml-5.1.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:55e13a19829dcdbf0c5233062977aeb6daf72e65124909128045976f659164e8"},
|
{file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:e196a4ff48310ba62e53a8e0f97ca2bca83cdd2fe2934d8b5cb0df0a841b193a"},
|
||||||
{file = "lxml-5.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:adedfb61be862f48907218e3a24bf051fd2ecca53358f3958b0bdb17d7881c20"},
|
{file = "lxml-5.2.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:200e63525948e325d6a13a76ba2911f927ad399ef64f57898cf7c74e69b71095"},
|
||||||
{file = "lxml-5.1.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:77425482e4311d1cff119a2b5ab26c52ec209d2a3d728a54db3223ab91995e20"},
|
{file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dae0ed02f6b075426accbf6b2863c3d0a7eacc1b41fb40f2251d931e50188dad"},
|
||||||
{file = "lxml-5.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d380f183bd03ab827899753ea96dabe27d2025eb0bfd4f2ac0eee4afa0f351d"},
|
{file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:ab31a88a651039a07a3ae327d68ebdd8bc589b16938c09ef3f32a4b809dc96ef"},
|
||||||
{file = "lxml-5.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8682af96b5ad5093aab9eee5e4ff24cb7a9796c78699d914dd456ebfe7484a6"},
|
{file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:df2e6f546c4df14bc81f9498bbc007fbb87669f1bb707c6138878c46b06f6510"},
|
||||||
{file = "lxml-5.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:68eed33377a9925aed7ba56c8611d50aaa1e45638c07a92b4b4b0a0436cc2dd2"},
|
{file = "lxml-5.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5dd1537e7cc06efd81371f5d1a992bd5ab156b2b4f88834ca852de4a8ea523fa"},
|
||||||
{file = "lxml-5.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c7c1d2f6e9c7a1c4478146ee38d16dbe0eb3be998424bc0f01346c671c38b86d"},
|
{file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9b9ec9c9978b708d488bec36b9e4c94d88fd12ccac3e62134a9d17ddba910ea9"},
|
||||||
{file = "lxml-5.1.1-cp312-cp312-win32.whl", hash = "sha256:81107c8de3e463052ae8fd05fd31b97c371c7a9ce4a189b8bb5f45b0b3545fb9"},
|
{file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8e77c69d5892cb5ba71703c4057091e31ccf534bd7f129307a4d084d90d014b8"},
|
||||||
{file = "lxml-5.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:0e46181d15fae102c53621bed9356b7a599a1e837b978c934a350dd00842b1d9"},
|
{file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a8d5c70e04aac1eda5c829a26d1f75c6e5286c74743133d9f742cda8e53b9c2f"},
|
||||||
{file = "lxml-5.1.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:19c6bc7476eeac4598ff925ae98597610109e21af4cd7ab1e060efcfc4b1c6e2"},
|
{file = "lxml-5.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c94e75445b00319c1fad60f3c98b09cd63fe1134a8a953dcd48989ef42318534"},
|
||||||
{file = "lxml-5.1.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20cd17eb21f5ae54da96791c49e1fbd3327bf66b2c00556cdf8d0552c2270f92"},
|
{file = "lxml-5.2.1-cp311-cp311-win32.whl", hash = "sha256:4951e4f7a5680a2db62f7f4ab2f84617674d36d2d76a729b9a8be4b59b3659be"},
|
||||||
{file = "lxml-5.1.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a02ed1ebc469734dbfed5b688f709334de19e7a333cba7ae187b17d2b2c1d4ff"},
|
{file = "lxml-5.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:5c670c0406bdc845b474b680b9a5456c561c65cf366f8db5a60154088c92d102"},
|
||||||
{file = "lxml-5.1.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:161838cb95c97e8d76d01e544a3570b52ab6b863f4897a90e1f073bb110a75ba"},
|
{file = "lxml-5.2.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:abc25c3cab9ec7fcd299b9bcb3b8d4a1231877e425c650fa1c7576c5107ab851"},
|
||||||
{file = "lxml-5.1.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1abbf2249467a37da45fb2d7ff37e578dfc9813f142800e58db9da761cb7899"},
|
{file = "lxml-5.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6935bbf153f9a965f1e07c2649c0849d29832487c52bb4a5c5066031d8b44fd5"},
|
||||||
{file = "lxml-5.1.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:6c49eb5deaed1990fde5b5d80d6800aec1b5fd6113346b5f11068d988f68f2c4"},
|
{file = "lxml-5.2.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d793bebb202a6000390a5390078e945bbb49855c29c7e4d56a85901326c3b5d9"},
|
||||||
{file = "lxml-5.1.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:60ceffdca5d637fe8ee95c7f06733a6c9646e07da80997efe3af2d4b4f366e36"},
|
{file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd5562927cdef7c4f5550374acbc117fd4ecc05b5007bdfa57cc5355864e0a4"},
|
||||||
{file = "lxml-5.1.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a76a7b35e7660c74eb3f943c19f5f78c882dceab890cf8017027b6100b79ad8e"},
|
{file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0e7259016bc4345a31af861fdce942b77c99049d6c2107ca07dc2bba2435c1d9"},
|
||||||
{file = "lxml-5.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5dcb373720b70aa05419e508265dd86f06886ca0388967f6f024fbc4d551379f"},
|
{file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:530e7c04f72002d2f334d5257c8a51bf409db0316feee7c87e4385043be136af"},
|
||||||
{file = "lxml-5.1.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3641bc124b037921de4220538a5ebb52354fd2799fc2bbfb335d28096063c7d6"},
|
{file = "lxml-5.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59689a75ba8d7ffca577aefd017d08d659d86ad4585ccc73e43edbfc7476781a"},
|
||||||
{file = "lxml-5.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a6e9b34f59c9755aa279c652e1c48c333c665d05a88afcd8e5ff0bde86f3b14"},
|
{file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f9737bf36262046213a28e789cc82d82c6ef19c85a0cf05e75c670a33342ac2c"},
|
||||||
{file = "lxml-5.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:318847c165063549c8fda6b162a0d068689b10deb825cb3859caef69fddaaaff"},
|
{file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:3a74c4f27167cb95c1d4af1c0b59e88b7f3e0182138db2501c353555f7ec57f4"},
|
||||||
{file = "lxml-5.1.1.tar.gz", hash = "sha256:42a8aa957e98bd8b884a8142175ec24ce4ef0a57760e8879f193bfe64b757ca9"},
|
{file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:68a2610dbe138fa8c5826b3f6d98a7cfc29707b850ddcc3e21910a6fe51f6ca0"},
|
||||||
|
{file = "lxml-5.2.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:f0a1bc63a465b6d72569a9bba9f2ef0334c4e03958e043da1920299100bc7c08"},
|
||||||
|
{file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c2d35a1d047efd68027817b32ab1586c1169e60ca02c65d428ae815b593e65d4"},
|
||||||
|
{file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:79bd05260359170f78b181b59ce871673ed01ba048deef4bf49a36ab3e72e80b"},
|
||||||
|
{file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:865bad62df277c04beed9478fe665b9ef63eb28fe026d5dedcb89b537d2e2ea6"},
|
||||||
|
{file = "lxml-5.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:44f6c7caff88d988db017b9b0e4ab04934f11e3e72d478031efc7edcac6c622f"},
|
||||||
|
{file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:71e97313406ccf55d32cc98a533ee05c61e15d11b99215b237346171c179c0b0"},
|
||||||
|
{file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:057cdc6b86ab732cf361f8b4d8af87cf195a1f6dc5b0ff3de2dced242c2015e0"},
|
||||||
|
{file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:f3bbbc998d42f8e561f347e798b85513ba4da324c2b3f9b7969e9c45b10f6169"},
|
||||||
|
{file = "lxml-5.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:491755202eb21a5e350dae00c6d9a17247769c64dcf62d8c788b5c135e179dc4"},
|
||||||
|
{file = "lxml-5.2.1-cp312-cp312-win32.whl", hash = "sha256:8de8f9d6caa7f25b204fc861718815d41cbcf27ee8f028c89c882a0cf4ae4134"},
|
||||||
|
{file = "lxml-5.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:f2a9efc53d5b714b8df2b4b3e992accf8ce5bbdfe544d74d5c6766c9e1146a3a"},
|
||||||
|
{file = "lxml-5.2.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9b0ff53900566bc6325ecde9181d89afadc59c5ffa39bddf084aaedfe3b06a11"},
|
||||||
|
{file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd6037392f2d57793ab98d9e26798f44b8b4da2f2464388588f48ac52c489ea1"},
|
||||||
|
{file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b9c07e7a45bb64e21df4b6aa623cb8ba214dfb47d2027d90eac197329bb5e94"},
|
||||||
|
{file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:3249cc2989d9090eeac5467e50e9ec2d40704fea9ab72f36b034ea34ee65ca98"},
|
||||||
|
{file = "lxml-5.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f42038016852ae51b4088b2862126535cc4fc85802bfe30dea3500fdfaf1864e"},
|
||||||
|
{file = "lxml-5.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:533658f8fbf056b70e434dff7e7aa611bcacb33e01f75de7f821810e48d1bb66"},
|
||||||
|
{file = "lxml-5.2.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:622020d4521e22fb371e15f580d153134bfb68d6a429d1342a25f051ec72df1c"},
|
||||||
|
{file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efa7b51824aa0ee957ccd5a741c73e6851de55f40d807f08069eb4c5a26b2baa"},
|
||||||
|
{file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c6ad0fbf105f6bcc9300c00010a2ffa44ea6f555df1a2ad95c88f5656104817"},
|
||||||
|
{file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e233db59c8f76630c512ab4a4daf5a5986da5c3d5b44b8e9fc742f2a24dbd460"},
|
||||||
|
{file = "lxml-5.2.1-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6a014510830df1475176466b6087fc0c08b47a36714823e58d8b8d7709132a96"},
|
||||||
|
{file = "lxml-5.2.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:d38c8f50ecf57f0463399569aa388b232cf1a2ffb8f0a9a5412d0db57e054860"},
|
||||||
|
{file = "lxml-5.2.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5aea8212fb823e006b995c4dda533edcf98a893d941f173f6c9506126188860d"},
|
||||||
|
{file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff097ae562e637409b429a7ac958a20aab237a0378c42dabaa1e3abf2f896e5f"},
|
||||||
|
{file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f5d65c39f16717a47c36c756af0fb36144069c4718824b7533f803ecdf91138"},
|
||||||
|
{file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:3d0c3dd24bb4605439bf91068598d00c6370684f8de4a67c2992683f6c309d6b"},
|
||||||
|
{file = "lxml-5.2.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e32be23d538753a8adb6c85bd539f5fd3b15cb987404327c569dfc5fd8366e85"},
|
||||||
|
{file = "lxml-5.2.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cc518cea79fd1e2f6c90baafa28906d4309d24f3a63e801d855e7424c5b34144"},
|
||||||
|
{file = "lxml-5.2.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a0af35bd8ebf84888373630f73f24e86bf016642fb8576fba49d3d6b560b7cbc"},
|
||||||
|
{file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8aca2e3a72f37bfc7b14ba96d4056244001ddcc18382bd0daa087fd2e68a354"},
|
||||||
|
{file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ca1e8188b26a819387b29c3895c47a5e618708fe6f787f3b1a471de2c4a94d9"},
|
||||||
|
{file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c8ba129e6d3b0136a0f50345b2cb3db53f6bda5dd8c7f5d83fbccba97fb5dcb5"},
|
||||||
|
{file = "lxml-5.2.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e998e304036198b4f6914e6a1e2b6f925208a20e2042563d9734881150c6c246"},
|
||||||
|
{file = "lxml-5.2.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d3be9b2076112e51b323bdf6d5a7f8a798de55fb8d95fcb64bd179460cdc0704"},
|
||||||
|
{file = "lxml-5.2.1.tar.gz", hash = "sha256:3f7765e69bbce0906a7c74d5fe46d2c7a7596147318dbc08e4a2431f3060e306"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1744,27 +1781,27 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruff"
|
name = "ruff"
|
||||||
version = "0.3.4"
|
version = "0.3.7"
|
||||||
requires_python = ">=3.7"
|
requires_python = ">=3.7"
|
||||||
summary = "An extremely fast Python linter and code formatter, written in Rust."
|
summary = "An extremely fast Python linter and code formatter, written in Rust."
|
||||||
files = [
|
files = [
|
||||||
{file = "ruff-0.3.4-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:60c870a7d46efcbc8385d27ec07fe534ac32f3b251e4fc44b3cbfd9e09609ef4"},
|
{file = "ruff-0.3.7-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0e8377cccb2f07abd25e84fc5b2cbe48eeb0fea9f1719cad7caedb061d70e5ce"},
|
||||||
{file = "ruff-0.3.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6fc14fa742e1d8f24910e1fff0bd5e26d395b0e0e04cc1b15c7c5e5fe5b4af91"},
|
{file = "ruff-0.3.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:15a4d1cc1e64e556fa0d67bfd388fed416b7f3b26d5d1c3e7d192c897e39ba4b"},
|
||||||
{file = "ruff-0.3.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3ee7880f653cc03749a3bfea720cf2a192e4f884925b0cf7eecce82f0ce5854"},
|
{file = "ruff-0.3.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d28bdf3d7dc71dd46929fafeec98ba89b7c3550c3f0978e36389b5631b793663"},
|
||||||
{file = "ruff-0.3.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cf133dd744f2470b347f602452a88e70dadfbe0fcfb5fd46e093d55da65f82f7"},
|
{file = "ruff-0.3.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:379b67d4f49774ba679593b232dcd90d9e10f04d96e3c8ce4a28037ae473f7bb"},
|
||||||
{file = "ruff-0.3.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f3860057590e810c7ffea75669bdc6927bfd91e29b4baa9258fd48b540a4365"},
|
{file = "ruff-0.3.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c060aea8ad5ef21cdfbbe05475ab5104ce7827b639a78dd55383a6e9895b7c51"},
|
||||||
{file = "ruff-0.3.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:986f2377f7cf12efac1f515fc1a5b753c000ed1e0a6de96747cdf2da20a1b369"},
|
{file = "ruff-0.3.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ebf8f615dde968272d70502c083ebf963b6781aacd3079081e03b32adfe4d58a"},
|
||||||
{file = "ruff-0.3.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fd98e85869603e65f554fdc5cddf0712e352fe6e61d29d5a6fe087ec82b76c"},
|
{file = "ruff-0.3.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d48098bd8f5c38897b03604f5428901b65e3c97d40b3952e38637b5404b739a2"},
|
||||||
{file = "ruff-0.3.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64abeed785dad51801b423fa51840b1764b35d6c461ea8caef9cf9e5e5ab34d9"},
|
{file = "ruff-0.3.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da8a4fda219bf9024692b1bc68c9cff4b80507879ada8769dc7e985755d662ea"},
|
||||||
{file = "ruff-0.3.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df52972138318bc7546d92348a1ee58449bc3f9eaf0db278906eb511889c4b50"},
|
{file = "ruff-0.3.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c44e0149f1d8b48c4d5c33d88c677a4aa22fd09b1683d6a7ff55b816b5d074f"},
|
||||||
{file = "ruff-0.3.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:98e98300056445ba2cc27d0b325fd044dc17fcc38e4e4d2c7711585bd0a958ed"},
|
{file = "ruff-0.3.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3050ec0af72b709a62ecc2aca941b9cd479a7bf2b36cc4562f0033d688e44fa1"},
|
||||||
{file = "ruff-0.3.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:519cf6a0ebed244dce1dc8aecd3dc99add7a2ee15bb68cf19588bb5bf58e0488"},
|
{file = "ruff-0.3.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a29cc38e4c1ab00da18a3f6777f8b50099d73326981bb7d182e54a9a21bb4ff7"},
|
||||||
{file = "ruff-0.3.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bb0acfb921030d00070539c038cd24bb1df73a2981e9f55942514af8b17be94e"},
|
{file = "ruff-0.3.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b15cc59c19edca917f51b1956637db47e200b0fc5e6e1878233d3a938384b0b"},
|
||||||
{file = "ruff-0.3.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cf187a7e7098233d0d0c71175375c5162f880126c4c716fa28a8ac418dcf3378"},
|
{file = "ruff-0.3.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e491045781b1e38b72c91247cf4634f040f8d0cb3e6d3d64d38dcf43616650b4"},
|
||||||
{file = "ruff-0.3.4-py3-none-win32.whl", hash = "sha256:af27ac187c0a331e8ef91d84bf1c3c6a5dea97e912a7560ac0cef25c526a4102"},
|
{file = "ruff-0.3.7-py3-none-win32.whl", hash = "sha256:bc931de87593d64fad3a22e201e55ad76271f1d5bfc44e1a1887edd0903c7d9f"},
|
||||||
{file = "ruff-0.3.4-py3-none-win_amd64.whl", hash = "sha256:de0d5069b165e5a32b3c6ffbb81c350b1e3d3483347196ffdf86dc0ef9e37dd6"},
|
{file = "ruff-0.3.7-py3-none-win_amd64.whl", hash = "sha256:5ef0e501e1e39f35e03c2acb1d1238c595b8bb36cf7a170e7c1df1b73da00e74"},
|
||||||
{file = "ruff-0.3.4-py3-none-win_arm64.whl", hash = "sha256:6810563cc08ad0096b57c717bd78aeac888a1bfd38654d9113cb3dc4d3f74232"},
|
{file = "ruff-0.3.7-py3-none-win_arm64.whl", hash = "sha256:789e144f6dc7019d1f92a812891c645274ed08af6037d11fc65fcbc183b7d59f"},
|
||||||
{file = "ruff-0.3.4.tar.gz", hash = "sha256:f0f4484c6541a99862b693e13a151435a279b271cff20e37101116a21e2a1ad1"},
|
{file = "ruff-0.3.7.tar.gz", hash = "sha256:d5c1aebee5162c2226784800ae031f660c350e7a3402c4d1f8ea4e97e232e3ba"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1779,12 +1816,12 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "setuptools"
|
name = "setuptools"
|
||||||
version = "69.2.0"
|
version = "69.5.1"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Easily download, build, install, upgrade, and uninstall Python packages"
|
summary = "Easily download, build, install, upgrade, and uninstall Python packages"
|
||||||
files = [
|
files = [
|
||||||
{file = "setuptools-69.2.0-py3-none-any.whl", hash = "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c"},
|
{file = "setuptools-69.5.1-py3-none-any.whl", hash = "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32"},
|
||||||
{file = "setuptools-69.2.0.tar.gz", hash = "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e"},
|
{file = "setuptools-69.5.1.tar.gz", hash = "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1852,28 +1889,28 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tablib"
|
name = "tablib"
|
||||||
version = "3.6.0"
|
version = "3.6.1"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Format agnostic tabular data library (XLS, JSON, YAML, CSV, etc.)"
|
summary = "Format agnostic tabular data library (XLS, JSON, YAML, CSV, etc.)"
|
||||||
files = [
|
files = [
|
||||||
{file = "tablib-3.6.0-py3-none-any.whl", hash = "sha256:c403ed093d438b6162236efb106463d76c37a66283565b8c5c4631010c7e8b6d"},
|
{file = "tablib-3.6.1-py3-none-any.whl", hash = "sha256:c771d38ed1d74350a69873db43e0afb7f1cca0ed2915a7243094463eb6789207"},
|
||||||
{file = "tablib-3.6.0.tar.gz", hash = "sha256:414cb1922ae14af267ddd93163687dac6db74220360c5e0bd91f9a4479a9a649"},
|
{file = "tablib-3.6.1.tar.gz", hash = "sha256:040685fde11e9237675f43e985edb94b63250a5e9236f89d561ce6fb1465b839"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tablib"
|
name = "tablib"
|
||||||
version = "3.6.0"
|
version = "3.6.1"
|
||||||
extras = ["ods", "xlsx"]
|
extras = ["ods", "xlsx"]
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Format agnostic tabular data library (XLS, JSON, YAML, CSV, etc.)"
|
summary = "Format agnostic tabular data library (XLS, JSON, YAML, CSV, etc.)"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"odfpy",
|
"odfpy",
|
||||||
"openpyxl>=2.6.0",
|
"openpyxl>=2.6.0",
|
||||||
"tablib==3.6.0",
|
"tablib==3.6.1",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "tablib-3.6.0-py3-none-any.whl", hash = "sha256:c403ed093d438b6162236efb106463d76c37a66283565b8c5c4631010c7e8b6d"},
|
{file = "tablib-3.6.1-py3-none-any.whl", hash = "sha256:c771d38ed1d74350a69873db43e0afb7f1cca0ed2915a7243094463eb6789207"},
|
||||||
{file = "tablib-3.6.0.tar.gz", hash = "sha256:414cb1922ae14af267ddd93163687dac6db74220360c5e0bd91f9a4479a9a649"},
|
{file = "tablib-3.6.1.tar.gz", hash = "sha256:040685fde11e9237675f43e985edb94b63250a5e9236f89d561ce6fb1465b839"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1924,15 +1961,15 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "types-bleach"
|
name = "types-bleach"
|
||||||
version = "6.1.0.20240311"
|
version = "6.1.0.20240331"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Typing stubs for bleach"
|
summary = "Typing stubs for bleach"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"types-html5lib",
|
"types-html5lib",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "types-bleach-6.1.0.20240311.tar.gz", hash = "sha256:1e65b16ab56d61c1d963f53a8dc44e9de50c6c44e3e267e2d3ae76fa41484c8e"},
|
{file = "types-bleach-6.1.0.20240331.tar.gz", hash = "sha256:2ee858a84fb06fc2225ff56ba2f7f6c88b65638659efae0d7bfd6b24a1b5a524"},
|
||||||
{file = "types_bleach-6.1.0.20240311-py3-none-any.whl", hash = "sha256:bd2bc2d57b677c44d0439f3cfdb98759f61200477fa1b602f6dc668e71f0ab7c"},
|
{file = "types_bleach-6.1.0.20240331-py3-none-any.whl", hash = "sha256:399bc59bfd20a36a56595f13f805e56c8a08e5a5c07903e5cf6fafb5a5107dd4"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1965,15 +2002,15 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "types-requests"
|
name = "types-requests"
|
||||||
version = "2.31.0.20240311"
|
version = "2.31.0.20240406"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Typing stubs for requests"
|
summary = "Typing stubs for requests"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"urllib3>=2",
|
"urllib3>=2",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "types-requests-2.31.0.20240311.tar.gz", hash = "sha256:b1c1b66abfb7fa79aae09097a811c4aa97130eb8831c60e47aee4ca344731ca5"},
|
{file = "types-requests-2.31.0.20240406.tar.gz", hash = "sha256:4428df33c5503945c74b3f42e82b181e86ec7b724620419a2966e2de604ce1a1"},
|
||||||
{file = "types_requests-2.31.0.20240311-py3-none-any.whl", hash = "sha256:47872893d65a38e282ee9f277a4ee50d1b28bd592040df7d1fdaffdf3779937d"},
|
{file = "types_requests-2.31.0.20240406-py3-none-any.whl", hash = "sha256:6216cdac377c6b9a040ac1c0404f7284bd13199c0e1bb235f4324627e8898cf5"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -8,7 +8,7 @@ authors = [
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"django~=5.0",
|
"django~=5.0",
|
||||||
"django-admin-logs~=1.2",
|
"django-admin-logs~=1.2",
|
||||||
"django-auth-ldap~=4.7",
|
"django-auth-ldap~=4.8",
|
||||||
"django-markdownx~=4.0",
|
"django-markdownx~=4.0",
|
||||||
"django-recurrence~=1.11",
|
"django-recurrence~=1.11",
|
||||||
"django-widget-tweaks~=1.5",
|
"django-widget-tweaks~=1.5",
|
||||||
@ -23,7 +23,7 @@ dependencies = [
|
|||||||
"semver~=3.0",
|
"semver~=3.0",
|
||||||
"djangorestframework~=3.15",
|
"djangorestframework~=3.15",
|
||||||
"django-q2~=1.6",
|
"django-q2~=1.6",
|
||||||
"lxml~=5.1",
|
"lxml~=5.2",
|
||||||
"django-object-actions~=4.2",
|
"django-object-actions~=4.2",
|
||||||
"bitstring~=4.1",
|
"bitstring~=4.1",
|
||||||
"udm-rest-client~=1.2",
|
"udm-rest-client~=1.2",
|
||||||
@ -37,14 +37,14 @@ dependencies = [
|
|||||||
"django-mysql~=4.12",
|
"django-mysql~=4.12",
|
||||||
"django-weasyprint~=2.3",
|
"django-weasyprint~=2.3",
|
||||||
"django-sendfile2~=0.7",
|
"django-sendfile2~=0.7",
|
||||||
"django-bootstrap5~=23.4",
|
"django-bootstrap5~=24.1",
|
||||||
]
|
]
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
server = [
|
server = [
|
||||||
"uvicorn[standard]~=0.29",
|
"uvicorn[standard]~=0.29",
|
||||||
"setuptools~=69.2",
|
"setuptools~=69.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.entry-points."djangoq.errorreporters"]
|
[project.entry-points."djangoq.errorreporters"]
|
||||||
@ -116,7 +116,7 @@ lint = [
|
|||||||
typing = [
|
typing = [
|
||||||
"mypy~=1.7",
|
"mypy~=1.7",
|
||||||
"django-stubs~=4.2",
|
"django-stubs~=4.2",
|
||||||
"setuptools~=69.2",
|
"setuptools~=69.5",
|
||||||
"types-bleach~=6.1",
|
"types-bleach~=6.1",
|
||||||
"types-requests~=2.31",
|
"types-requests~=2.31",
|
||||||
"types-urllib3~=1.26",
|
"types-urllib3~=1.26",
|
||||||
@ -128,8 +128,8 @@ debug = [
|
|||||||
]
|
]
|
||||||
dev = [
|
dev = [
|
||||||
"django-extensions~=3.2",
|
"django-extensions~=3.2",
|
||||||
"ipython~=8.22",
|
"ipython~=8.23",
|
||||||
"hypothesis[django]~=6.99",
|
"hypothesis[django]~=6.100",
|
||||||
"tblib~=3.0",
|
"tblib~=3.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user