From aff3d98929e5c8a7f06e1a76ee8af0356352d274 Mon Sep 17 00:00:00 2001 From: Krao Hasanee Date: Thu, 11 Jun 2026 23:09:53 -0400 Subject: [PATCH] fix: fourge_error revisions always bill $0 to client Fourge's own error revisions should never be charged to the client. getRevisionChargeQuantity now returns 0 for revision_type=fourge_error regardless of version number. Applied at all 4 invoice picker call sites. Co-Authored-By: Claude Opus 4.8 --- .claude/settings.local.json | 3 ++- src/lib/invoiceVersionRules.js | 4 +++- src/pages/team/TeamCreateInvoice.jsx | 4 ++-- src/pages/team/TeamInvoices.jsx | 4 ++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 8ddeafe..328aa5f 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -33,7 +33,8 @@ "mcp__plugin_supabase_supabase__list_projects", "Bash(grep -rni \"task_number\\\\|task #\\\\|task#\\\\|#\\\\${\\\\|taskNumber\\\\|seq\" src/pages/Tasks.jsx src/pages/TaskDetail.jsx src/pages/ProjectDetail.jsx)", "mcp__plugin_supabase_supabase__apply_migration", - "Bash(git commit -q -m 'fix: invoice picker skips review-shadow rows for service_type/pricing *)" + "Bash(git commit -q -m 'fix: invoice picker skips review-shadow rows for service_type/pricing *)", + "Bash(git commit -q -m 'fix: fourge_error revisions always bill $0 to client *)" ] } } diff --git a/src/lib/invoiceVersionRules.js b/src/lib/invoiceVersionRules.js index fbbc7a5..881f029 100644 --- a/src/lib/invoiceVersionRules.js +++ b/src/lib/invoiceVersionRules.js @@ -12,7 +12,9 @@ export function isInitialVersionEligible(task) { return isCompletedVersionEligible(task, 0); } -export function getRevisionChargeQuantity(versionNumber) { +export function getRevisionChargeQuantity(versionNumber, revisionType) { + // Fourge's own error revisions are never billed to the client. + if (revisionType === 'fourge_error') return 0; const version = Number(versionNumber || 0); return version >= 2 ? 1 : 0; } diff --git a/src/pages/team/TeamCreateInvoice.jsx b/src/pages/team/TeamCreateInvoice.jsx index 328b117..108f80e 100644 --- a/src/pages/team/TeamCreateInvoice.jsx +++ b/src/pages/team/TeamCreateInvoice.jsx @@ -146,7 +146,7 @@ export default function CreateInvoice() { const serviceLabel = getRevisionServiceType(revision); const description = buildRevisionItemDescription(revision); const price = priceList.find(p => p.service_type === serviceLabel && p.price_type === 'revision'); - const revisionChargeQty = getRevisionChargeQuantity(revision?.version_number); + const revisionChargeQty = getRevisionChargeQuantity(revision?.version_number, revision?.revision_type); const quantity = revisionChargeQty > 0 ? revisionChargeQty : 1; const unitPrice = revisionChargeQty > 0 ? (price?.price || '') : 0; setItems(prev => { @@ -436,7 +436,7 @@ export default function CreateInvoice() { {uninvoicedRevisions.map(rev => { const revServiceType = getRevisionServiceType(rev); const price = priceList.find(p => p.service_type === revServiceType && p.price_type === 'revision'); - const revisionChargeQty = getRevisionChargeQuantity(rev?.version_number); + const revisionChargeQty = getRevisionChargeQuantity(rev?.version_number, rev?.revision_type); const alreadyAdded = items.some(i => i.submission_id === rev.id); return (
diff --git a/src/pages/team/TeamInvoices.jsx b/src/pages/team/TeamInvoices.jsx index 3ca7b23..ae44206 100644 --- a/src/pages/team/TeamInvoices.jsx +++ b/src/pages/team/TeamInvoices.jsx @@ -376,7 +376,7 @@ export default function Invoices() { const invAddRevision = (rev) => { const svcType = pickInitialServiceType(rev.task?.submissions, rev.service_type || rev.task?.title || 'Revision'); const price = invPriceList.find(p => p.service_type === svcType && p.price_type === 'revision'); - const revisionChargeQty = getRevisionChargeQuantity(rev?.version_number); + const revisionChargeQty = getRevisionChargeQuantity(rev?.version_number, rev?.revision_type); const qty = revisionChargeQty > 0 ? revisionChargeQty : 1; const unitPrice = revisionChargeQty > 0 ? (price?.price || '') : 0; const desc = invBuildRevisionItemDescription(rev); @@ -2017,7 +2017,7 @@ export default function Invoices() {
{invUnbilledRevisions.map(r => { const added = invItems.some(i => i.submission_id === r.id); - const revisionQty = getRevisionChargeQuantity(r?.version_number); + const revisionQty = getRevisionChargeQuantity(r?.version_number, r?.revision_type); const revisionServiceType = pickInitialServiceType(r.task?.submissions, r.service_type || r.task?.title || 'Revision'); const revisionPrice = invPriceList.find(p => p.service_type === revisionServiceType && p.price_type === 'revision'); const revisionLabel = revisionQty > 0 ? (revisionPrice ? `$${Number(revisionPrice.price).toFixed(2)}` : 'No price') : 'Free';