@mudraforge/statutory 2.12.1 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +13 -0
- package/docs/ARCHITECTURE.md +70 -47
- package/docs/ARCHITECTURE_DECISIONS.md +22 -2
- package/docs/CORPUS_QUALITY.md +3 -3
- package/docs/DOMAIN_BREADTH_AND_DEPTH_COMPARISON.md +4 -4
- package/docs/ENTERPRISE_GOVERNANCE.md +2 -1
- package/docs/OKF_MAINTENANCE_SOP.md +5 -5
- package/docs/PILOT_EVALUATION_GUIDE.md +5 -4
- package/docs/PROVENANCE.md +6 -6
- package/docs/VERIFICATION.md +6 -6
- package/okf/corporate_ma_restructuring/business_combinations_indas_103/ast.json +20 -0
- package/okf/corporate_ma_restructuring/impairment_of_assets_indas_36/ast.json +20 -0
- package/okf/corporate_ma_restructuring/loss_carryforward_sec79/ast.json +33 -0
- package/okf/corporate_ma_restructuring/share_based_payments_indas_102/ast.json +20 -0
- package/okf/corporate_ma_restructuring/slump_sale_50b/ast.json +21 -0
- package/okf/corporate_ma_restructuring/tax_clearance_sec281/ast.json +21 -0
- package/okf/direct_tax/corporate_tax_115baa_115jb/ast.json +23 -0
- package/okf/direct_tax/income_taxes_deferred_tax_indas_12/ast.json +20 -0
- package/okf/direct_tax/special_rates_non_filer_206ab/ast.json +26 -0
- package/okf/direct_tax/statutory_disallowance_43b/ast.json +35 -0
- package/okf/direct_tax/tcs_goods_206c_1h/ast.json +69 -0
- package/okf/direct_tax/tds_commission_194h/ast.json +60 -0
- package/okf/direct_tax/tds_contractor_194c/ast.json +71 -0
- package/okf/direct_tax/tds_ecommerce_194o/ast.json +48 -0
- package/okf/direct_tax/tds_goods_194q/ast.json +71 -0
- package/okf/direct_tax/tds_goods_393/ast.json +59 -0
- package/okf/direct_tax/tds_individual_contract_194m/ast.json +59 -0
- package/okf/direct_tax/tds_interest_194a/ast.json +59 -0
- package/okf/direct_tax/tds_perquisites_194r/ast.json +47 -0
- package/okf/direct_tax/tds_property_194ia/ast.json +70 -0
- package/okf/direct_tax/tds_rent_194i/ast.json +60 -0
- package/okf/direct_tax/tds_rent_individual_194ib/ast.json +59 -0
- package/okf/direct_tax/tds_services_194j/ast.json +60 -0
- package/okf/indirect_tax_gst/blocked_itc_17_5/ast.json +26 -0
- package/okf/indirect_tax_gst/common_itc_reversal_rule42_43/ast.json +26 -0
- package/okf/indirect_tax_gst/composite_mixed_supplies_sec8/ast.json +21 -0
- package/okf/indirect_tax_gst/composition_levy_sec10/ast.json +23 -0
- package/okf/indirect_tax_gst/credit_debit_notes_sec34/ast.json +21 -0
- package/okf/indirect_tax_gst/e_invoicing_rule48_4/ast.json +20 -0
- package/okf/indirect_tax_gst/export_services_lut_sec16/ast.json +20 -0
- package/okf/indirect_tax_gst/gst_tds_sec51/ast.json +23 -0
- package/okf/indirect_tax_gst/itc_eligibility_16_2/ast.json +20 -0
- package/okf/indirect_tax_gst/itc_reversal_rule37_37a/ast.json +45 -0
- package/okf/indirect_tax_gst/rcm_liability_sec9_3/ast.json +26 -0
- package/okf/international_tax/cross_border_remittance_195/ast.json +39 -0
- package/okf/international_tax/financial_instruments_ecl_indas_109/ast.json +24 -0
- package/okf/international_tax/foreign_exchange_indas_21_109/ast.json +20 -0
- package/okf/international_tax/foreign_tax_credit_irc_901_904/ast.json +20 -0
- package/okf/international_tax/transfer_pricing_alp_92c/ast.json +25 -0
- package/okf/manifest.json +49 -3
- package/okf/msme_commercial/delayed_payments_15_16/ast.json +38 -0
- package/okf/msme_commercial/enterprise_classification_sec7/ast.json +25 -0
- package/okf/msme_commercial/lease_accounting_indas_116/ast.json +20 -0
- package/okf/msme_commercial/mca_msme_1_filing/ast.json +20 -0
- package/okf/msme_commercial/provisions_contingencies_indas_37/ast.json +20 -0
- package/okf/msme_commercial/revenue_recognition_indas_115/ast.json +20 -0
- package/okf/msme_commercial/statutory_disclosures_sec22/ast.json +21 -0
- package/package.json +16 -1
- package/src/constants.js +1 -1
- package/src/index.js +16 -2
- package/src/payroll.js +506 -0
- package/src/usvm/evaluation_vm.js +504 -0
- package/src/usvm/index.js +65 -0
- package/src/usvm/math_rational.js +165 -0
- package/src/usvm/rules/sec_115baa_115jb_mat.json +23 -0
- package/src/usvm/rules/sec_192_salary_tds.json +23 -0
- package/src/usvm/rules/sec_194a_interest.json +59 -0
- package/src/usvm/rules/sec_194c_contractors.json +71 -0
- package/src/usvm/rules/sec_194h_commission.json +60 -0
- package/src/usvm/rules/sec_194i_rent.json +60 -0
- package/src/usvm/rules/sec_194ia_property.json +70 -0
- package/src/usvm/rules/sec_194ib_rent_ind.json +59 -0
- package/src/usvm/rules/sec_194j_services.json +60 -0
- package/src/usvm/rules/sec_194m_contract_ind.json +59 -0
- package/src/usvm/rules/sec_194o_ecommerce.json +48 -0
- package/src/usvm/rules/sec_194q_goods.json +71 -0
- package/src/usvm/rules/sec_194r_perquisites.json +47 -0
- package/src/usvm/rules/sec_195_cross_border.json +39 -0
- package/src/usvm/rules/sec_206ab_non_filer.json +26 -0
- package/src/usvm/rules/sec_206c1h_tcs.json +69 -0
- package/src/usvm/rules/sec_281_tax_clearance.json +21 -0
- package/src/usvm/rules/sec_393_goods.json +59 -0
- package/src/usvm/rules/sec_43bh_disallowance.json +35 -0
- package/src/usvm/rules/sec_50b_slump_sale.json +21 -0
- package/src/usvm/rules/sec_79_loss_continuity.json +33 -0
- package/src/usvm/rules/sec_92c_transfer_pricing.json +25 -0
- package/src/usvm/rules/sec_ftc_dtaa_relief.json +20 -0
- package/src/usvm/rules/sec_gst_blocked_itc_17_5.json +26 -0
- package/src/usvm/rules/sec_gst_composite_mixed_8.json +21 -0
- package/src/usvm/rules/sec_gst_composition_levy_10.json +23 -0
- package/src/usvm/rules/sec_gst_credit_debit_notes_34.json +21 -0
- package/src/usvm/rules/sec_gst_einvoicing_rule48_4.json +20 -0
- package/src/usvm/rules/sec_gst_ewaybill_rule138.json +21 -0
- package/src/usvm/rules/sec_gst_export_lut_16.json +20 -0
- package/src/usvm/rules/sec_gst_itc_eligibility_16_2.json +20 -0
- package/src/usvm/rules/sec_gst_itc_reversal_rule37_37a.json +45 -0
- package/src/usvm/rules/sec_gst_rcm_liability_9_3.json +26 -0
- package/src/usvm/rules/sec_gst_rule42_43_apportionment.json +26 -0
- package/src/usvm/rules/sec_gst_tds_sec51.json +23 -0
- package/src/usvm/rules/sec_indas102_esop.json +20 -0
- package/src/usvm/rules/sec_indas103_mna.json +20 -0
- package/src/usvm/rules/sec_indas109_ecl.json +24 -0
- package/src/usvm/rules/sec_indas115_revenue.json +20 -0
- package/src/usvm/rules/sec_indas116_leases.json +20 -0
- package/src/usvm/rules/sec_indas12_deferred_tax.json +20 -0
- package/src/usvm/rules/sec_indas21_fx_reval.json +20 -0
- package/src/usvm/rules/sec_indas36_impairment.json +20 -0
- package/src/usvm/rules/sec_indas37_provisions.json +20 -0
- package/src/usvm/rules/sec_msme_classification_sec7.json +25 -0
- package/src/usvm/rules/sec_msme_delayed_payments_15_16.json +38 -0
- package/src/usvm/rules/sec_msme_disclosures_sec22.json +21 -0
- package/src/usvm/rules/sec_msme_mca_form_1.json +20 -0
- package/src/usvm/schemas/statutory_ast_schema.js +203 -0
- package/src/usvm/usvm_domain_evaluators.js +1021 -0
- package/types/index.d.ts +39 -0
|
@@ -0,0 +1,1021 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MUDRAFORGE UNIVERSAL STATUTORY VIRTUAL MACHINE (USVM) - DOMAIN EVALUATORS
|
|
3
|
+
* Implements pure evaluation handlers for advanced statutory archetypes:
|
|
4
|
+
* - MSMED Section 15/16 3x Bank Compounding
|
|
5
|
+
* - Section 43B(h) March 31 Fiscal Boundary Engine
|
|
6
|
+
* - MSMED Section 7 Enterprise Classification
|
|
7
|
+
* - CGST Rule 37 180-Day ITC Reversal & Rule 37A Supplier Non-Filing
|
|
8
|
+
* - CGST Rule 42/43 Input & Capital Goods Common Credit Apportionment
|
|
9
|
+
* - International Section 195/393 Cross-Border DTAA Treaty Matrix
|
|
10
|
+
* - Transfer Pricing Section 92C & Rule 10CA Percentile ALP
|
|
11
|
+
* - Section 79 Loss Carryforward & Voting Continuity
|
|
12
|
+
* - Section 281 Tax Clearance & Void Asset Transfer
|
|
13
|
+
*
|
|
14
|
+
* Strict Statutory Invariant: Every evaluation stamps isAuthorizedToDisburse: false.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
roundToPaisa,
|
|
19
|
+
roundSection288B,
|
|
20
|
+
cleanNumericAmount,
|
|
21
|
+
calculateMsmeCompoundInterest,
|
|
22
|
+
evaluateSection43bH,
|
|
23
|
+
calculateItcReversalRule37,
|
|
24
|
+
calculateRule37ASupplierNonFilingReversal,
|
|
25
|
+
calculateGstItcApportionmentRule42_43,
|
|
26
|
+
evaluateCrossBorderRemittance,
|
|
27
|
+
calculateTransferPricingAlp,
|
|
28
|
+
evaluateSection79LossContinuity,
|
|
29
|
+
evaluateSection281TaxClearance,
|
|
30
|
+
revalueForeignExchangeIndAs109,
|
|
31
|
+
calculateCorporateTaxMatVsConcessional,
|
|
32
|
+
generateMsme1AndScheduleThreeAging,
|
|
33
|
+
calculateRevenueAllocationIndAs115,
|
|
34
|
+
calculateLeaseAmortizationIndAs116,
|
|
35
|
+
calculateExpectedCreditLossIndAs109,
|
|
36
|
+
calculateEsopAmortizationIndAs102,
|
|
37
|
+
calculateDeferredTaxIndAs12,
|
|
38
|
+
evaluateProvisionsAndContingenciesIndAs37,
|
|
39
|
+
calculateForeignCurrencyIndAs21,
|
|
40
|
+
calculateImpairmentIndAs36,
|
|
41
|
+
calculateBusinessCombinationsIndAs103
|
|
42
|
+
} from '../calculators.js';
|
|
43
|
+
|
|
44
|
+
import {
|
|
45
|
+
evaluateSalaryTds
|
|
46
|
+
} from '../payroll.js';
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Evaluates MSMED Section 15/16 Compound Interest at 3x RBI Bank Rate.
|
|
50
|
+
*/
|
|
51
|
+
export function evaluateMsmeDelayedPaymentCompoundInterest(ruleAst, facts, trace = []) {
|
|
52
|
+
trace.push(`USVM evaluating MSMED Section 15/16 delayed payments compounding`);
|
|
53
|
+
const principal = facts.principal ?? facts.invoiceAmount ?? facts.consideration ?? 0;
|
|
54
|
+
const rbiBankRate = facts.rbiBankRate ?? ruleAst.computation?.defaultBankRate ?? 0.0675;
|
|
55
|
+
|
|
56
|
+
const res = calculateMsmeCompoundInterest({
|
|
57
|
+
principal,
|
|
58
|
+
acceptanceDate: facts.acceptanceDate || null,
|
|
59
|
+
deliveryDate: facts.deliveryDate || null,
|
|
60
|
+
writtenObjectionDate: facts.writtenObjectionDate || null,
|
|
61
|
+
objectionRemovalDate: facts.objectionRemovalDate || null,
|
|
62
|
+
agreedPaymentDate: facts.agreedPaymentDate || null,
|
|
63
|
+
hasWrittenAgreement: facts.hasWrittenAgreement,
|
|
64
|
+
vendorNicCode: facts.vendorNicCode || facts.nicCode || null,
|
|
65
|
+
nicCode: facts.nicCode || facts.vendorNicCode || null,
|
|
66
|
+
supplierType: facts.supplierType || null,
|
|
67
|
+
isTrader: facts.isTrader,
|
|
68
|
+
dueDate: facts.dueDate || null,
|
|
69
|
+
accrualStartDate: facts.accrualStartDate || null,
|
|
70
|
+
paymentDate: facts.paymentDate || facts.transactionDate || new Date().toISOString(),
|
|
71
|
+
rbiBankRate,
|
|
72
|
+
dateConvention: facts.dateConvention || 'START_DATE_INCLUSIVE',
|
|
73
|
+
commenceDayAfter: facts.commenceDayAfter || false,
|
|
74
|
+
includePaymentDate: facts.includePaymentDate || false
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
...res,
|
|
79
|
+
ruleId: ruleAst.sectionId,
|
|
80
|
+
ruleVersion: ruleAst.version,
|
|
81
|
+
governingStatute: ruleAst.governingStatute,
|
|
82
|
+
governingSection: ruleAst.statutorySection,
|
|
83
|
+
isAuthorizedToDisburse: false, // Fiduciary invariant
|
|
84
|
+
executionTrace: trace
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Evaluates Section 43B(h) Temporal & Fiscal Boundary State Machine.
|
|
90
|
+
*/
|
|
91
|
+
export function evaluateSection43bHFiscalBoundary(ruleAst, facts, trace = []) {
|
|
92
|
+
trace.push(`USVM evaluating Section 43B(h) fiscal year boundary`);
|
|
93
|
+
const res = evaluateSection43bH({
|
|
94
|
+
invoiceDate: facts.invoiceDate || facts.transactionDate || facts.creditDate,
|
|
95
|
+
acceptanceDate: facts.acceptanceDate || null,
|
|
96
|
+
agreedTermsDays: facts.agreedTermsDays || null,
|
|
97
|
+
disputeStartDate: facts.disputeStartDate || null,
|
|
98
|
+
disputeEndDate: facts.disputeEndDate || null,
|
|
99
|
+
paymentDate: facts.paymentDate || null,
|
|
100
|
+
fyEndDate: facts.fyEndDate || null,
|
|
101
|
+
supplierType: facts.supplierType || 'MANUFACTURER',
|
|
102
|
+
nicCode: facts.nicCode || facts.vendorNicCode || null
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
...res,
|
|
107
|
+
ruleId: ruleAst.sectionId,
|
|
108
|
+
ruleVersion: ruleAst.version,
|
|
109
|
+
governingStatute: ruleAst.governingStatute,
|
|
110
|
+
governingSection: ruleAst.statutorySection,
|
|
111
|
+
isAuthorizedToDisburse: false,
|
|
112
|
+
executionTrace: trace
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Evaluates Section 7 MSME Enterprise Classification (Micro / Small / Medium).
|
|
118
|
+
*/
|
|
119
|
+
export function evaluateMsmeEnterpriseClassification(ruleAst, facts, trace = []) {
|
|
120
|
+
trace.push(`USVM evaluating MSME Section 7 classification criteria`);
|
|
121
|
+
const plantAndMachinery = Number(facts.plantAndMachineryInr ?? facts.investmentInPpmInr ?? 0);
|
|
122
|
+
const turnover = Number(facts.turnoverInr ?? 0);
|
|
123
|
+
|
|
124
|
+
let enterpriseCategory = 'LARGE';
|
|
125
|
+
let statutoryBasis = '';
|
|
126
|
+
|
|
127
|
+
// Micro: Plant/Machinery <= 1 Cr AND Turnover <= 5 Cr
|
|
128
|
+
if (plantAndMachinery <= 10000000 && turnover <= 50000000) {
|
|
129
|
+
enterpriseCategory = 'MICRO';
|
|
130
|
+
statutoryBasis = 'Investment <= 1 Crore and Turnover <= 5 Crores under Section 7(1) of MSMED Act, 2006';
|
|
131
|
+
} else if (plantAndMachinery <= 100000000 && turnover <= 500000000) {
|
|
132
|
+
enterpriseCategory = 'SMALL';
|
|
133
|
+
statutoryBasis = 'Investment <= 10 Crores and Turnover <= 50 Crores under Section 7(1) of MSMED Act, 2006';
|
|
134
|
+
} else if (plantAndMachinery <= 500000000 && turnover <= 2500000000) {
|
|
135
|
+
enterpriseCategory = 'MEDIUM';
|
|
136
|
+
statutoryBasis = 'Investment <= 50 Crores and Turnover <= 250 Crores under Section 7(1) of MSMED Act, 2006';
|
|
137
|
+
} else {
|
|
138
|
+
enterpriseCategory = 'LARGE';
|
|
139
|
+
statutoryBasis = 'Investment > 50 Crores or Turnover > 250 Crores exceeds MSME ceiling';
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
enterpriseCategory,
|
|
144
|
+
isMicroOrSmall: enterpriseCategory === 'MICRO' || enterpriseCategory === 'SMALL',
|
|
145
|
+
isMedium: enterpriseCategory === 'MEDIUM',
|
|
146
|
+
isMsme: enterpriseCategory !== 'LARGE',
|
|
147
|
+
plantAndMachineryInr: plantAndMachinery,
|
|
148
|
+
turnoverInr: turnover,
|
|
149
|
+
statutoryBasis,
|
|
150
|
+
ruleId: ruleAst.sectionId,
|
|
151
|
+
ruleVersion: ruleAst.version,
|
|
152
|
+
governingStatute: ruleAst.governingStatute,
|
|
153
|
+
governingSection: ruleAst.statutorySection,
|
|
154
|
+
isAuthorizedToDisburse: false,
|
|
155
|
+
executionTrace: trace
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Evaluates CGST Rule 37 180-Day Non-Payment Proportional ITC Reversal.
|
|
161
|
+
*/
|
|
162
|
+
export function evaluateGstRule37ProportionalReversal(ruleAst, facts, trace = []) {
|
|
163
|
+
trace.push(`USVM evaluating CGST Rule 37 180-day ITC reversal`);
|
|
164
|
+
const res = calculateItcReversalRule37({
|
|
165
|
+
invoiceNumber: facts.invoiceNumber || 'INV-UNKNOWN',
|
|
166
|
+
invoiceDate: facts.invoiceDate || facts.transactionDate,
|
|
167
|
+
calculationDate: facts.calculationDate || facts.paymentDate || new Date().toISOString().slice(0, 10),
|
|
168
|
+
invoiceAmount: facts.invoiceAmount ?? facts.grossAmountInr ?? 0,
|
|
169
|
+
taxAmount: facts.taxAmount ?? facts.itcClaimedInr ?? 0,
|
|
170
|
+
paidAmount: facts.paidAmount ?? facts.valuePaidInr ?? 0,
|
|
171
|
+
itcAvailmentDate: facts.itcAvailmentDate || null,
|
|
172
|
+
isRcm: facts.isRcm === true,
|
|
173
|
+
isScheduleISupply: facts.isScheduleISupply === true,
|
|
174
|
+
annualInterestRatePercent: facts.annualInterestRatePercent ?? ruleAst.computation?.annualInterestRatePercent ?? 18.0
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
...res,
|
|
179
|
+
ruleId: ruleAst.sectionId,
|
|
180
|
+
ruleVersion: ruleAst.version,
|
|
181
|
+
governingStatute: ruleAst.governingStatute,
|
|
182
|
+
governingSection: ruleAst.statutorySection,
|
|
183
|
+
isAuthorizedToDisburse: false,
|
|
184
|
+
executionTrace: trace
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Evaluates CGST Rule 37A Supplier GSTR-3B Non-Filing Reversal.
|
|
190
|
+
*/
|
|
191
|
+
export function evaluateGstRule37ASupplierNonFiling(ruleAst, facts, trace = []) {
|
|
192
|
+
trace.push(`USVM evaluating CGST Rule 37A supplier non-filing cutover`);
|
|
193
|
+
const res = calculateRule37ASupplierNonFilingReversal({
|
|
194
|
+
financialYear: facts.financialYear || '2024-25',
|
|
195
|
+
supplierGstin: facts.supplierGstin || 'UNKNOWN',
|
|
196
|
+
itcClaimedInr: facts.itcClaimedInr ?? facts.taxAmount ?? 0,
|
|
197
|
+
hasSupplierFiledGstr3B: facts.hasSupplierFiledGstr3B === true,
|
|
198
|
+
currentEvaluationDate: facts.currentEvaluationDate || facts.transactionDate || new Date().toISOString().slice(0, 10),
|
|
199
|
+
subsequentFilingDate: facts.subsequentFilingDate || null
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
return {
|
|
203
|
+
...res,
|
|
204
|
+
ruleId: ruleAst.sectionId,
|
|
205
|
+
ruleVersion: ruleAst.version,
|
|
206
|
+
governingStatute: ruleAst.governingStatute,
|
|
207
|
+
governingSection: ruleAst.statutorySection,
|
|
208
|
+
isAuthorizedToDisburse: false,
|
|
209
|
+
executionTrace: trace
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Evaluates CGST Rule 42/43 Common ITC Apportionment and Exempt Ratio Reversal.
|
|
215
|
+
*/
|
|
216
|
+
export function evaluateGstRule42CommonCreditApportionment(ruleAst, facts, trace = []) {
|
|
217
|
+
trace.push(`USVM evaluating CGST Rule 42/43 common credit apportionment`);
|
|
218
|
+
const res = calculateGstItcApportionmentRule42_43({
|
|
219
|
+
taxPeriod: facts.taxPeriod || null,
|
|
220
|
+
financialYear: facts.financialYear || '2025-26',
|
|
221
|
+
totalInputTaxCreditT: facts.totalInputTaxCreditT ?? facts.totalItc ?? facts.taxAmount,
|
|
222
|
+
exclusiveNonBusinessT1: facts.exclusiveNonBusinessT1 || 0,
|
|
223
|
+
exclusiveExemptT2: facts.exclusiveExemptT2 || 0,
|
|
224
|
+
blockedSection17_5_T3: facts.blockedSection17_5_T3 || 0,
|
|
225
|
+
exclusiveTaxableT4: facts.exclusiveTaxableT4 || 0,
|
|
226
|
+
exemptTurnoverE: facts.exemptTurnoverE || 0,
|
|
227
|
+
totalTurnoverF: facts.totalTurnoverF || 0,
|
|
228
|
+
capitalGoodsCommonCreditA: facts.capitalGoodsCommonCreditA || 0,
|
|
229
|
+
capitalGoodsPriorQuartersExempt: facts.capitalGoodsPriorQuartersExempt || 0,
|
|
230
|
+
isAnnualTrueUp: facts.isAnnualTrueUp === true,
|
|
231
|
+
annualExemptTurnover: facts.annualExemptTurnover || null,
|
|
232
|
+
annualTotalTurnover: facts.annualTotalTurnover || null,
|
|
233
|
+
sumOfMonthlyReversalsD1: facts.sumOfMonthlyReversalsD1 || 0,
|
|
234
|
+
isRealEstateProject: facts.isRealEstateProject === true
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
...res,
|
|
239
|
+
ruleId: ruleAst.sectionId,
|
|
240
|
+
ruleVersion: ruleAst.version,
|
|
241
|
+
governingStatute: ruleAst.governingStatute,
|
|
242
|
+
governingSection: ruleAst.statutorySection,
|
|
243
|
+
isAuthorizedToDisburse: false,
|
|
244
|
+
executionTrace: trace
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Evaluates Section 195/393 Cross-Border Remittance & DTAA Form Matrix.
|
|
250
|
+
*/
|
|
251
|
+
export function evaluateCrossBorderDtaaMatrix(ruleAst, facts, temporal, trace = []) {
|
|
252
|
+
trace.push(`USVM evaluating Section 195/393 cross-border remittance`);
|
|
253
|
+
const res = evaluateCrossBorderRemittance({
|
|
254
|
+
amountUsd: facts.amountUsd ?? (facts.amountInr ? facts.amountInr / (facts.fxRate || 83.5) : 0),
|
|
255
|
+
fxRate: facts.fxRate || 83.5,
|
|
256
|
+
transactionDate: facts.transactionDate || temporal?.crystallizedDate || new Date().toISOString(),
|
|
257
|
+
country: facts.country || null,
|
|
258
|
+
isAutomatedCloudInfra: facts.isAutomatedCloudInfra !== false,
|
|
259
|
+
hasHumanTechnicalServices: facts.hasHumanTechnicalServices === true,
|
|
260
|
+
hasTrc: facts.hasTrc === true,
|
|
261
|
+
hasNoPe: facts.hasNoPe === true,
|
|
262
|
+
hasForm10F: facts.hasForm10F === true,
|
|
263
|
+
hasAoCertificate: facts.hasAoCertificate === true
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
return {
|
|
267
|
+
...res,
|
|
268
|
+
ruleId: ruleAst.sectionId,
|
|
269
|
+
ruleVersion: ruleAst.version,
|
|
270
|
+
governingStatute: ruleAst.governingStatute,
|
|
271
|
+
governingSection: ruleAst.statutorySection,
|
|
272
|
+
isAuthorizedToDisburse: false,
|
|
273
|
+
executionTrace: trace
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Evaluates Section 92C & Rule 10CA Transfer Pricing Percentile Range & ALP.
|
|
279
|
+
*/
|
|
280
|
+
export function evaluateTransferPricingPercentileAlp(ruleAst, facts, trace = []) {
|
|
281
|
+
trace.push(`USVM evaluating Section 92C & Rule 10CA Transfer Pricing ALP`);
|
|
282
|
+
const res = calculateTransferPricingAlp({
|
|
283
|
+
transactionDescription: facts.transactionDescription || 'International Transaction with Associated Enterprise',
|
|
284
|
+
testedParty: facts.testedParty || 'Indian Enterprise',
|
|
285
|
+
associatedEnterpriseName: facts.associatedEnterpriseName || 'Foreign AE',
|
|
286
|
+
isAssociatedEnterprise: facts.isAssociatedEnterprise !== false,
|
|
287
|
+
internationalTransactionAmountInr: facts.internationalTransactionAmountInr ?? facts.amountInr ?? 0,
|
|
288
|
+
testedPartyOperatingMarginPercent: facts.testedPartyOperatingMarginPercent ?? facts.marginPercent ?? 0,
|
|
289
|
+
isWholesaleTrading: facts.isWholesaleTrading === true,
|
|
290
|
+
comparablesData: facts.comparablesData || [],
|
|
291
|
+
transferPricingMethod: facts.transferPricingMethod || 'TNMM'
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
return {
|
|
295
|
+
...res,
|
|
296
|
+
ruleId: ruleAst.sectionId,
|
|
297
|
+
ruleVersion: ruleAst.version,
|
|
298
|
+
governingStatute: ruleAst.governingStatute,
|
|
299
|
+
governingSection: ruleAst.statutorySection,
|
|
300
|
+
isAuthorizedToDisburse: false,
|
|
301
|
+
executionTrace: trace
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Evaluates Section 79 Loss Carryforward & Voting Continuity.
|
|
307
|
+
*/
|
|
308
|
+
export function evaluateSection79VotingContinuity(ruleAst, facts, trace = []) {
|
|
309
|
+
trace.push(`USVM evaluating Section 79 voting continuity`);
|
|
310
|
+
const res = evaluateSection79LossContinuity({
|
|
311
|
+
companyType: facts.companyType || 'CLOSELY_HELD_COMPANY',
|
|
312
|
+
isDpiitRecognizedStartup: facts.isDpiitRecognizedStartup === true,
|
|
313
|
+
isIbcResolutionPlan: facts.isIbcResolutionPlan === true,
|
|
314
|
+
accumulatedBroughtForwardLossInr: facts.accumulatedBroughtForwardLossInr || 0,
|
|
315
|
+
unabsorbedDepreciationInr: facts.unabsorbedDepreciationInr || 0,
|
|
316
|
+
shareholdingInLossYear: facts.shareholdingInLossYear || [],
|
|
317
|
+
shareholdingInSetOffYear: facts.shareholdingInSetOffYear || [],
|
|
318
|
+
votingPowerHeldByOriginalShareholdersPercent: facts.votingPowerHeldByOriginalShareholdersPercent ?? null
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
return {
|
|
322
|
+
...res,
|
|
323
|
+
ruleId: ruleAst.sectionId,
|
|
324
|
+
ruleVersion: ruleAst.version,
|
|
325
|
+
governingStatute: ruleAst.governingStatute,
|
|
326
|
+
governingSection: ruleAst.statutorySection,
|
|
327
|
+
isAuthorizedToDisburse: false,
|
|
328
|
+
executionTrace: trace
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Evaluates Section 281 Void Transfer of Assets during Tax Proceedings.
|
|
334
|
+
*/
|
|
335
|
+
export function evaluateSection281VoidTransfer(ruleAst, facts, trace = []) {
|
|
336
|
+
trace.push(`USVM evaluating Section 281 tax clearance`);
|
|
337
|
+
const res = evaluateSection281TaxClearance({
|
|
338
|
+
assetType: facts.assetType || 'IMMOVABLE_PROPERTY',
|
|
339
|
+
assetDescription: facts.assetDescription || 'Commercial Asset / Undertaking',
|
|
340
|
+
assetValueInr: facts.assetValueInr ?? facts.consideration ?? 0,
|
|
341
|
+
transferNature: facts.transferNature || 'SALE',
|
|
342
|
+
hasPendingProceedings: facts.hasPendingProceedings === true,
|
|
343
|
+
pendingProceedings: facts.pendingProceedings || [],
|
|
344
|
+
hasOutstandingDemand: facts.hasOutstandingDemand === true,
|
|
345
|
+
outstandingDemandInr: facts.outstandingDemandInr || 0,
|
|
346
|
+
hasPriorAoPermission: facts.hasPriorAoPermission === true,
|
|
347
|
+
aoPermissionReference: facts.aoPermissionReference || null,
|
|
348
|
+
aoPermissionDate: facts.aoPermissionDate || null,
|
|
349
|
+
hasAdequateConsideration: facts.hasAdequateConsideration !== false,
|
|
350
|
+
hasNoticeOfProceedingsOrDemand: facts.hasNoticeOfProceedingsOrDemand === true,
|
|
351
|
+
alternativeSecurityFurnishedInr: facts.alternativeSecurityFurnishedInr || 0
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
return {
|
|
355
|
+
...res,
|
|
356
|
+
ruleId: ruleAst.sectionId,
|
|
357
|
+
ruleVersion: ruleAst.version,
|
|
358
|
+
governingStatute: ruleAst.governingStatute,
|
|
359
|
+
governingSection: ruleAst.statutorySection,
|
|
360
|
+
isAuthorizedToDisburse: false,
|
|
361
|
+
executionTrace: trace
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Evaluates Corporate Tax Section 115BAA vs MAT Section 115JB.
|
|
367
|
+
*/
|
|
368
|
+
export function evaluateCorporateTaxMatVsConcessionalUsvm(ruleAst, facts, trace = []) {
|
|
369
|
+
trace.push('USVM evaluating Corporate Tax Section 115BAA vs MAT 115JB');
|
|
370
|
+
const res = calculateCorporateTaxMatVsConcessional({
|
|
371
|
+
netProfitBeforeTaxInr: facts.netProfitBeforeTaxInr ?? facts.profitBeforeTaxInr ?? 0,
|
|
372
|
+
additionsBookProfitInr: facts.additionsBookProfitInr || 0,
|
|
373
|
+
deductionsBookProfitInr: facts.deductionsBookProfitInr || 0,
|
|
374
|
+
deductionsChapterVIAInr: facts.deductionsChapterVIAInr || 0,
|
|
375
|
+
unabsorbedDepreciationInr: facts.unabsorbedDepreciationInr || 0,
|
|
376
|
+
broughtForwardLossInr: facts.broughtForwardLossInr || 0,
|
|
377
|
+
turnoverPriorYearInr: facts.turnoverPriorYearInr || 0,
|
|
378
|
+
isDomesticCompany: facts.isDomesticCompany !== false
|
|
379
|
+
});
|
|
380
|
+
return {
|
|
381
|
+
...res,
|
|
382
|
+
ruleId: ruleAst.sectionId,
|
|
383
|
+
ruleVersion: ruleAst.version,
|
|
384
|
+
governingStatute: ruleAst.governingStatute,
|
|
385
|
+
governingSection: ruleAst.statutorySection,
|
|
386
|
+
isAuthorizedToDisburse: false,
|
|
387
|
+
executionTrace: trace
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Evaluates Salary TDS Section 192 / Section 392.
|
|
393
|
+
*/
|
|
394
|
+
export function evaluateSalaryProgressiveTds(ruleAst, facts, trace = []) {
|
|
395
|
+
trace.push('USVM evaluating Salary TDS Section 192 / Section 392');
|
|
396
|
+
const res = evaluateSalaryTds({
|
|
397
|
+
annualGrossSalaryInr: facts.annualGrossSalaryInr ?? facts.grossSalaryInr ?? 0,
|
|
398
|
+
regime: facts.regime || 'NEW',
|
|
399
|
+
hraExemptionInr: facts.hraExemptionInr || 0,
|
|
400
|
+
section80CDeductionsInr: facts.section80CDeductionsInr || 0,
|
|
401
|
+
section80DDeductionsInr: facts.section80DDeductionsInr || 0,
|
|
402
|
+
otherDeductionsChapterVIAInr: facts.otherDeductionsChapterVIAInr || 0,
|
|
403
|
+
priorTdsDeductedInr: facts.priorTdsDeductedInr || 0,
|
|
404
|
+
remainingMonthsInFy: facts.remainingMonthsInFy || 12
|
|
405
|
+
});
|
|
406
|
+
return {
|
|
407
|
+
...res,
|
|
408
|
+
ruleId: ruleAst.sectionId,
|
|
409
|
+
ruleVersion: ruleAst.version,
|
|
410
|
+
governingStatute: ruleAst.governingStatute,
|
|
411
|
+
governingSection: ruleAst.statutorySection,
|
|
412
|
+
isAuthorizedToDisburse: false,
|
|
413
|
+
executionTrace: trace
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Evaluates Section 206AB Non-Filer Penal Rate.
|
|
419
|
+
*/
|
|
420
|
+
export function evaluateNonFilerPenalRate206AB(ruleAst, facts, trace = []) {
|
|
421
|
+
trace.push('USVM evaluating Section 206AB non-filer rate');
|
|
422
|
+
const txDate = String(facts.transactionDate || facts.creditDate || facts.paymentDate || '2025-01-01');
|
|
423
|
+
const isOmitted = txDate >= '2025-04-01';
|
|
424
|
+
const baseRatePercent = Number(facts.standardRatePercent ?? facts.baseRatePercent ?? 2.0);
|
|
425
|
+
const effectiveRatePercent = isOmitted ? baseRatePercent : Math.max(5.0, baseRatePercent * 2);
|
|
426
|
+
const amountInr = Number(facts.invoiceAmount ?? facts.grossAmountInr ?? 0);
|
|
427
|
+
const calculatedTdsInr = roundToPaisa((amountInr * effectiveRatePercent) / 100);
|
|
428
|
+
|
|
429
|
+
return {
|
|
430
|
+
status: isOmitted ? 'SUNSET_OMITTED_FA_2025' : 'PENAL_RATE_APPLIED',
|
|
431
|
+
isOmittedFinanceAct2025: isOmitted,
|
|
432
|
+
baseRatePercent,
|
|
433
|
+
effectiveRatePercent,
|
|
434
|
+
amountInr,
|
|
435
|
+
calculatedTdsInr,
|
|
436
|
+
statutoryDisposition: isOmitted ? 'SECTION_206AB_OMITTED_USE_STANDARD_RATE' : 'SECTION_206AB_HIGHER_RATE_MANDATORY',
|
|
437
|
+
ruleId: ruleAst.sectionId,
|
|
438
|
+
ruleVersion: ruleAst.version,
|
|
439
|
+
governingStatute: ruleAst.governingStatute,
|
|
440
|
+
governingSection: ruleAst.statutorySection,
|
|
441
|
+
isAuthorizedToDisburse: false,
|
|
442
|
+
executionTrace: trace
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Evaluates Ind AS 12 Deferred Taxes.
|
|
448
|
+
*/
|
|
449
|
+
export function evaluateDeferredTaxIndAs12Usvm(ruleAst, facts, trace = []) {
|
|
450
|
+
trace.push('USVM evaluating Ind AS 12 Deferred Tax');
|
|
451
|
+
const res = calculateDeferredTaxIndAs12({
|
|
452
|
+
accountingProfitInr: facts.accountingProfitInr || 0,
|
|
453
|
+
permanentDifferencesInr: facts.permanentDifferencesInr || 0,
|
|
454
|
+
temporaryTaxableDifferencesInr: facts.temporaryTaxableDifferencesInr || 0,
|
|
455
|
+
temporaryDeductibleDifferencesInr: facts.temporaryDeductibleDifferencesInr || 0,
|
|
456
|
+
enactedTaxRatePercent: facts.enactedTaxRatePercent || 25.17,
|
|
457
|
+
futureExpectedRatePercent: facts.futureExpectedRatePercent || 25.17
|
|
458
|
+
});
|
|
459
|
+
return {
|
|
460
|
+
...res,
|
|
461
|
+
ruleId: ruleAst.sectionId,
|
|
462
|
+
ruleVersion: ruleAst.version,
|
|
463
|
+
governingStatute: ruleAst.governingStatute,
|
|
464
|
+
governingSection: ruleAst.statutorySection,
|
|
465
|
+
isAuthorizedToDisburse: false,
|
|
466
|
+
executionTrace: trace
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Evaluates CGST Section 17(5) Blocked ITC.
|
|
472
|
+
*/
|
|
473
|
+
export function evaluateBlockedCreditSection17_5(ruleAst, facts, trace = []) {
|
|
474
|
+
trace.push('USVM evaluating CGST Section 17(5) blocked credit');
|
|
475
|
+
const category = String(facts.expenseCategory || facts.category || '').toUpperCase();
|
|
476
|
+
const blockedCategories = ['MOTOR_VEHICLE', 'FOOD_AND_BEVERAGES', 'OUTDOOR_CATERING', 'CLUB_MEMBERSHIP', 'HEALTH_FITNESS', 'PERSONAL_CONSUMPTION', 'LOST_STOLEN_GOODS', 'FREE_SAMPLES'];
|
|
477
|
+
const isBlocked = blockedCategories.some(c => category.includes(c));
|
|
478
|
+
const taxAmount = Number(facts.taxAmount ?? facts.itcAmount ?? 0);
|
|
479
|
+
|
|
480
|
+
return {
|
|
481
|
+
status: isBlocked ? 'BLOCKED_ITC_INELIGIBLE' : 'ELIGIBLE_ITC',
|
|
482
|
+
isBlocked,
|
|
483
|
+
blockedCategory: isBlocked ? category : null,
|
|
484
|
+
itcBlockedInr: isBlocked ? taxAmount : 0,
|
|
485
|
+
itcEligibleInr: isBlocked ? 0 : taxAmount,
|
|
486
|
+
governingSection: 'CGST Act, 2017 Section 17(5)',
|
|
487
|
+
ruleId: ruleAst.sectionId,
|
|
488
|
+
ruleVersion: ruleAst.version,
|
|
489
|
+
isAuthorizedToDisburse: false,
|
|
490
|
+
executionTrace: trace
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Evaluates CGST Section 16(2) ITC Eligibility Conditions.
|
|
496
|
+
*/
|
|
497
|
+
export function evaluateItcEligibilitySection16_2(ruleAst, facts, trace = []) {
|
|
498
|
+
trace.push('USVM evaluating CGST Section 16(2) ITC eligibility conditions');
|
|
499
|
+
const hasTaxInvoice = facts.hasTaxInvoice !== false;
|
|
500
|
+
const hasReceivedGoods = facts.hasReceivedGoods !== false;
|
|
501
|
+
const isTaxPaidBySupplier = facts.isTaxPaidBySupplier !== false;
|
|
502
|
+
const hasFurnishedReturn = facts.hasFurnishedReturn !== false;
|
|
503
|
+
|
|
504
|
+
const allConditionsSatisfied = hasTaxInvoice && hasReceivedGoods && isTaxPaidBySupplier && hasFurnishedReturn;
|
|
505
|
+
const taxAmount = Number(facts.taxAmount ?? facts.itcAmount ?? 0);
|
|
506
|
+
|
|
507
|
+
return {
|
|
508
|
+
status: allConditionsSatisfied ? 'ITC_ELIGIBLE' : 'ITC_INELIGIBLE_CONDITIONS_UNMET',
|
|
509
|
+
isEligible: allConditionsSatisfied,
|
|
510
|
+
itcEligibleInr: allConditionsSatisfied ? taxAmount : 0,
|
|
511
|
+
itcIneligibleInr: allConditionsSatisfied ? 0 : taxAmount,
|
|
512
|
+
failedConditions: [
|
|
513
|
+
!hasTaxInvoice ? 'MISSING_TAX_INVOICE' : null,
|
|
514
|
+
!hasReceivedGoods ? 'GOODS_SERVICES_NOT_RECEIVED' : null,
|
|
515
|
+
!isTaxPaidBySupplier ? 'TAX_NOT_PAID_TO_GOVERNMENT' : null,
|
|
516
|
+
!hasFurnishedReturn ? 'GSTR3B_RETURN_NOT_FURNISHED' : null
|
|
517
|
+
].filter(Boolean),
|
|
518
|
+
ruleId: ruleAst.sectionId,
|
|
519
|
+
ruleVersion: ruleAst.version,
|
|
520
|
+
isAuthorizedToDisburse: false,
|
|
521
|
+
executionTrace: trace
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Evaluates CGST Section 9(3) Reverse Charge Mechanism.
|
|
527
|
+
*/
|
|
528
|
+
export function evaluateRcmLiabilitySection9_3(ruleAst, facts, trace = []) {
|
|
529
|
+
trace.push('USVM evaluating CGST Section 9(3) Reverse Charge Mechanism');
|
|
530
|
+
const serviceType = String(facts.serviceType || facts.natureOfSupply || '').toUpperCase();
|
|
531
|
+
const rcmList = ['GTA', 'GOODS_TRANSPORT', 'LEGAL_SERVICES', 'ADVOCATE', 'DIRECTOR', 'RECOVERY_AGENT', 'SECURITY_SERVICES'];
|
|
532
|
+
const isRcmApplicable = rcmList.some(r => serviceType.includes(r));
|
|
533
|
+
const amountInr = Number(facts.invoiceAmount ?? facts.grossAmountInr ?? 0);
|
|
534
|
+
const rcmRatePercent = Number(facts.rcmRatePercent || 5.0);
|
|
535
|
+
const rcmTaxInr = isRcmApplicable ? roundToPaisa((amountInr * rcmRatePercent) / 100) : 0;
|
|
536
|
+
|
|
537
|
+
return {
|
|
538
|
+
status: isRcmApplicable ? 'RCM_TAX_PAYABLE_BY_RECIPIENT' : 'FORWARD_CHARGE_REGULAR',
|
|
539
|
+
isRcmApplicable,
|
|
540
|
+
recipientRcmLiabilityInr: rcmTaxInr,
|
|
541
|
+
cashLedgerPaymentMandatory: isRcmApplicable,
|
|
542
|
+
governingSection: 'CGST Act, 2017 Section 9(3)',
|
|
543
|
+
ruleId: ruleAst.sectionId,
|
|
544
|
+
ruleVersion: ruleAst.version,
|
|
545
|
+
isAuthorizedToDisburse: false,
|
|
546
|
+
executionTrace: trace
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Evaluates CGST Section 8 Composite & Mixed Supplies.
|
|
552
|
+
*/
|
|
553
|
+
export function evaluateCompositeMixedSuppliesSection8(ruleAst, facts, trace = []) {
|
|
554
|
+
trace.push('USVM evaluating CGST Section 8 composite vs mixed supply');
|
|
555
|
+
const supplyType = String(facts.supplyType || 'COMPOSITE').toUpperCase();
|
|
556
|
+
const isComposite = supplyType === 'COMPOSITE';
|
|
557
|
+
const amountInr = Number(facts.invoiceAmount ?? facts.grossAmountInr ?? 0);
|
|
558
|
+
const applicableRatePercent = isComposite
|
|
559
|
+
? Number(facts.principalSupplyRatePercent || 18.0)
|
|
560
|
+
: Number(facts.highestItemRatePercent || 28.0);
|
|
561
|
+
|
|
562
|
+
const taxAmountInr = roundToPaisa((amountInr * applicableRatePercent) / 100);
|
|
563
|
+
|
|
564
|
+
return {
|
|
565
|
+
status: 'SUCCESS',
|
|
566
|
+
supplyType: isComposite ? 'COMPOSITE_SUPPLY' : 'MIXED_SUPPLY',
|
|
567
|
+
applicableRatePercent,
|
|
568
|
+
taxAmountInr,
|
|
569
|
+
governingSection: 'CGST Act, 2017 Section 8',
|
|
570
|
+
ruleId: ruleAst.sectionId,
|
|
571
|
+
ruleVersion: ruleAst.version,
|
|
572
|
+
isAuthorizedToDisburse: false,
|
|
573
|
+
executionTrace: trace
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Evaluates CGST Section 10 Composition Levy.
|
|
579
|
+
*/
|
|
580
|
+
export function evaluateCompositionLevySection10(ruleAst, facts, trace = []) {
|
|
581
|
+
trace.push('USVM evaluating CGST Section 10 Composition Levy');
|
|
582
|
+
const turnoverInr = Number(facts.aggregateTurnoverInr || 0);
|
|
583
|
+
const isEligible = turnoverInr <= 15000000;
|
|
584
|
+
const businessType = String(facts.businessType || 'TRADER').toUpperCase();
|
|
585
|
+
let ratePercent = 1.0;
|
|
586
|
+
if (businessType === 'RESTAURANT') ratePercent = 5.0;
|
|
587
|
+
else if (businessType === 'SERVICE') ratePercent = 6.0;
|
|
588
|
+
|
|
589
|
+
const compositionTaxInr = isEligible ? roundToPaisa((turnoverInr * ratePercent) / 100) : null;
|
|
590
|
+
|
|
591
|
+
return {
|
|
592
|
+
status: isEligible ? 'COMPOSITION_ELIGIBLE' : 'INELIGIBLE_TURNOVER_EXCEEDED',
|
|
593
|
+
isEligible,
|
|
594
|
+
applicableRatePercent: isEligible ? ratePercent : null,
|
|
595
|
+
compositionTaxInr,
|
|
596
|
+
governingSection: 'CGST Act, 2017 Section 10',
|
|
597
|
+
ruleId: ruleAst.sectionId,
|
|
598
|
+
ruleVersion: ruleAst.version,
|
|
599
|
+
isAuthorizedToDisburse: false,
|
|
600
|
+
executionTrace: trace
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Evaluates CGST Section 34 Credit and Debit Note Timelines.
|
|
606
|
+
*/
|
|
607
|
+
export function evaluateCreditDebitNotesSection34(ruleAst, facts, trace = []) {
|
|
608
|
+
trace.push('USVM evaluating CGST Section 34 Credit Note adjustment timelines');
|
|
609
|
+
const noteDate = String(facts.creditNoteDate || facts.transactionDate || '2025-01-01');
|
|
610
|
+
const cutoffDate = String(facts.cutoffDate || '2025-11-30');
|
|
611
|
+
const isWithinTimelines = noteDate <= cutoffDate;
|
|
612
|
+
|
|
613
|
+
return {
|
|
614
|
+
status: isWithinTimelines ? 'WITHIN_STATUTORY_DEADLINE' : 'EXPIRED_POST_NOVEMBER_CUTOFF',
|
|
615
|
+
isWithinTimelines,
|
|
616
|
+
creditNoteDate: noteDate,
|
|
617
|
+
statutoryCutoffDate: cutoffDate,
|
|
618
|
+
governingSection: 'CGST Act, 2017 Section 34(2)',
|
|
619
|
+
ruleId: ruleAst.sectionId,
|
|
620
|
+
ruleVersion: ruleAst.version,
|
|
621
|
+
isAuthorizedToDisburse: false,
|
|
622
|
+
executionTrace: trace
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
/**
|
|
627
|
+
* Evaluates IGST Section 16 Zero-Rated Export with LUT.
|
|
628
|
+
*/
|
|
629
|
+
export function evaluateExportLutSection16(ruleAst, facts, trace = []) {
|
|
630
|
+
trace.push('USVM evaluating IGST Section 16 export of services under LUT');
|
|
631
|
+
const hasValidLut = facts.hasValidLut !== false;
|
|
632
|
+
const exportAmountInr = Number(facts.exportAmountInr ?? facts.invoiceAmount ?? 0);
|
|
633
|
+
|
|
634
|
+
return {
|
|
635
|
+
status: hasValidLut ? 'ZERO_RATED_LUT_AUTHORIZED' : 'EXPORT_WITH_PAYMENT_REQUIRED',
|
|
636
|
+
hasValidLut,
|
|
637
|
+
exportAmountInr,
|
|
638
|
+
igstPayableInr: hasValidLut ? 0 : roundToPaisa((exportAmountInr * 18) / 100),
|
|
639
|
+
governingSection: 'IGST Act, 2017 Section 16',
|
|
640
|
+
ruleId: ruleAst.sectionId,
|
|
641
|
+
ruleVersion: ruleAst.version,
|
|
642
|
+
isAuthorizedToDisburse: false,
|
|
643
|
+
executionTrace: trace
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Evaluates CGST Rule 48(4) E-Invoicing Mandate.
|
|
649
|
+
*/
|
|
650
|
+
export function evaluateEInvoicingRule48_4(ruleAst, facts, trace = []) {
|
|
651
|
+
trace.push('USVM evaluating CGST Rule 48(4) e-invoicing mandate');
|
|
652
|
+
const turnoverInr = Number(facts.aggregateTurnoverInr || 0);
|
|
653
|
+
const isEInvoicingMandatory = turnoverInr > 50000000; // 5 Cr
|
|
654
|
+
|
|
655
|
+
return {
|
|
656
|
+
status: isEInvoicingMandatory ? 'EINVOICING_MANDATORY_IRN_REQUIRED' : 'EXEMPT_BELOW_TURNOVER_THRESHOLD',
|
|
657
|
+
isEInvoicingMandatory,
|
|
658
|
+
turnoverInr,
|
|
659
|
+
governingSection: 'CGST Rules, 2017 Rule 48(4)',
|
|
660
|
+
ruleId: ruleAst.sectionId,
|
|
661
|
+
ruleVersion: ruleAst.version,
|
|
662
|
+
isAuthorizedToDisburse: false,
|
|
663
|
+
executionTrace: trace
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Evaluates CGST Rule 138 E-Way Bill Consignment Threshold.
|
|
669
|
+
*/
|
|
670
|
+
export function evaluateEWayBillRule138(ruleAst, facts, trace = []) {
|
|
671
|
+
trace.push('USVM evaluating CGST Rule 138 e-way bill threshold');
|
|
672
|
+
const consignmentValueInr = Number(facts.consignmentValueInr ?? facts.invoiceAmount ?? 0);
|
|
673
|
+
const isEWayBillRequired = consignmentValueInr > 50000;
|
|
674
|
+
|
|
675
|
+
return {
|
|
676
|
+
status: isEWayBillRequired ? 'EWAYBILL_GENERATION_MANDATORY' : 'EXEMPT_BELOW_50K_THRESHOLD',
|
|
677
|
+
isEWayBillRequired,
|
|
678
|
+
consignmentValueInr,
|
|
679
|
+
governingSection: 'CGST Rules, 2017 Rule 138',
|
|
680
|
+
ruleId: ruleAst.sectionId,
|
|
681
|
+
ruleVersion: ruleAst.version,
|
|
682
|
+
isAuthorizedToDisburse: false,
|
|
683
|
+
executionTrace: trace
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* Evaluates CGST Section 51 GST TDS Deduction.
|
|
689
|
+
*/
|
|
690
|
+
export function evaluateGstTdsSection51(ruleAst, facts, trace = []) {
|
|
691
|
+
trace.push('USVM evaluating CGST Section 51 GST TDS');
|
|
692
|
+
const contractValueInr = Number(facts.contractValueInr || 0);
|
|
693
|
+
const invoiceAmountInr = Number(facts.invoiceAmount ?? facts.paymentAmountInr ?? 0);
|
|
694
|
+
const isGovernmentRecipient = facts.isGovernmentRecipient === true || facts.isGovernmentDeductor === true;
|
|
695
|
+
const isThresholdBreached = contractValueInr > 250000;
|
|
696
|
+
const isDeductible = isGovernmentRecipient && isThresholdBreached;
|
|
697
|
+
|
|
698
|
+
const cgstTdsInr = isDeductible ? roundToPaisa((invoiceAmountInr * 1) / 100) : 0;
|
|
699
|
+
const sgstTdsInr = isDeductible ? roundToPaisa((invoiceAmountInr * 1) / 100) : 0;
|
|
700
|
+
|
|
701
|
+
return {
|
|
702
|
+
status: isDeductible ? 'GST_TDS_MANDATORY' : 'NOT_APPLICABLE',
|
|
703
|
+
isDeductible,
|
|
704
|
+
cgstTdsInr,
|
|
705
|
+
sgstTdsInr,
|
|
706
|
+
totalGstTdsInr: roundToPaisa(cgstTdsInr + sgstTdsInr),
|
|
707
|
+
governingSection: 'CGST Act, 2017 Section 51',
|
|
708
|
+
ruleId: ruleAst.sectionId,
|
|
709
|
+
ruleVersion: ruleAst.version,
|
|
710
|
+
isAuthorizedToDisburse: false,
|
|
711
|
+
executionTrace: trace
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Evaluates MCA Form MSME-1 Aging & Reporting.
|
|
717
|
+
*/
|
|
718
|
+
export function evaluateMcaMsme1Aging(ruleAst, facts, trace = []) {
|
|
719
|
+
trace.push('USVM evaluating MCA Form MSME-1 45-day overdue aging');
|
|
720
|
+
const res = generateMsme1AndScheduleThreeAging({
|
|
721
|
+
asOfDate: facts.asOfDate || new Date().toISOString().slice(0, 10),
|
|
722
|
+
payables: facts.payables || []
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
return {
|
|
726
|
+
...res,
|
|
727
|
+
ruleId: ruleAst.sectionId,
|
|
728
|
+
ruleVersion: ruleAst.version,
|
|
729
|
+
governingStatute: ruleAst.governingStatute,
|
|
730
|
+
governingSection: ruleAst.statutorySection,
|
|
731
|
+
isAuthorizedToDisburse: false,
|
|
732
|
+
executionTrace: trace
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* Evaluates MSMED Section 22 Annual Disclosures.
|
|
738
|
+
*/
|
|
739
|
+
export function evaluateMsmeDisclosuresSection22(ruleAst, facts, trace = []) {
|
|
740
|
+
trace.push('USVM evaluating MSMED Section 22 balance sheet note disclosures');
|
|
741
|
+
const principalDueInr = Number(facts.principalDueInr ?? facts.unpaidPrincipalInr ?? 0);
|
|
742
|
+
const interestAccruedInr = Number(facts.interestAccruedInr ?? facts.unpaidInterestInr ?? 0);
|
|
743
|
+
|
|
744
|
+
const disclosures = [
|
|
745
|
+
'Principal and interest unpaid as at year end',
|
|
746
|
+
'Interest paid u/s 16 during the year',
|
|
747
|
+
'Interest due and payable for delay without payment u/s 16',
|
|
748
|
+
'Interest accrued and remaining unpaid at end of each accounting year'
|
|
749
|
+
];
|
|
750
|
+
|
|
751
|
+
return {
|
|
752
|
+
status: 'SUCCESS',
|
|
753
|
+
principalDueInr,
|
|
754
|
+
interestAccruedInr,
|
|
755
|
+
disclosuresRequired: disclosures,
|
|
756
|
+
isDisclosureMandatory: true,
|
|
757
|
+
governingSection: 'MSMED Act, 2006 Section 22',
|
|
758
|
+
ruleId: ruleAst.sectionId,
|
|
759
|
+
ruleVersion: ruleAst.version,
|
|
760
|
+
isAuthorizedToDisburse: false,
|
|
761
|
+
executionTrace: trace
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* Evaluates Ind AS 116 Lease Amortization.
|
|
767
|
+
*/
|
|
768
|
+
export function evaluateLeaseAmortizationIndAs116Usvm(ruleAst, facts, trace = []) {
|
|
769
|
+
trace.push('USVM evaluating Ind AS 116 Lease Amortization');
|
|
770
|
+
const res = calculateLeaseAmortizationIndAs116({
|
|
771
|
+
leaseTermMonths: facts.leaseTermMonths || 36,
|
|
772
|
+
annualDiscountRatePercent: facts.annualDiscountRatePercent || 8.5,
|
|
773
|
+
monthlyLeasePaymentInr: facts.monthlyLeasePaymentInr || 100000,
|
|
774
|
+
initialDirectCostsInr: facts.initialDirectCostsInr || 0,
|
|
775
|
+
leaseIncentivesReceivedInr: facts.leaseIncentivesReceivedInr || 0
|
|
776
|
+
});
|
|
777
|
+
|
|
778
|
+
return {
|
|
779
|
+
...res,
|
|
780
|
+
ruleId: ruleAst.sectionId,
|
|
781
|
+
ruleVersion: ruleAst.version,
|
|
782
|
+
governingStatute: ruleAst.governingStatute,
|
|
783
|
+
governingSection: ruleAst.statutorySection,
|
|
784
|
+
isAuthorizedToDisburse: false,
|
|
785
|
+
executionTrace: trace
|
|
786
|
+
};
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* Evaluates Ind AS 115 Revenue Allocation.
|
|
791
|
+
*/
|
|
792
|
+
export function evaluateRevenueAllocationIndAs115Usvm(ruleAst, facts, trace = []) {
|
|
793
|
+
trace.push('USVM evaluating Ind AS 115 Revenue Allocation');
|
|
794
|
+
const res = calculateRevenueAllocationIndAs115({
|
|
795
|
+
transactionPriceInr: facts.transactionPriceInr || 1000000,
|
|
796
|
+
performanceObligations: facts.performanceObligations || [],
|
|
797
|
+
variableConsiderationConstraintInr: facts.variableConsiderationConstraintInr || 0,
|
|
798
|
+
significantFinancingRatePercent: facts.significantFinancingRatePercent || 0,
|
|
799
|
+
financingPeriodMonths: facts.financingPeriodMonths || 0
|
|
800
|
+
});
|
|
801
|
+
|
|
802
|
+
return {
|
|
803
|
+
...res,
|
|
804
|
+
ruleId: ruleAst.sectionId,
|
|
805
|
+
ruleVersion: ruleAst.version,
|
|
806
|
+
governingStatute: ruleAst.governingStatute,
|
|
807
|
+
governingSection: ruleAst.statutorySection,
|
|
808
|
+
isAuthorizedToDisburse: false,
|
|
809
|
+
executionTrace: trace
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
/**
|
|
814
|
+
* Evaluates Ind AS 37 Provisions and Contingencies.
|
|
815
|
+
*/
|
|
816
|
+
export function evaluateProvisionsAndContingenciesIndAs37Usvm(ruleAst, facts, trace = []) {
|
|
817
|
+
trace.push('USVM evaluating Ind AS 37 Provisions & Contingencies');
|
|
818
|
+
const res = evaluateProvisionsAndContingenciesIndAs37({
|
|
819
|
+
obligationType: facts.obligationType || 'LEGAL_DISPUTE',
|
|
820
|
+
probabilityAssessment: facts.probabilityAssessment || 'PROBABLE',
|
|
821
|
+
probabilityPercent: facts.probabilityPercent ?? 75,
|
|
822
|
+
bestEstimateAmountInr: facts.bestEstimateAmountInr || 500000,
|
|
823
|
+
minRangeAmountInr: facts.minRangeAmountInr || 300000,
|
|
824
|
+
maxRangeAmountInr: facts.maxRangeAmountInr || 700000,
|
|
825
|
+
reimbursementExpectedInr: facts.reimbursementExpectedInr || 0,
|
|
826
|
+
discountRatePercent: facts.discountRatePercent || 0,
|
|
827
|
+
timeHorizonYears: facts.timeHorizonYears || 1
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
return {
|
|
831
|
+
...res,
|
|
832
|
+
ruleId: ruleAst.sectionId,
|
|
833
|
+
ruleVersion: ruleAst.version,
|
|
834
|
+
governingStatute: ruleAst.governingStatute,
|
|
835
|
+
governingSection: ruleAst.statutorySection,
|
|
836
|
+
isAuthorizedToDisburse: false,
|
|
837
|
+
executionTrace: trace
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
/**
|
|
842
|
+
* Evaluates Ind AS 21 & 109 Foreign Exchange Revaluation.
|
|
843
|
+
*/
|
|
844
|
+
export function evaluateForeignExchangeRevaluationUsvm(ruleAst, facts, trace = []) {
|
|
845
|
+
trace.push('USVM evaluating Ind AS 21 & 109 Foreign Exchange Revaluation');
|
|
846
|
+
const res = calculateForeignCurrencyIndAs21({
|
|
847
|
+
originalForeignAmount: facts.originalForeignAmount || 10000,
|
|
848
|
+
originalSpotRate: facts.originalSpotRate || 82.5,
|
|
849
|
+
closingSpotRate: facts.closingSpotRate || 83.5,
|
|
850
|
+
isMonetaryItem: facts.isMonetaryItem !== false,
|
|
851
|
+
isHedgingDesignated: facts.isHedgingDesignated === true,
|
|
852
|
+
hedgeEffectivenessRatio: facts.hedgeEffectivenessRatio || 1.0,
|
|
853
|
+
foreignCurrency: facts.foreignCurrency || 'USD'
|
|
854
|
+
});
|
|
855
|
+
|
|
856
|
+
return {
|
|
857
|
+
...res,
|
|
858
|
+
ruleId: ruleAst.sectionId,
|
|
859
|
+
ruleVersion: ruleAst.version,
|
|
860
|
+
governingStatute: ruleAst.governingStatute,
|
|
861
|
+
governingSection: ruleAst.statutorySection,
|
|
862
|
+
isAuthorizedToDisburse: false,
|
|
863
|
+
executionTrace: trace
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* Evaluates Ind AS 109 Expected Credit Loss.
|
|
869
|
+
*/
|
|
870
|
+
export function evaluateExpectedCreditLossIndAs109Usvm(ruleAst, facts, trace = []) {
|
|
871
|
+
trace.push('USVM evaluating Ind AS 109 Expected Credit Loss');
|
|
872
|
+
const res = calculateExpectedCreditLossIndAs109({
|
|
873
|
+
grossCarryingAmountInr: facts.grossCarryingAmountInr || 1000000,
|
|
874
|
+
isCreditImpaired: facts.isCreditImpaired === true,
|
|
875
|
+
isSignificantIncreaseInCreditRisk: facts.isSignificantIncreaseInCreditRisk === true,
|
|
876
|
+
pdStage1Percent: facts.pdStage1Percent || 1.5,
|
|
877
|
+
pdStage2Percent: facts.pdStage2Percent || 5.0,
|
|
878
|
+
lgdPercent: facts.lgdPercent || 40.0,
|
|
879
|
+
forwardLookingMacroFactorPercent: facts.forwardLookingMacroFactorPercent || 1.0
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
return {
|
|
883
|
+
...res,
|
|
884
|
+
ruleId: ruleAst.sectionId,
|
|
885
|
+
ruleVersion: ruleAst.version,
|
|
886
|
+
governingStatute: ruleAst.governingStatute,
|
|
887
|
+
governingSection: ruleAst.statutorySection,
|
|
888
|
+
isAuthorizedToDisburse: false,
|
|
889
|
+
executionTrace: trace
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
/**
|
|
894
|
+
* Evaluates Foreign Tax Credit Relief (IRC §§ 901/904 / DTAA Art 23).
|
|
895
|
+
*/
|
|
896
|
+
export function evaluateForeignTaxCreditRelief(ruleAst, facts, trace = []) {
|
|
897
|
+
trace.push('USVM evaluating Foreign Tax Credit relief limitation');
|
|
898
|
+
const foreignIncomeInr = Number(facts.foreignIncomeInr || 0);
|
|
899
|
+
const foreignTaxPaidInr = Number(facts.foreignTaxPaidInr || 0);
|
|
900
|
+
const domesticTaxOnForeignIncomeInr = Number(facts.domesticTaxOnForeignIncomeInr || 0);
|
|
901
|
+
|
|
902
|
+
const allowableFtcInr = Math.min(foreignTaxPaidInr, domesticTaxOnForeignIncomeInr);
|
|
903
|
+
|
|
904
|
+
return {
|
|
905
|
+
status: 'SUCCESS',
|
|
906
|
+
foreignIncomeInr,
|
|
907
|
+
foreignTaxPaidInr,
|
|
908
|
+
domesticTaxOnForeignIncomeInr,
|
|
909
|
+
allowableForeignTaxCreditInr: allowableFtcInr,
|
|
910
|
+
excessUncreditedForeignTaxInr: Math.max(0, foreignTaxPaidInr - allowableFtcInr),
|
|
911
|
+
governingStatute: 'US IRC §§ 901/904 & Income-tax Act Section 90/91',
|
|
912
|
+
ruleId: ruleAst.sectionId,
|
|
913
|
+
ruleVersion: ruleAst.version,
|
|
914
|
+
isAuthorizedToDisburse: false,
|
|
915
|
+
executionTrace: trace
|
|
916
|
+
};
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
/**
|
|
920
|
+
* Evaluates Section 50B Slump Sale Net Worth & Capital Gains.
|
|
921
|
+
*/
|
|
922
|
+
export function evaluateSlumpSaleSection50B(ruleAst, facts, trace = []) {
|
|
923
|
+
trace.push('USVM evaluating Section 50B Slump Sale Net Worth');
|
|
924
|
+
const slumpSaleConsiderationInr = Number(facts.slumpSaleConsiderationInr ?? facts.invoiceAmount ?? 0);
|
|
925
|
+
const bookValueOfAssetsInr = Number(facts.bookValueOfAssetsInr || 0);
|
|
926
|
+
const liabilitiesInr = Number(facts.liabilitiesInr || 0);
|
|
927
|
+
const netWorthInr = facts.netWorthInr !== undefined
|
|
928
|
+
? Number(facts.netWorthInr)
|
|
929
|
+
: Math.max(0, bookValueOfAssetsInr - liabilitiesInr);
|
|
930
|
+
const capitalGainInr = Math.max(0, slumpSaleConsiderationInr - netWorthInr);
|
|
931
|
+
const isLongTerm = facts.holdingPeriodMonths !== undefined
|
|
932
|
+
? facts.holdingPeriodMonths >= 36
|
|
933
|
+
: (facts.undertakingAgeYears !== undefined ? facts.undertakingAgeYears >= 3 : true);
|
|
934
|
+
|
|
935
|
+
return {
|
|
936
|
+
status: 'SUCCESS',
|
|
937
|
+
slumpSaleConsiderationInr,
|
|
938
|
+
netWorthInr,
|
|
939
|
+
capitalGainInr,
|
|
940
|
+
isLongTermCapitalGain: isLongTerm,
|
|
941
|
+
governingSection: 'Income-tax Act, 1961 Section 50B read with Rule 11UAE',
|
|
942
|
+
ruleId: ruleAst.sectionId,
|
|
943
|
+
ruleVersion: ruleAst.version,
|
|
944
|
+
isAuthorizedToDisburse: false,
|
|
945
|
+
executionTrace: trace
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
/**
|
|
950
|
+
* Evaluates Ind AS 103 Business Combinations.
|
|
951
|
+
*/
|
|
952
|
+
export function evaluateBusinessCombinationsIndAs103Usvm(ruleAst, facts, trace = []) {
|
|
953
|
+
trace.push('USVM evaluating Ind AS 103 Business Combinations');
|
|
954
|
+
const res = calculateBusinessCombinationsIndAs103({
|
|
955
|
+
purchaseConsiderationInr: facts.purchaseConsiderationInr || 10000000,
|
|
956
|
+
fairValueOfNetIdentifiableAssetsInr: facts.fairValueOfNetIdentifiableAssetsInr || 8000000,
|
|
957
|
+
nonControllingInterestValueInr: facts.nonControllingInterestValueInr || 0,
|
|
958
|
+
nciValuationMethod: facts.nciValuationMethod || 'PROPORTIONATE_SHARE',
|
|
959
|
+
previouslyHeldEquityFairValueInr: facts.previouslyHeldEquityFairValueInr || 0,
|
|
960
|
+
acquisitionRelatedCostsInr: facts.acquisitionRelatedCostsInr || 0
|
|
961
|
+
});
|
|
962
|
+
|
|
963
|
+
return {
|
|
964
|
+
...res,
|
|
965
|
+
ruleId: ruleAst.sectionId,
|
|
966
|
+
ruleVersion: ruleAst.version,
|
|
967
|
+
governingStatute: ruleAst.governingStatute,
|
|
968
|
+
governingSection: ruleAst.statutorySection,
|
|
969
|
+
isAuthorizedToDisburse: false,
|
|
970
|
+
executionTrace: trace
|
|
971
|
+
};
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
/**
|
|
975
|
+
* Evaluates Ind AS 36 Impairment of Assets.
|
|
976
|
+
*/
|
|
977
|
+
export function evaluateImpairmentIndAs36Usvm(ruleAst, facts, trace = []) {
|
|
978
|
+
trace.push('USVM evaluating Ind AS 36 Impairment of Assets');
|
|
979
|
+
const res = calculateImpairmentIndAs36({
|
|
980
|
+
carryingAmountCguInr: facts.carryingAmountCguInr || 5000000,
|
|
981
|
+
fairValueLessCostsOfDisposalInr: facts.fairValueLessCostsOfDisposalInr || 4000000,
|
|
982
|
+
valueInUseInr: facts.valueInUseInr || 4500000,
|
|
983
|
+
allocatedGoodwillInr: facts.allocatedGoodwillInr || 500000,
|
|
984
|
+
cguAssetsList: facts.cguAssetsList || []
|
|
985
|
+
});
|
|
986
|
+
|
|
987
|
+
return {
|
|
988
|
+
...res,
|
|
989
|
+
ruleId: ruleAst.sectionId,
|
|
990
|
+
ruleVersion: ruleAst.version,
|
|
991
|
+
governingStatute: ruleAst.governingStatute,
|
|
992
|
+
governingSection: ruleAst.statutorySection,
|
|
993
|
+
isAuthorizedToDisburse: false,
|
|
994
|
+
executionTrace: trace
|
|
995
|
+
};
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
/**
|
|
999
|
+
* Evaluates Ind AS 102 Share-Based Payments (ESOP).
|
|
1000
|
+
*/
|
|
1001
|
+
export function evaluateShareBasedPaymentsIndAs102Usvm(ruleAst, facts, trace = []) {
|
|
1002
|
+
trace.push('USVM evaluating Ind AS 102 Share-Based Payments (ESOP)');
|
|
1003
|
+
const res = calculateEsopAmortizationIndAs102({
|
|
1004
|
+
optionsGrantedCount: facts.optionsGrantedCount || 10000,
|
|
1005
|
+
grantDateFairValuePerOptionInr: facts.grantDateFairValuePerOptionInr || 50,
|
|
1006
|
+
vestingPeriodYears: facts.vestingPeriodYears || 3,
|
|
1007
|
+
expectedForfeitureRatePercent: facts.expectedForfeitureRatePercent || 5,
|
|
1008
|
+
exercisePriceInr: facts.exercisePriceInr || 100,
|
|
1009
|
+
currentMarketPriceInr: facts.currentMarketPriceInr || 150
|
|
1010
|
+
});
|
|
1011
|
+
|
|
1012
|
+
return {
|
|
1013
|
+
...res,
|
|
1014
|
+
ruleId: ruleAst.sectionId,
|
|
1015
|
+
ruleVersion: ruleAst.version,
|
|
1016
|
+
governingStatute: ruleAst.governingStatute,
|
|
1017
|
+
governingSection: ruleAst.statutorySection,
|
|
1018
|
+
isAuthorizedToDisburse: false,
|
|
1019
|
+
executionTrace: trace
|
|
1020
|
+
};
|
|
1021
|
+
}
|