/** * E-Invoice (IRP/NIC/PWC) Error Code Mapping * Maps technical error codes from IRP/PWC API to user-friendly messages * * Sources: NIC IRP Portal, ClearTax, GST Portal documentation */ interface EInvoiceErrorInfo { /** User-friendly message shown in the UI toast */ userMessage: string; /** Suggested action for the user */ action?: string; } /** * Comprehensive mapping of IRP/NIC/PWC error codes to user-friendly messages * Error codes come from the IRP (Invoice Registration Portal) managed by NIC */ const ERROR_CODE_MAP: Record = { // ── Duplicate / Already Exists ── '2150': { userMessage: 'This invoice has already been registered. An IRN was previously generated for this invoice.', action: 'No action needed — the existing IRN will be used.', }, '2295': { userMessage: 'This invoice was already submitted to another IRP portal.', action: 'Ensure invoices are not submitted to multiple IRP portals simultaneously.', }, 'DUPIRN': { userMessage: 'Duplicate IRN detected — this invoice was already registered.', action: 'The existing IRN will be used automatically.', }, // ── GSTIN Errors ── '2117': { userMessage: 'The supplier GSTIN is invalid or not active on the GST portal.', action: 'Please verify the dealer GSTIN is correct and active.', }, '2118': { userMessage: 'The buyer GSTIN is invalid or not active on the GST portal.', action: 'Please verify the buyer GSTIN is correct and active.', }, '2148': { userMessage: 'The GSTIN provided is not registered for e-invoicing.', action: 'Ensure the GSTIN is registered and eligible for e-invoice generation.', }, '2163': { userMessage: 'Invalid supplier GSTIN format.', action: 'Please check the dealer GSTIN — it should be a valid 15-character GSTIN.', }, '2164': { userMessage: 'Invalid buyer GSTIN format.', action: 'Please verify the buyer GSTIN format.', }, '2166': { userMessage: 'The supplier GSTIN is not found in the e-invoice master database.', action: 'The dealer GSTIN needs to be registered in the e-invoice system. Please contact support.', }, '701': { userMessage: 'The supplier GSTIN is not registered in the e-invoice master.', action: 'Please ensure the GSTIN is registered and synced with the e-invoice portal.', }, // ── Supplier/Buyer Issues ── '2160': { userMessage: 'The supplier and buyer GSTIN cannot be the same.', action: 'Ensure the dealer GSTIN and Royal Enfield GSTIN are different.', }, '2165': { userMessage: 'Buyer GSTIN cannot be "URP" (Unregistered Person) for B2B supply type.', action: 'Please provide a valid GSTIN for the buyer.', }, // ── State Code / Location ── '2161': { userMessage: 'The state code in the GSTIN does not match the state code in the address.', action: 'Verify that the dealer state code matches the first 2 digits of their GSTIN.', }, '2167': { userMessage: 'Invalid PIN code provided for the supplier or buyer.', action: 'Please check the PIN code in the dealer address details.', }, '2168': { userMessage: 'The PIN code does not match the state code.', action: 'Ensure the PIN code belongs to the correct state as per the GSTIN.', }, // ── Tax Calculation Errors ── '2172': { userMessage: 'IGST amount cannot be applied for intra-state (same state) transactions.', action: 'For same-state transactions, use CGST + SGST instead of IGST.', }, '2173': { userMessage: 'CGST/SGST amounts are not applicable for inter-state transactions.', action: 'For different-state transactions, use IGST instead of CGST + SGST.', }, '2174': { userMessage: 'Invalid CGST or SGST amount — they must be equal.', action: 'Please ensure CGST and SGST amounts are exactly equal (half of the total GST each).', }, '2175': { userMessage: 'Invalid IGST amount for the given item.', action: 'Verify the IGST amount = Taxable Value × GST Rate.', }, // ── HSN / Item Errors ── '2176': { userMessage: 'Invalid HSN code provided for one or more items.', action: 'Please verify the HSN/SAC code from the official GST HSN list.', }, '2178': { userMessage: 'Invalid GST rate for the given HSN code.', action: 'Please ensure the correct GST rate is applied for the HSN/SAC code.', }, '2179': { userMessage: 'Duplicate item serial numbers found in the invoice.', action: 'Each line item must have a unique serial number.', }, // ── Value Mismatch ── '2182': { userMessage: 'Total taxable value does not match the sum of individual line items.', action: 'Please check that the total taxable value equals the sum of all item amounts.', }, '2189': { userMessage: 'Total invoice value does not match the sum of item values.', action: 'Ensure total invoice value = taxable value + all taxes + cess + other charges.', }, '2188': { userMessage: 'Invalid total item value — must equal assessable value + taxes.', action: 'Recalculate the item total to include base amount and all applicable taxes.', }, // ── Document Errors ── '2153': { userMessage: 'Invalid invoice number format.', action: 'Invoice number should contain only alphanumeric characters, hyphens, and slashes.', }, '2155': { userMessage: 'Invoice date is invalid or in the future.', action: 'Please provide a valid invoice date that is not in the future.', }, '2157': { userMessage: 'The invoice date is older than the allowed limit.', action: 'E-invoices can only be generated for recent invoices as per GST guidelines.', }, // ── Authentication ── '1005': { userMessage: 'Authentication with the e-invoice portal failed.', action: 'Please try again. If the issue persists, contact the system administrator.', }, '1004': { userMessage: 'E-invoice portal session expired.', action: 'Please try again — a new session will be created automatically.', }, // ── System / Network ── '404': { userMessage: 'The e-invoice service is temporarily unavailable.', action: 'Please try again after a few minutes.', }, '500': { userMessage: 'The e-invoice portal encountered an internal error.', action: 'Please try again. If the issue persists, contact support.', }, '503': { userMessage: 'The e-invoice portal is currently under maintenance.', action: 'Please try again after some time.', }, }; /** * Common keywords in PWC validation remarks → user-friendly messages */ const KEYWORD_MAP: Array<{ pattern: RegExp; userMessage: string; action?: string }> = [ { pattern: /gstin.*not\s*(found|registered|valid|present)/i, userMessage: 'The dealer GSTIN is not registered in the e-invoice system.', action: 'Please verify the dealer GSTIN or contact support to register it.', }, { pattern: /duplicate\s*irn/i, userMessage: 'This invoice was already registered and an IRN exists.', action: 'The existing IRN will be used.', }, { pattern: /hsn.*invalid|invalid.*hsn/i, userMessage: 'The HSN/SAC code provided is not valid.', action: 'Please check the HSN code from the GST portal.', }, { pattern: /pin\s*code.*invalid|invalid.*pin/i, userMessage: 'The PIN code in the address is invalid.', action: 'Please update the dealer address with a valid PIN code.', }, { pattern: /tax.*mismatch|mismatch.*tax|amount.*mismatch/i, userMessage: 'Tax amount does not match the expected calculation.', action: 'Please verify that the tax amounts are correctly calculated based on the taxable value and GST rate.', }, { pattern: /igst.*intra|intra.*igst/i, userMessage: 'IGST cannot be applied for same-state (intra-state) transactions.', action: 'Use CGST + SGST for same-state transactions.', }, { pattern: /supplier.*buyer.*same|same.*gstin/i, userMessage: 'Supplier and buyer GSTIN cannot be the same.', action: 'Ensure the dealer and buyer GSTINs are different.', }, { pattern: /authentication|auth.*fail|token.*invalid|unauthorized/i, userMessage: 'E-invoice portal authentication failed.', action: 'Please try again. If the issue persists, contact the administrator.', }, { pattern: /timeout|timed?\s*out|connection.*refused/i, userMessage: 'Could not connect to the e-invoice portal.', action: 'Please check your internet connection and try again.', }, { pattern: /invoice.*date.*future|future.*date/i, userMessage: 'Invoice date cannot be in the future.', action: 'Please set the invoice date to today or a past date.', }, { pattern: /request.*not\s*found|not\s*found/i, userMessage: 'The claim request was not found.', action: 'Please refresh the page and try again.', }, { pattern: /dealer.*activity.*missing|missing.*dealer/i, userMessage: 'Dealer or activity details are missing for this request.', action: 'Please ensure the dealer and activity information is complete before generating the invoice.', }, { pattern: /claim\s*details?\s*not\s*found/i, userMessage: 'Claim details not found for this request.', action: 'Please ensure the claim proposal has been submitted.', }, { pattern: /cannot\s*generate.*currently\s*at\s*step/i, userMessage: 'Cannot generate the invoice at this stage.', action: 'Please complete all previous approval steps before generating the e-invoice.', }, ]; /** * Translate a raw PWC/IRP error message into a user-friendly message * * @param rawError The raw error string from PWC/IRP response * @returns User-friendly error message suitable for toast display */ export function translateEInvoiceError(rawError: string): string { if (!rawError) return 'E-Invoice generation failed. Please try again.'; // 1. Try exact error code match // Extract error codes like "2150", "701" from messages like "2150: Duplicate IRN" const codeMatch = rawError.match(/\b(\d{3,4})\b/); if (codeMatch) { const code = codeMatch[1]; const mapped = ERROR_CODE_MAP[code]; if (mapped) { return mapped.action ? `${mapped.userMessage} ${mapped.action}` : mapped.userMessage; } } // Also check for named codes like "DUPIRN" const namedCodeMatch = rawError.match(/\b(DUPIRN)\b/i); if (namedCodeMatch) { const mapped = ERROR_CODE_MAP[namedCodeMatch[1].toUpperCase()]; if (mapped) { return mapped.action ? `${mapped.userMessage} ${mapped.action}` : mapped.userMessage; } } // 2. Try keyword-based matching for (const entry of KEYWORD_MAP) { if (entry.pattern.test(rawError)) { return entry.action ? `${entry.userMessage} ${entry.action}` : entry.userMessage; } } // 3. Fallback: clean up the raw message for display // Remove internal prefixes like "[PWC]", "Failed to generate signed e-invoice via PWC:" let cleaned = rawError .replace(/\[PWC\]\s*/gi, '') .replace(/\[PWCIntegration\]\s*/gi, '') .replace(/Failed to generate signed e-invoice via PWC:\s*/gi, '') .replace(/E-Invoice generation failed:\s*/gi, '') .trim(); // If the cleaned message is still very technical, provide a generic one if (cleaned.length > 200 || /stack\s*trace|at\s+\w+\.\w+\s*\(/i.test(cleaned)) { return 'E-Invoice generation failed due to a validation error. Please verify the claim details (dealer GSTIN, amounts, HSN codes) and try again.'; } return cleaned || 'E-Invoice generation failed. Please try again.'; }