Add bulk calendar invitation delivery

This commit is contained in:
2026-08-02 16:38:48 +02:00
parent 7733265cc8
commit bf6e07f307
17 changed files with 1356 additions and 20 deletions
@@ -14,6 +14,7 @@ from govoplan_campaign.backend.schemas import (
CampaignCreateMinimalRequest,
CampaignAddressLookupCandidate,
CampaignAddressLookupResponse,
CampaignCalendarCatalogResponse,
CampaignPostboxCatalogResponse,
CampaignRecipientAddressSource,
CampaignRecipientAddressSourcesResponse,
@@ -63,6 +64,7 @@ from govoplan_campaign.backend.campaign.postbox_targets import (
delivery_catalog_payload,
)
from govoplan_campaign.backend.integrations import (
calendar_integration,
PostboxDeliveryUnavailable,
postbox_integration,
templates_integration,
@@ -756,6 +758,55 @@ def campaign_postbox_catalog(
)
@router.get(
"/{campaign_id}/calendar-invitation-catalog",
response_model=CampaignCalendarCatalogResponse,
)
def campaign_calendar_invitation_catalog(
campaign_id: str,
session: Session = Depends(get_session),
principal: ApiPrincipal = Depends(require_scope("campaigns:campaign:update")),
):
_get_campaign_for_principal(session, campaign_id, principal, write=True)
integration = calendar_integration()
if not integration.available:
return CampaignCalendarCatalogResponse(
reason="The Calendar invitation capability is not active."
)
if not any(
principal.has(scope)
for scope in (
"calendar:calendar:read",
"calendar:calendar:write",
"calendar:calendar:admin",
)
):
return CampaignCalendarCatalogResponse(
reason="You are not permitted to select a Calendar collection."
)
calendars = integration.list_calendars(
session,
tenant_id=principal.tenant_id,
user_id=str(getattr(principal.user, "id", "")) or None,
group_ids=tuple(principal.group_ids),
can_admin=principal.has("calendar:calendar:admin"),
)
return CampaignCalendarCatalogResponse(
available=True,
calendars=[
{
"id": item.id,
"name": item.name,
"color": item.color,
"timezone": item.timezone,
"source_kind": item.source_kind,
"writable": item.writable,
}
for item in calendars
],
)
@router.get("/{campaign_id}/print-templates")
def campaign_print_templates(
campaign_id: str,
+8 -1
View File
@@ -46,6 +46,7 @@ from govoplan_campaign.backend.services.job_queries import (
_campaign_jobs_page_response,
_campaign_jobs_query_context,
_job_attempts_payload,
_calendar_invitations_for_jobs,
_job_detail_payload,
_job_diagnostics_payload,
)
@@ -422,7 +423,13 @@ def get_job_detail(
else []
)
return CampaignJobDetailResponse(
job=_job_detail_payload(job),
job=_job_detail_payload(
job,
calendar_invitation=_calendar_invitations_for_jobs(
session,
[job],
).get(job.id),
),
attempts=_job_attempts_payload(
send_attempts,
imap_attempts,