How the Bangladesh বেতনের আয়কর (income tax on salary) calculator is verified

Inputs

InputFieldType
Gross monthly salary (BDT)grossMonthlynumber
Festival and other bonuses for the year (BDT)bonusAnnualnumber
Your provident fund contribution (BDT / month)providentFundMonthlynumber
Other eligible investment for the year (BDT)otherInvestmentAnnualnumber
Your tax-free threshold grouptaxpayerCategorystring
Children or dependants with a disabilitydisabledChildrennumber
First return (new taxpayer: minimum tax ৳1,000)newTaxpayerboolean

The formula

Each derived value below is computed by the Valem engine from the expression shown, in this order. Nothing else runs — there is no hidden code path.

Derived valueFieldFormula (JSONata)
Salary for the yeargrossAnnual$round($n(grossMonthly) * 12 + $n(bonusAnnual), 2)
Exempt: 1/3, at most ৳5,00,000salaryExemption$round($min([grossAnnual / $const.salaryExemptionDivisor, $const.salaryExemptionCap]), 2)
Taxable incometaxableIncome$round($max([0, grossAnnual - salaryExemption]), 2)
Tax-free thresholdtaxFreeThreshold($c := taxpayerCategory; $c = 'womanOrSenior' ? $const.taxFreeWomanSenior : ($c = 'disabledOrThirdGender' ? $const.taxFreeDisabledThirdGender : ($c = 'warWounded' ? $const.taxFreeWarWounded : $const.taxFreeGeneral))) + $n(disabledChildren) * $const.disabledChildAddOn
Tax at the Schedule 2 ratesslabTax($t := taxFreeThreshold; $w1 := $t + $const.bandWidth1; $w2 := $w1 + $const.bandWidth2; $w3 := $w2 + $const.bandWidth3; $w4 := $w3 + $const.bandWidth4; $round($bandedCharge(taxableIncome, [{"upTo": $t, "rate": $const.rate0}, {"upTo": $w1, "rate": $const.rate1}, {"upTo": $w2, "rate": $const.rate2}, {"upTo": $w3, "rate": $const.rate3}, {"upTo": $w4, "rate": $const.rate4}, {"upTo": null, "rate": $const.rate5}]), 2))
Eligible InvestmenteligibleInvestment$round($n(providentFundMonthly) * 12 + $n(otherInvestmentAnnual), 2)
Investment rebate (s.78)investmentRebate$round($min([taxableIncome * $const.rebateIncomeRate, eligibleInvestment * $const.rebateInvestmentRate, $const.rebateCap, slabTax]), 2)
Income tax for the yearincomeTaxAnnualtaxableIncome > taxFreeThreshold ? $round($max([slabTax - investmentRebate, newTaxpayer ? $const.minimumTaxNewTaxpayer : $const.minimumTax]), 2) : 0
Income tax / monthincomeTaxMonthly$round(incomeTaxAnnual / 12, 2)
Take-home for the yearnetAnnual$round($max([0, grossAnnual - incomeTaxAnnual - $n(providentFundMonthly) * 12]), 2)
Net / monthnetMonthly$round(netAnnual / 12, 2)

Rates and thresholds

The expressions above read these as $const. They are the figures the annual refresh replaces, so they live as data rather than being written into the formulas — which is what makes a year-on-year change a one-line diff instead of an edit to arithmetic.

ConstantValue
salaryExemptionDivisor3
salaryExemptionCap500000
taxFreeGeneral400000
taxFreeWomanSenior450000
taxFreeDisabledThirdGender525000
taxFreeWarWounded550000
bandWidth1300000
bandWidth2400000
bandWidth3500000
bandWidth42000000
rate00
rate10.1
rate20.15
rate30.2
rate40.25
rate50.3
minimumTax5000
minimumTaxNewTaxpayer1000
disabledChildAddOn50000
rebateIncomeRate0.03
rebateInvestmentRate0.1
rebateCap750000

Test vectors (12)

Every case is executed against this model on each build, by the Java engine and independently by a JavaScript one. A mismatch of a single cent fails the build, so the page cannot ship advertising a figure the model no longer produces.

Case 1 — N1 ৳1,00,000 a month, ৳5,000 PF and ৳40,000 other investment: tax ৳45,000 less the ৳10,000 rebate

given grossMonthly100000
given bonusAnnual0
given providentFundMonthly5000
given otherInvestmentAnnual40000
given taxpayerCategorygeneral
given disabledChildren0
given newTaxpayerno
expect taxableIncome800000
expect slabTax45000
expect investmentRebate10000
expect incomeTaxAnnual35000
expect netMonthly92083.33

Case 2 — N1b same: exemption, eligible investment, year totals

