gst_calculator 0.0.3
gst_calculator: ^0.0.3 copied to clipboard
Indian GST calculator for Dart and Flutter. Add or remove GST, split CGST/SGST/IGST, with optional paise-accurate rounding.
GST Calculator #
A lightweight, dependency-free Dart package for Indian GST (Goods and Services Tax) calculations. Works in Flutter apps and pure Dart (server, CLI) on every platform, including the web.
- Add GST to a GST-exclusive price
- Remove GST from a GST-inclusive price
- Split tax into CGST + SGST (intra-state) or IGST (inter-state)
- Optional rounding to paise that keeps invoice lines consistent
- Clear
ArgumentErrors for invalid input
Installation #
dart pub add gst_calculator
or add it to pubspec.yaml:
dependencies:
gst_calculator: ^0.0.3
Usage #
import 'package:gst_calculator/gst_calculator.dart';
Add GST (price excludes GST) #
final result = GstCalculator.addGST(amount: 1000, gstRate: 18);
print(result.cgst); // 90.0
print(result.sgst); // 90.0
print(result.gstAmount); // 180.0
print(result.total); // 1180.0
Remove GST (price includes GST) #
final result = GstCalculator.removeGST(amount: 1180, gstRate: 18);
print(result.baseAmount); // 1000.0
print(result.cgst); // 90.0
print(result.total); // 1180.0 (the amount you passed in)
Inter-state supply (IGST) #
final result = GstCalculator.addGST(
amount: 1000,
gstRate: 18,
isInterState: true,
);
print(result.igst); // 180.0
print(result.cgst); // 0.0
Rounding for invoices #
By default results are unrounded doubles, so they can contain floating point
noise (0.1 at 18% gives a total of 0.11800000000000001) or fractions of a
paisa. Pass fractionDigits to get values ready for an invoice:
final result = GstCalculator.addGST(
amount: 99.99,
gstRate: 5,
fractionDigits: 2,
);
print(result.cgst); // 2.5 (exact value 2.49975)
print(result.sgst); // 2.5
print(result.total); // 104.99
With fractionDigits:
- The input amount is rounded first, and
removeGSTreturns that rounded amount astotal:removeGST(amount: 100.005, gstRate: 18, fractionDigits: 2).totalis100.01. - CGST and SGST are each rounded separately, so they are always equal. IGST is rounded once.
addGSTkeeps the base amount and adds the rounded tax to get the total.removeGSTkeeps the total and subtracts the rounded tax to get the base.baseAmount + gstAmount == totalholds exactly in minor units, for example(r.baseAmount * 100).round() + (r.gstAmount * 100).round() == (r.total * 100).round(). Compare in paise, not with==on doubles, because adding two doubles is not exact.- Rounding is exact and half away from zero. It applies to the amount as
written (its shortest decimal form), so
1.005rounds to1.01even though the nearestdoubleis slightly below 1.005.
fractionDigits must be between 0 and GstCalculator.maxFractionDigits
(6). Use 0 to round to whole rupees. To display a value, format it yourself,
for example result.total.toStringAsFixed(2).
Result #
GstResult has:
| Property | Meaning |
|---|---|
baseAmount |
Taxable value, before GST |
gstRate |
Rate used, as a percentage |
cgst |
Central GST (intra-state only, else 0) |
sgst |
State / UT GST (intra-state only, else 0) |
igst |
Integrated GST (inter-state only, else 0) |
gstAmount |
Total tax: cgst + sgst + igst |
total |
Amount including GST |
It also supports value equality (==) and a readable toString().
Error handling #
Invalid input throws an ArgumentError rather than returning NaN or
Infinity:
try {
GstCalculator.addGST(amount: 100, gstRate: -5);
} on ArgumentError catch (e) {
print(e.message); // Must be a finite, non-negative percentage
}
| Input | Result |
|---|---|
amount is NaN or infinite |
ArgumentError |
gstRate is negative, NaN or infinite |
ArgumentError |
fractionDigits outside 0..6 |
RangeError |
Amount too large to round exactly (fractionDigits set; above ~₹6 × 10¹³ at 2 digits) |
ArgumentError |
addGST total too large for a double (above ~1.8 × 10³⁰⁸) |
ArgumentError |
Negative amount (credit notes, refunds) |
Allowed; tax values are negative |
gstRate of 0 |
Allowed; no tax |
Notes and limitations #
- The rate is not validated against official GST slabs, because slabs change. Pass whatever rate applies to your supply.
- In Union Territories without a legislature, the state component is UTGST.
It is calculated the same way; read it from
sgst. - Compensation cess and TDS/TCS are not calculated.
- Calculations use
double. For totals across very many line items, sum the rounded values in integer paise (for example(result.total * 100).round()) to avoid accumulating error. - This package does arithmetic only and is not tax advice.
Compatibility #
- Dart SDK 2.17 or later (Flutter 3.0 or later).
- No dependencies.
- All calculations are pure, synchronous functions with no shared state,
so they are safe to call from any isolate or widget
buildmethod.
Upgrading #
From 0.0.2 #
The version constraint ^0.0.2 does not allow 0.0.3, so update it to
^0.0.3. Unrounded results are unchanged, except that -0.0 is now 0.0.
Rounded results (fractionDigits set) are now exact, so some change by one
minor unit:
removeGSTrounds exact half-paisa ties up, as documented. Before, some ties rounded down (for example12.39at 18% gave CGST0.94, now0.95).- Very large amounts inside the accepted range are no longer rounded to 15 significant digits.
- Amounts are rounded as written: the
doublejust below1.005(1.0049999999999997) now rounds to1.00.1.005still rounds to1.01.
addGST without fractionDigits now throws an ArgumentError instead of
returning Infinity when the total does not fit in a double.
From 0.0.1 #
Existing code keeps working and returns the same values for valid input. Two things changed:
- Invalid input (
NaNor infinite amounts, negative or non-finite rates) now throws anArgumentError. Before, it silently returnedNaN/Infinity. - The version constraint
^0.0.1does not allow0.0.2, so update it to^0.0.2.