export const CLIENT_APPROVED_OR_BETTER = new Set(['client_approved', 'invoiced', 'paid']); export function isCompletedVersionEligible(task, versionNumber) { const taskVersion = Number(task?.current_version || 0); const version = Number(versionNumber || 0); if (version < taskVersion) return true; return version === taskVersion && CLIENT_APPROVED_OR_BETTER.has(task?.status); } export function isInitialVersionEligible(task) { if (!task || task.invoiced) return false; return isCompletedVersionEligible(task, 0); } 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; } // Parses version number from a subcontractor invoice item description like // "Project • Task – R01". Legacy fallback only — new rows store version_number directly. export function parseVersionFromItemDescription(description = '') { const match = String(description).match(/[–\-]\s*R(\d{2})\b/i); return match ? Number(match[1]) : 0; }