given grossMonthly100000
given bonusAnnual0
given providentFundMonthly5000
given otherInvestmentAnnual40000
given taxpayerCategorygeneral
given disabledChildren0
given newTaxpayerno
expect grossAnnual1200000
expect salaryExemption400000
expect eligibleInvestment100000
expect netAnnual1105000
expect incomeTaxMonthly2916.67

Case 3 — N2 ৳1,00,000 a month, no investment: ৳30,000 + ৳15,000

given grossMonthly100000
given bonusAnnual0
given providentFundMonthly0
given otherInvestmentAnnual0
given taxpayerCategorygeneral
given disabledChildren0
given newTaxpayerno
expect incomeTaxAnnual45000
expect netMonthly96250

Case 4 — N3 ৳50,000 a month: ৳4,00,000 taxable does not exceed the threshold

given grossMonthly50000
given bonusAnnual0
given providentFundMonthly0
given otherInvestmentAnnual0
given taxpayerCategorygeneral
given disabledChildren0
given newTaxpayerno
expect taxableIncome400000
expect incomeTaxAnnual0
expect netMonthly50000

Case 5 — N4 ৳52,000 a month: ৳1,600 at 10% is lifted to the ৳5,000 minimum

given grossMonthly52000
given bonusAnnual0
given providentFundMonthly0
given otherInvestmentAnnual0
given taxpayerCategorygeneral
given disabledChildren0
given newTaxpayerno
expect taxableIncome416000
expect slabTax1600
expect incomeTaxAnnual5000

Case 6 — N5 same as a new taxpayer: minimum ৳1,000

given grossMonthly52000
given bonusAnnual0
given providentFundMonthly0
given otherInvestmentAnnual0
given taxpayerCategorygeneral
given disabledChildren0
given newTaxpayeryes
expect incomeTaxAnnual1600

Case 7 — N5b new taxpayer at ৳51,000 a month: ৳400 lifted to ৳1,000

given grossMonthly51000
given bonusAnnual0
given providentFundMonthly0
given otherInvestmentAnnual0
given taxpayerCategorygeneral
given disabledChildren0
given newTaxpayeryes
expect taxableIncome408000
expect slabTax800
expect incomeTaxAnnual1000

Case 8 — N6 woman or 65+: threshold ৳4,50,000, tax ৳30,000 + ৳7,500

given grossMonthly100000
given bonusAnnual0
given providentFundMonthly0
given otherInvestmentAnnual0
given taxpayerCategorywomanOrSenior
given disabledChildren0
given newTaxpayerno
expect taxFreeThreshold450000
expect incomeTaxAnnual37500

Case 9 — N7 disability, two disabled children: threshold ৳6,25,000, 10% of ৳1,75,000

given grossMonthly100000
given bonusAnnual0
given providentFundMonthly0
given otherInvestmentAnnual0
given taxpayerCategorydisabledOrThirdGender
given disabledChildren2
given newTaxpayerno
expect taxFreeThreshold625000
expect incomeTaxAnnual17500

Case 10 — N8 war-wounded freedom fighter: threshold ৳5,50,000, 10% of ৳2,50,000

given grossMonthly100000
given bonusAnnual0
given providentFundMonthly0
given otherInvestmentAnnual0
given taxpayerCategorywarWounded
given disabledChildren0
given newTaxpayerno
expect taxFreeThreshold550000
expect incomeTaxAnnual25000

Case 11 — N9 ৳5,00,000 a month: exemption capped at ৳5 lakh, ৳6,90,000 + 30% of ৳19,00,000, rebate 3% of income

given grossMonthly500000
given bonusAnnual0
given providentFundMonthly0
given otherInvestmentAnnual2000000
given taxpayerCategorygeneral
given disabledChildren0
given newTaxpayerno
expect salaryExemption500000
expect taxableIncome5500000
expect slabTax1260000
expect investmentRebate165000
expect incomeTaxAnnual1095000

Case 12 — N10 ৳30,00,000 a month: the rebate stops at ৳7,50,000

given grossMonthly3000000
given bonusAnnual0
given providentFundMonthly0
given otherInvestmentAnnual10000000
given taxpayerCategorygeneral
given disabledChildren0
given newTaxpayerno
expect slabTax10260000
expect investmentRebate750000
expect incomeTaxAnnual9510000

Sources

Check it yourself — and reuse it

The whole model as JSON — inputs, outputs, formulas, vectors and sources in one re-runnable document.

This model is published under CC BY 4.0: use it, adapt it, build on it, with attribution. The licence covers the model — the expression of each rule and the arrangement of the catalog. The rates and thresholds are law, and nobody licenses those; the sources above are where they come from.

← Back to the Bangladesh বেতনের আয়কর (income tax on salary) calculator

Built with Valem — a live, verifiable calculator you can fork and embed.