Indian GST tax configuration, computation, and compliance engine for procurement transactions -- covering tax rates, grouping, exemptions, TDS, HSN/SAC mapping, and reverse charge mechanism.
The Tax Configuration module manages Indian GST tax configuration, computation, and compliance for all procurement transactions within ProKure. It handles automatic tax determination based on HSN/SAC codes, inter-state vs intra-state classification via GSTIN analysis, TDS deduction rules, exemption certificate management, and reverse charge mechanism applicability.
Master table of all tax rates including GST components, cess, and TDS sections. tax_type: GST | CGST | SGST | IGST | CESS | TDS. Rate is DECIMAL(5,2). Uses effective_from / effective_until for date-range versioning.
Logical groupings of individual tax rates applied together (e.g. CGST 9% + SGST 9% = GST 18% intra-state). tax_ids is a UUID[] array referencing config.tax_rates. is_inter_state flags inter-state (IGST) vs intra-state (CGST+SGST).
Exemption certificates for entities qualifying for zero-rated or reduced-rate taxation. exemption_type: SEZ | GOVERNMENT | DIPLOMATIC | MSME | EXPORT. entity_type: VENDOR | CUSTOMER | PRODUCT. exempted_taxes is JSONB. status: ACTIVE | EXPIRED | REVOKED.
Under the Indian GST regime, the applicable tax type depends on whether the transaction is intra-state or inter-state. This is determined by comparing the state codes embedded in the supplier GSTIN and buyer GSTIN (first two digits).
| Scenario | Condition | Applicable Tax | Example |
|---|---|---|---|
| Intra-State | Supplier state code = Buyer state code | CGST + SGST (split equally) | 27AAACR5055K1Z5 to 27BBBCR1234K1Z8 (both MH = 27) |
| Inter-State | Supplier state code != Buyer state code | IGST (full rate) | 29AAACR5055K1Z5 (KA) to 27BBBCR1234K1Z8 (MH) |
[Transaction Initiated]
|
v
+-------------------------------+
| Extract state codes from |
| supplier_gstin (first 2 dig) |
| buyer_gstin (first 2 dig) |
+-------------------------------+
|
v
+-------------------------------+
| supplier_state = buyer_state? |
+-------+--------------+-------+
| |
YES NO
| |
v v
+-----------+ +-----------+
|INTRA-STATE| |INTER-STATE|
| CGST = R/2| | IGST = R |
| SGST = R/2| | |
+-----------+ +-----------+
| |
v v
+-------------------------------+
| Apply Cess if applicable |
| (lookup by HSN code) |
+-------------------------------+
|
v
[Tax amounts computed]
Every product or service is mapped to an HSN code (goods, 4-8 digits) or SAC code (services, 6 digits starting with 99). The system uses this code to automatically determine the applicable tax rate.
-- Auto-determine tax rate from product HSN code SELECT tr.tax_code, tr.tax_name, tr.tax_type, tr.rate FROM config.tax_rates tr WHERE tr.hsn_sac_code = product.hsn_code AND tr.is_active = TRUE AND tr.effective_from <= CURRENT_DATE AND (tr.effective_until IS NULL OR tr.effective_until >= CURRENT_DATE) ORDER BY tr.effective_from DESC LIMIT 1; -- Service SAC code lookup (same pattern) SELECT tr.tax_code, tr.rate FROM config.tax_rates tr WHERE tr.hsn_sac_code = service.sac_code AND tr.is_active = TRUE AND tr.effective_from <= invoice_date AND (tr.effective_until IS NULL OR tr.effective_until >= invoice_date);
Tax Deducted at Source (TDS) is deducted from vendor payments based on transaction nature and vendor type. ProKure auto-computes TDS using columns on logistics.vendor_invoices (tds_section, tds_rate, tds_certificate_number).
| TDS Section | Nature of Payment | Rate (Ind / Co) | Threshold |
|---|---|---|---|
| 194C | Contractors / Sub-contractors | 1% / 2% | Single: 30K / Aggregate: 1L p.a. |
| 194J | Professional / Technical fees | 10% / 10% | 30,000 p.a. |
| 194Q | Purchase of goods | 0.1% / 0.1% | 50,00,000 p.a. |
-- TDS computation logic tds_amount = invoice_amount * tds_rate / 100 -- Lower deduction certificate handling IF vendor.has_lower_tds_certificate = TRUE AND certificate.valid_until >= CURRENT_DATE THEN effective_tds_rate = certificate.reduced_rate ELSE effective_tds_rate = standard_tds_rate_for_section END IF -- Net payable to vendor net_payable = invoice_amount - tds_amount
Compare supplier GSTIN state code (first 2 digits) with buyer GSTIN to classify as intra-state or inter-state.
Look up HSN/SAC code in config.tax_rates; select appropriate tax group (CGST+SGST or IGST) from config.tax_groups.
Query config.tax_exemptions for the vendor/product. If valid and active, apply zero-rate or reduced rate.
tax_amount = taxable_amount * rate / 100 per component. Sum all line-item taxes by component. Round to 2 decimal places per GST guidelines; add round-off adjustment line if needed.
-- Line-item tax computation SELECT li.id AS line_item_id, li.taxable_amount, tr.tax_type, tr.rate, ROUND(li.taxable_amount * tr.rate / 100, 2) AS tax_amount FROM invoice_line_items li JOIN config.tax_groups tg ON tg.id = li.tax_group_id JOIN config.tax_rates tr ON tr.id = ANY(tg.tax_ids) WHERE li.invoice_id = :invoice_id AND tr.is_active = TRUE; -- Invoice-level aggregation by tax type SELECT tr.tax_type, SUM(ROUND(li.taxable_amount * tr.rate / 100, 2)) AS total_tax FROM invoice_line_items li JOIN config.tax_groups tg ON tg.id = li.tax_group_id JOIN config.tax_rates tr ON tr.id = ANY(tg.tax_ids) WHERE li.invoice_id = :invoice_id AND tr.is_active = TRUE GROUP BY tr.tax_type; -- Round-off adjustment: ROUND(total, 0) - total
| Type | Description | Tax Treatment | Certificate Required |
|---|---|---|---|
| SEZ | Special Economic Zone vendors | Zero-rated supply; no GST | SEZ registration + LUT/Bond |
| GOVERNMENT | Government entity purchases | Specific exemptions per notification | Government order reference |
| DIPLOMATIC | Diplomatic missions | Full GST exemption on eligible goods | Diplomatic exemption certificate |
| MSME | Micro, Small, Medium Enterprises | Composition scheme / threshold exemptions | Udyam registration number |
| EXPORT | Export transactions | Zero-rated under LUT or IGST refund | LUT filing / Export docs |
-- Check if vendor has valid exemption SELECT te.exemption_type, te.exempted_taxes, te.status FROM config.tax_exemptions te WHERE te.entity_id = :vendor_id AND te.entity_type = 'VENDOR' AND te.status = 'ACTIVE' AND te.valid_from <= CURRENT_DATE AND te.valid_until >= CURRENT_DATE; -- Valid: apply zero-rate for taxes in exempted_taxes JSONB -- Expired: auto-update status to 'EXPIRED', apply standard rates
Under RCM, the recipient (buyer) is liable to pay GST instead of the supplier. This applies to purchases from unregistered vendors and specific notified services under Section 9(3) of the CGST Act.
| Scenario | Condition | RCM Action |
|---|---|---|
| Unregistered vendor | Supplier has no valid GSTIN | Buyer pays GST under RCM on full invoice value |
| Notified services | Services under Section 9(3) CGST Act | Buyer self-assesses and pays GST |
| Import of services | Services from outside India | IGST payable by recipient under RCM |
[Vendor Invoice Received]
|
v
+-------------------------------+
| Vendor has valid GSTIN? |
+-------+--------------+-------+
YES NO ---------> [Flag as RCM; buyer pays GST]
|
v
+-------------------------------+
| Service under notified RCM |
| category (Sec 9(3))? |
+-------+--------------+-------+
YES NO
| |
v v
+--------------+ +--------------+
| Apply RCM | | Standard |
| (buyer pays | | treatment |
| despite GSTN)| | (vendor pays)|
+--------------+ +--------------+
Tax rates can change via GST Council notifications mid-year. The effective_from and effective_until columns on config.tax_rates enable accurate historical lookups and seamless rate transitions.
-- Mid-year rate change (e.g., GST on HSN 8471 from 18% to 12%) -- Step 1: Close old rate record UPDATE config.tax_rates SET effective_until = '2025-10-31' WHERE hsn_sac_code = '8471' AND rate = 18.00 AND effective_until IS NULL; -- Step 2: Insert new rate record INSERT INTO config.tax_rates (tax_code, tax_name, tax_type, rate, hsn_sac_code, effective_from, is_active) VALUES ('GST12_8471', 'GST 12% - Computers', 'GST', 12.00, '8471', '2025-11-01', TRUE); -- Historical lookup for a past invoice SELECT tr.rate FROM config.tax_rates tr WHERE tr.hsn_sac_code = '8471' AND tr.effective_from <= :invoice_date AND (tr.effective_until IS NULL OR tr.effective_until >= :invoice_date) AND tr.is_active = TRUE ORDER BY tr.effective_from DESC LIMIT 1;
| Rule ID | Rule Description | Enforcement |
|---|---|---|
| BR-TAX-001 | Tax is auto-applied based on HSN/SAC code. Manual override of the auto-determined rate requires Finance Manager approval. | System blocks manual tax changes unless approved via workflow. Audit log records overrides with approver ID and justification. |
| BR-TAX-002 | TDS deduction is mandatory for vendor payments exceeding the threshold for the applicable section (194C, 194J, 194Q). Aggregate thresholds tracked per vendor per FY. | Payment processing blocked if TDS not computed. System auto-calculates TDS at invoice approval stage. |
| BR-TAX-003 | Exemption certificates must be validated (status = ACTIVE, valid_until >= current date) before applying zero-rate taxation. | System checks config.tax_exemptions at computation time. Expired or revoked certificates result in standard tax rates. |
| BR-TAX-004 | Inter-state vs intra-state determination is automatic based on GSTIN first two digits. Manual classification is not permitted. | GSTIN state code extraction is programmatic. Missing GSTIN flags transaction for manual finance review. |
ProKure Database Documentation - Tax Configuration Logic v1.0
Part of the ProKure Procurement Management System