From a8b9e1d532a83af6bcd480806f47e3dd814a0718 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Thu, 21 May 2026 01:27:55 +0000 Subject: [PATCH] fix: allow deleting organization with failed invoices The cloud backend (already merged) now cancels pending/failed invoices on organization delete instead of throwing BILLING_INVOICE_PENDING. The console was still gating the delete modal via the unpaid-invoices branch of the delete-estimation endpoint, which rendered an alternate view without the org-name confirmation input and left the Delete button permanently disabled. Drop the estimation-based gate (and the now-unused estimation fetch, component, and import) so the confirm-name form always renders. The backend will cancel any failed invoices server-side as part of the delete. The informational upcoming-invoice Alert is preserved. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../deleteOrganizationEstimation.svelte | 18 --- .../settings/deleteOrganizationModal.svelte | 112 +++++++----------- 2 files changed, 44 insertions(+), 86 deletions(-) delete mode 100644 src/routes/(console)/organization-[organization]/settings/deleteOrganizationEstimation.svelte diff --git a/src/routes/(console)/organization-[organization]/settings/deleteOrganizationEstimation.svelte b/src/routes/(console)/organization-[organization]/settings/deleteOrganizationEstimation.svelte deleted file mode 100644 index 14ae7d8bcb..0000000000 --- a/src/routes/(console)/organization-[organization]/settings/deleteOrganizationEstimation.svelte +++ /dev/null @@ -1,18 +0,0 @@ - - -{#if estimation} - {#if estimation.unpaidInvoices?.length > 0} - - This organization has unresolved invoices that must be settled before it can be deleted. - Please review and resolve these invoices to proceed. - - - - {/if} -{/if} diff --git a/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte b/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte index 51a1d483aa..6962fb8d3a 100644 --- a/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte +++ b/src/routes/(console)/organization-[organization]/settings/deleteOrganizationModal.svelte @@ -14,7 +14,6 @@ import { formatCurrency } from '$lib/helpers/numbers'; import { billingIdToPlan } from '$lib/stores/billing'; import { Table, Tabs, Alert } from '@appwrite.io/pink-svelte'; - import DeleteOrganizationEstimation from './deleteOrganizationEstimation.svelte'; import type { Models } from '@appwrite.io/console'; export let showDelete = false; @@ -23,7 +22,6 @@ let error: string = null; let selectedTab = 'projects'; let organizationName: string = null; - let estimation: Models.EstimationDeleteOrganization; async function deleteOrg() { try { @@ -76,21 +74,6 @@ $: if (!showDelete) { // reset on close. organizationName = ''; - } else { - getEstimate(); - } - - async function getEstimate() { - if (isCloud) { - try { - error = ''; - estimation = await sdk.forConsole.organizations.estimationDeleteOrganization({ - organizationId: $organization.$id - }); - } catch (e) { - error = e.message; - } - } } @@ -114,60 +97,53 @@ This action is irreversible. {/if}

- - {#if estimation && (estimation.unpaidInvoices.length > 0 || estimation.unpaidInvoices.some((invoice) => invoice.grossAmount > 0))} - - {:else} - {#if $projects.total > 0} - - {#each tabs as { name, label, total }} - (selectedTab = name)} - active={selectedTab === name}> - {label.desktop} ({total}) - + {#if $projects.total > 0} + + {#each tabs as { name, label, total }} + (selectedTab = name)} + active={selectedTab === name}> + {label.desktop} ({total}) + + {/each} + + {#if selectedTab === 'projects'} + + + Projects + Last updated + + {#each $projects.projects as project} + + {project.name} + {toLocaleDate(project.$updatedAt)} + + {/each} + + {:else} + + + Members + Last updated + + {#each $members.memberships as membership} + + {membership.userName} + {toLocaleDate(membership.$updatedAt)} + {/each} - - {#if selectedTab === 'projects'} - - - Projects - Last updated - - {#each $projects.projects as project} - - {project.name} - {toLocaleDate(project.$updatedAt)} - - {/each} - - {:else} - - - Members - Last updated - - {#each $members.memberships as membership} - - {membership.userName} - {toLocaleDate(membership.$updatedAt)} - - {/each} - - {/if} + {/if} - {/if} +