{
  "$comment": "Machine-readable companion to https://valem.run/calculators/bangladesh/self-employed. Formula, inputs, outputs, engine-verified test vectors, cited sources and the re-runnable Valem ModelSpec behind the page.",
  "url": "https://valem.run/calculators/bangladesh/self-employed",
  "dataUrl": "https://valem.run/calculators/bangladesh/self-employed.json",
  "license": {
    "name": "CC BY 4.0",
    "url": "https://creativecommons.org/licenses/by/4.0/",
    "attribution": "Bangladesh ব্যবসার আয়কর (business income tax) model by Valem (https://valem.run/calculators/bangladesh/self-employed), CC BY 4.0.",
    "note": "Covers the model — the expression of each rule and the arrangement of the catalog. The rates and thresholds themselves are law and are not licensed by anyone; the cited sources are where they come from."
  },
  "verificationUrl": "https://valem.run/calculators/bangladesh/self-employed/verify",
  "country": "bangladesh",
  "countryName": "Bangladesh",
  "formula": "self-employed",
  "formulaName": "Business income tax",
  "localName": "ব্যবসার আয়কর",
  "localLang": "bn",
  "englishName": "Business income tax",
  "title": "ব্যবসার আয়কর Bangladesh 2026-27 — self-employed tax calculator",
  "answer": "A self-employed individual in Bangladesh pays the larger of two figures: income tax on profit at the Finance Act 2026 rates — nothing on the first ৳4 lakh (more for some groups), then 10% rising to 30%, at least ৳5,000 once profit passes the threshold — and a turnover tax of 1% of gross receipts, which applies even with a loss; listed ICT and freelancing income received wholly by bank transfer is exempt from both until 30 June 2027.",
  "lang": "en",
  "currency": "BDT",
  "taxYear": "2026-27",
  "verification": {
    "claim": "internal-consistency",
    "statement": "The Valem engine reproduces this model's stated formula through 11 self-test cases (below, and re-runnable against the spec). That asserts internal consistency, NOT that the formula matches current law — the cited sources are the evidence for that, and carry the date each was last checked.",
    "selfTestCases": 11,
    "ratesAreIllustrative": false,
    "sourcesCheckedOn": "2026-11-01"
  },
  "sources": [
    {
      "label": "Finance Act 2026 (Act 96), s.160 and Schedule 2 Part 1 para (ক): 2026-27 and 2027-28 rates",
      "url": "https://bdlaws.minlaw.gov.bd/upload/act/2026-08-17-10-27-29-%E0%A6%A4%E0%A6%AB%E0%A6%B8%E0%A6%BF%E0%A6%B2_Act-No-96.pdf",
      "checked": "2026-11-01"
    },
    {
      "label": "ITA 2023 Sixth Schedule Pt 1 para 21: ICT and freelancing exempt (Act 96 s.157(খ))",
      "url": "https://bdlaws.minlaw.gov.bd/act-1725/section-59531.html",
      "checked": "2026-11-01"
    },
    {
      "label": "Income Tax Act 2023 s.163(6) turnover tax (substituted by the Finance Act 2026, s.91)",
      "url": "https://bdlaws.minlaw.gov.bd/act-1429/section-51993.html",
      "checked": "2026-11-01"
    },
    {
      "label": "Finance Act 2026, Bangladesh Gazette 30 June 2026 (NBR copy)",
      "url": "https://nbr.gov.bd/uploads/acts/Finance_Act_2026.pdf",
      "checked": "2026-11-01"
    }
  ],
  "terminalOutput": "netIncome",
  "headlineOutput": "netIncome",
  "inputs": [
    {
      "name": "annualTurnover",
      "type": "number",
      "label": "Gross receipts for the year (BDT)",
      "minimum": 0
    },
    {
      "name": "annualExpenses",
      "type": "number",
      "label": "Allowable business expenses (BDT)",
      "minimum": 0
    },
    {
      "name": "taxpayerCategory",
      "type": "string",
      "label": "Your tax-free threshold group",
      "enum": [
        "general",
        "womanOrSenior",
        "disabledOrThirdGender",
        "warWounded"
      ]
    },
    {
      "name": "disabledChildren",
      "type": "number",
      "label": "Children or dependants with a disability",
      "minimum": 0,
      "maximum": 20
    },
    {
      "name": "newTaxpayer",
      "type": "boolean",
      "label": "First return (new taxpayer: minimum tax ৳1,000)"
    },
    {
      "name": "ictExempt",
      "type": "boolean",
      "label": "All of it is ICT or freelancing income received by bank transfer (Sixth Schedule para 21, to 30 June 2027)"
    }
  ],
  "outputs": [
    {
      "name": "taxableIncome",
      "type": "number",
      "label": "Business income (receipts − expenses)",
      "format": "currency",
      "formula": "$round($max([0, $n(annualTurnover) - $n(annualExpenses)]), 2)"
    },
    {
      "name": "taxFreeThreshold",
      "type": "number",
      "label": "Tax-free threshold",
      "format": "currency",
      "formula": "($c := taxpayerCategory; $c = 'womanOrSenior' ? $const.taxFreeWomanSenior : ($c = 'disabledOrThirdGender' ? $const.taxFreeDisabledThirdGender : ($c = 'warWounded' ? $const.taxFreeWarWounded : $const.taxFreeGeneral))) + $n(disabledChildren) * $const.disabledChildAddOn"
    },
    {
      "name": "slabTax",
      "type": "number",
      "label": "Tax at the Schedule 2 rates",
      "format": "currency",
      "formula": "ictExempt ? 0 : ($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))"
    },
    {
      "name": "turnoverTax",
      "type": "number",
      "label": "Turnover tax: 1% of receipts",
      "format": "currency",
      "formula": "ictExempt ? 0 : $round($n(annualTurnover) * $const.turnoverTaxRate, 2)"
    },
    {
      "name": "regularTax",
      "type": "number",
      "formula": "(ictExempt or taxableIncome <= taxFreeThreshold) ? 0 : $round($max([slabTax, newTaxpayer ? $const.minimumTaxNewTaxpayer : $const.minimumTax]), 2)"
    },
    {
      "name": "incomeTax",
      "type": "number",
      "label": "Income tax",
      "format": "currency",
      "formula": "$round($max([regularTax, turnoverTax]), 2)"
    },
    {
      "name": "turnoverTaxCarryForward",
      "type": "number",
      "label": "Turnover tax above the ordinary tax, carried forward",
      "format": "currency",
      "formula": "$round($max([0, turnoverTax - regularTax]), 2)"
    },
    {
      "name": "netIncome",
      "type": "number",
      "label": "Profit after tax (৳0 at a loss)",
      "format": "currency",
      "formula": "$round($max([0, taxableIncome - incomeTax]), 2)"
    }
  ],
  "testCases": [
    {
      "description": "S1 ৳30 lakh receipts, ৳18 lakh expenses: ৳12 lakh profit, tax ৳30,000 + ৳60,000 + ৳20,000",
      "given": {
        "annualTurnover": 3000000,
        "annualExpenses": 1800000,
        "taxpayerCategory": "general",
        "disabledChildren": 0,
        "newTaxpayer": false,
        "ictExempt": false
      },
      "expect": {
        "taxableIncome": 1200000,
        "slabTax": 110000,
        "turnoverTax": 30000,
        "incomeTax": 110000,
        "netIncome": 1090000
      }
    },
    {
      "description": "S2 thin margin: ৳1 crore receipts, ৳5 lakh profit, turnover tax ৳1,00,000 exceeds ৳10,000",
      "given": {
        "annualTurnover": 10000000,
        "annualExpenses": 9500000,
        "taxpayerCategory": "general",
        "disabledChildren": 0,
        "newTaxpayer": false,
        "ictExempt": false
      },
      "expect": {
        "slabTax": 10000,
        "turnoverTax": 100000,
        "incomeTax": 100000,
        "turnoverTaxCarryForward": 90000,
        "netIncome": 400000
      }
    },
    {
      "description": "S3 profit below the threshold: turnover tax ৳10,000 still due",
      "given": {
        "annualTurnover": 1000000,
        "annualExpenses": 700000,
        "taxpayerCategory": "general",
        "disabledChildren": 0,
        "newTaxpayer": false,
        "ictExempt": false
      },
      "expect": {
        "taxableIncome": 300000,
        "slabTax": 0,
        "regularTax": 0,
        "incomeTax": 10000,
        "turnoverTaxCarryForward": 10000
      }
    },
    {
      "description": "S4 a loss: turnover tax applies regardless; profit after tax floored at 0",
      "given": {
        "annualTurnover": 2000000,
        "annualExpenses": 2500000,
        "taxpayerCategory": "general",
        "disabledChildren": 0,
        "newTaxpayer": false,
        "ictExempt": false
      },
      "expect": {
        "taxableIncome": 0,
        "incomeTax": 20000,
        "netIncome": 0
      }
    },
    {
      "description": "S5 ৳4,20,000 profit on ৳4,50,000 receipts: ৳2,000 lifted to the ৳5,000 minimum",
      "given": {
        "annualTurnover": 450000,
        "annualExpenses": 30000,
        "taxpayerCategory": "general",
        "disabledChildren": 0,
        "newTaxpayer": false,
        "ictExempt": false
      },
      "expect": {
        "slabTax": 2000,
        "turnoverTax": 4500,
        "incomeTax": 5000
      }
    },
    {
      "description": "S6 same as a new taxpayer: turnover tax ৳4,500 exceeds the ৳2,000 and the ৳1,000 minimum",
      "given": {
        "annualTurnover": 450000,
        "annualExpenses": 30000,
        "taxpayerCategory": "general",
        "disabledChildren": 0,
        "newTaxpayer": true,
        "ictExempt": false
      },
      "expect": {
        "incomeTax": 4500
      }
    },
    {
      "description": "S7 woman or 65+: threshold ৳4,50,000, tax ৳1,00,000",
      "given": {
        "annualTurnover": 3000000,
        "annualExpenses": 1800000,
        "taxpayerCategory": "womanOrSenior",
        "disabledChildren": 0,
        "newTaxpayer": false,
        "ictExempt": false
      },
      "expect": {
        "taxFreeThreshold": 450000,
        "incomeTax": 100000
      }
    },
    {
      "description": "S8 ৳1 crore profit: ৳6,90,000 + 30% of ৳64,00,000",
      "given": {
        "annualTurnover": 50000000,
        "annualExpenses": 40000000,
        "taxpayerCategory": "general",
        "disabledChildren": 0,
        "newTaxpayer": false,
        "ictExempt": false
      },
      "expect": {
        "slabTax": 2610000,
        "incomeTax": 2610000,
        "netIncome": 7390000
      }
    },
    {
      "description": "S9 ICT or freelancing income received by bank transfer: exempt, no turnover tax (para 21)",
      "given": {
        "annualTurnover": 3000000,
        "annualExpenses": 1800000,
        "taxpayerCategory": "general",
        "disabledChildren": 0,
        "newTaxpayer": false,
        "ictExempt": true
      },
      "expect": {
        "slabTax": 0,
        "turnoverTax": 0,
        "incomeTax": 0,
        "netIncome": 1200000
      }
    },
    {
      "description": "S10 two disabled children: threshold ৳5,00,000, tax ৳30,000 + ৳60,000",
      "given": {
        "annualTurnover": 3000000,
        "annualExpenses": 1800000,
        "taxpayerCategory": "general",
        "disabledChildren": 2,
        "newTaxpayer": false,
        "ictExempt": false
      },
      "expect": {
        "taxFreeThreshold": 500000,
        "incomeTax": 90000
      }
    },
    {
      "description": "S11 default: the ordinary tax exceeds the turnover tax, nothing carried forward",
      "given": {
        "annualTurnover": 3000000,
        "annualExpenses": 1800000,
        "taxpayerCategory": "general",
        "disabledChildren": 0,
        "newTaxpayer": false,
        "ictExempt": false
      },
      "expect": {
        "regularTax": 110000,
        "turnoverTaxCarryForward": 0
      }
    }
  ],
  "spec": {
    "id": "self-employed-bangladesh",
    "version": "1.0.0",
    "schema": {
      "type": "object",
      "properties": {
        "annualTurnover": {
          "type": "number",
          "minimum": 0
        },
        "annualExpenses": {
          "type": "number",
          "minimum": 0
        },
        "taxpayerCategory": {
          "type": "string",
          "enum": [
            "general",
            "womanOrSenior",
            "disabledOrThirdGender",
            "warWounded"
          ]
        },
        "disabledChildren": {
          "type": "number",
          "minimum": 0,
          "maximum": 20
        },
        "newTaxpayer": {
          "type": "boolean"
        },
        "ictExempt": {
          "type": "boolean"
        },
        "taxableIncome": {
          "type": "number",
          "readOnly": true
        },
        "taxFreeThreshold": {
          "type": "number",
          "readOnly": true
        },
        "slabTax": {
          "type": "number",
          "readOnly": true
        },
        "turnoverTax": {
          "type": "number",
          "readOnly": true
        },
        "regularTax": {
          "type": "number",
          "readOnly": true
        },
        "incomeTax": {
          "type": "number",
          "readOnly": true
        },
        "turnoverTaxCarryForward": {
          "type": "number",
          "readOnly": true
        },
        "netIncome": {
          "type": "number",
          "readOnly": true
        }
      }
    },
    "constants": {
      "taxFreeGeneral": 400000,
      "taxFreeWomanSenior": 450000,
      "taxFreeDisabledThirdGender": 525000,
      "taxFreeWarWounded": 550000,
      "bandWidth1": 300000,
      "bandWidth2": 400000,
      "bandWidth3": 500000,
      "bandWidth4": 2000000,
      "rate0": 0,
      "rate1": 0.1,
      "rate2": 0.15,
      "rate3": 0.2,
      "rate4": 0.25,
      "rate5": 0.3,
      "minimumTax": 5000,
      "minimumTaxNewTaxpayer": 1000,
      "disabledChildAddOn": 50000,
      "turnoverTaxRate": 0.01
    },
    "library": {
      "layers": [
        {
          "id": "statutory",
          "define": "(\n  /* Shared statutory helpers — the canonical copy (docs/sandbox/d8-statutory-families.md §5.4).\n     DO NOT EDIT A SPEC'S INLINED COPY. Edit this file and run `npm run sync:helpers`; a vitest\n     assertion and a Java assertion both require every inlined copy to be byte-identical to this one.\n\n     Why inlined rather than referenced: the `library` section's `ref` form — a library shared\n     between models — is still proposed, gated on the model-references design (see\n     ../../../../docs/design/library/jsonata-library.md). Inlining keeps each spec self-contained,\n     which is what lets `#e=` embedding, `#share=` import and MCP forking work with no resolver.\n\n     TWO TRAPS, both of which fail SILENTLY and both of which bit during the debt-payoff build:\n\n       1. A library function sees ONLY its arguments. It cannot read the consuming document — not\n          through a bare field name, not through `$`, not through `$$`. Everything these helpers\n          need is passed in. (`$const` is late-bound and so would resolve, but relying on it would\n          couple a shared helper to one spec's constant names.)\n       2. ONE null member wrecks a whole aggregate, and the two engines disagree about how. The JS\n          reference implementation THROWS (\"Argument 1 of function sum must be an array of\n          numbers\"); the Java port can instead yield null for the entire aggregate. Neither gives a\n          partial total, and the null-yielding form is the dangerous one because it is silent. So\n          callers coerce with `$n()` below before aggregating, which makes the behaviour identical\n          in both engines — measured, not assumed: see helpers.test.ts.\n\n       3. A PATH STEP DIRECTLY ON A CALL RESULT RETURNS NOTHING in the Java engine. This matters for\n          every caller of $amortize, which is the one helper here returning an object:\n\n              $amortize(p, r, n, 0).months            -> empty in Java, 360 in JS.  WRONG\n              ($a := $amortize(p, r, n, 0); $a.months) -> 360 in both.               RIGHT\n\n          Bind the result to a variable, then step into it. The JS reference accepts both forms, so\n          this is invisible until the page is served by the real engine, and it fails as a blank\n          field rather than an error. Measured with a probe, not inferred — the field simply does\n          not appear. */\n\n  /* Number coercion with an explicit zero default. The guard against trap 2. */\n  $n := function($v) { $v = null or $not($exists($v)) ? 0 : $number($v) };\n\n  /* ISO date -> its year / month / day parts. String slicing rather than $fromMillis formatting:\n     these are statutory dates (\"2026-04-06\"), and a timezone-sensitive round-trip through millis\n     can shift the day, which silently moves a service anniversary across a band boundary. */\n  $isoY := function($d) { $number($substring($d, 0, 4)) };\n  $isoM := function($d) { $number($substring($d, 5, 2)) };\n  $isoD := function($d) { $number($substring($d, 8, 2)) };\n\n  /* Whole years of completed service between two ISO dates. Counts an anniversary as reached only\n     when the month-and-day has arrived, which is what \"completed years of service\" means in every\n     severance statute — not a 365.25-day division, whose drift crosses a 5-year band boundary in\n     the wrong direction roughly one year in four. */\n  $yearsBetween := function($from, $to) { (\n    $y := $isoY($to) - $isoY($from);\n    $beforeAnniversary := $isoM($to) < $isoM($from)\n      or ($isoM($to) = $isoM($from) and $isoD($to) < $isoD($from));\n    $beforeAnniversary ? $y - 1 : $y\n  ) };\n\n  /* Whole completed months between two ISO dates, same convention. */\n  $monthsBetween := function($from, $to) { (\n    $m := ($isoY($to) - $isoY($from)) * 12 + ($isoM($to) - $isoM($from));\n    $isoD($to) < $isoD($from) ? $m - 1 : $m\n  ) };\n\n  /* Inclusive count of days between two ISO dates — both endpoints counted, because a leave year\n     runs from its first day to its last and an employee present on both is present for both.\n     Pro-rata accrual is then $proRataDays(a, b) / $proRataDays(yearStart, yearEnd). */\n  $proRataDays := function($from, $to) {\n    ($toMillis($to) - $toMillis($from)) / 86400000 + 1\n  };\n\n  /* Progressive charge across bands. `$bands` is ordered lowest-first, each {\"upTo\": n, \"rate\": r};\n     the final band's `upTo` is omitted or null to mean \"no ceiling\". Each band's rate applies ONLY\n     to the slice of the amount inside it — the single most common error in a hand-written bracket\n     walk is applying the top rate to the whole amount. Returns 0 for a non-positive amount. */\n  $bandedCharge := function($amount, $bands) { (\n    $a := $n($amount);\n    $a <= 0 ? 0 : $reduce($bands, function($acc, $band) { (\n      $ceiling := $exists($band.upTo) and $band.upTo != null ? $band.upTo : $a;\n      $top := $ceiling < $a ? $ceiling : $a;\n      $slice := $top - $acc.floor;\n      {\n        \"floor\": $top > $acc.floor ? $top : $acc.floor,\n        \"charge\": $acc.charge + ($slice > 0 ? $slice * $n($band.rate) : 0)\n      }\n    ) }, {\"floor\": 0, \"charge\": 0}).charge\n  ) };\n\n  /* Clamp into [floor, cap]. Either bound may be omitted (null) to leave that side open — a benefit\n     with a cap and no floor is as common as one with both. */\n  $clampFloorCap := function($value, $floor, $cap) { (\n    $v := $n($value);\n    $withFloor := $exists($floor) and $floor != null and $v < $floor ? $floor : $v;\n    $exists($cap) and $cap != null and $withFloor > $cap ? $cap : $withFloor\n  ) };\n\n  /* Level annuity payment for a principal over `$months` at `$annualRatePct` nominal, compounded\n     monthly. Falls back to straight-line division at a zero rate, where the standard formula\n     divides by zero. */\n  $annuityPayment := function($principal, $annualRatePct, $months) { (\n    $p := $n($principal);\n    $m := $n($months);\n    $i := $n($annualRatePct) / 1200;\n    $m <= 0 ? 0 : ($i = 0 ? $p / $m : $p * $i * $power(1 + $i, $m) / ($power(1 + $i, $m) - 1))\n  ) };\n\n  /* Amortisation schedule: one row per month until the balance clears or `$months` is reached.\n     Returns {\"payment\", \"months\", \"totalInterest\", \"schedule\": [{month, interest, principal,\n     balance}]}. `$extra` is an optional monthly overpayment.\n\n     A real month-by-month fold rather than a closed form, because an overpayment changes every\n     later row — the same reason debt-payoff simulates. Bounded by `$months`, so it always\n     terminates. */\n  $amortize := function($principal, $annualRatePct, $months, $extra) { (\n    $i := $n($annualRatePct) / 1200;\n    $pay := $annuityPayment($principal, $annualRatePct, $months) + $n($extra);\n    $r := $reduce([1..$n($months)], function($acc, $month) {\n      $acc.balance <= 0 ? $acc : (\n        /* The running balance is kept UNROUNDED and only the emitted row is rounded. Rounding the\n           balance each month instead accumulates drift: at 200,000 over 360 months it left 2.83\n           still owing in the final row, which would break the \"final balance is zero\" invariant\n           (§7.3) and look to a reader like the schedule does not pay the loan off. Lenders compute\n           on the exact balance and adjust the last payment, which is what this does. */\n        $interest := $acc.balance * $i;\n        $due := $acc.balance + $interest < $pay ? $acc.balance + $interest : $pay;\n        $principalPart := $due - $interest;\n        $balance := $acc.balance - $principalPart;\n        {\n          \"balance\": $balance,\n          \"totalInterest\": $acc.totalInterest + $interest,\n          \"schedule\": $append($acc.schedule, [{\n            \"month\": $month,\n            \"interest\": $round($interest, 2),\n            \"principal\": $round($principalPart, 2),\n            \"balance\": $round($balance, 2)\n          }])\n        }\n      )\n    }, {\"balance\": $n($principal), \"totalInterest\": 0, \"schedule\": []});\n    {\n      \"payment\": $round($pay, 2),\n      \"months\": $count($r.schedule),\n      \"totalInterest\": $round($r.totalInterest, 2),\n      \"schedule\": [$r.schedule]\n    }\n  ) };\n\n  [\"n\", \"isoY\", \"isoM\", \"isoD\", \"yearsBetween\", \"monthsBetween\", \"proRataDays\",\n   \"bandedCharge\", \"clampFloorCap\", \"annuityPayment\", \"amortize\"]\n)\n"
        }
      ]
    },
    "defaultValues": [
      {
        "path": "$",
        "expr": "{ 'annualTurnover': 3000000, 'annualExpenses': 1800000, 'taxpayerCategory': 'general', 'disabledChildren': 0, 'newTaxpayer': false, 'ictExempt': false }"
      }
    ],
    "derivations": [
      {
        "path": "$.taxableIncome",
        "expr": "$round($max([0, $n(annualTurnover) - $n(annualExpenses)]), 2)"
      },
      {
        "path": "$.taxFreeThreshold",
        "expr": "($c := taxpayerCategory; $c = 'womanOrSenior' ? $const.taxFreeWomanSenior : ($c = 'disabledOrThirdGender' ? $const.taxFreeDisabledThirdGender : ($c = 'warWounded' ? $const.taxFreeWarWounded : $const.taxFreeGeneral))) + $n(disabledChildren) * $const.disabledChildAddOn"
      },
      {
        "path": "$.slabTax",
        "expr": "ictExempt ? 0 : ($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))"
      },
      {
        "path": "$.turnoverTax",
        "expr": "ictExempt ? 0 : $round($n(annualTurnover) * $const.turnoverTaxRate, 2)"
      },
      {
        "path": "$.regularTax",
        "expr": "(ictExempt or taxableIncome <= taxFreeThreshold) ? 0 : $round($max([slabTax, newTaxpayer ? $const.minimumTaxNewTaxpayer : $const.minimumTax]), 2)"
      },
      {
        "path": "$.incomeTax",
        "expr": "$round($max([regularTax, turnoverTax]), 2)"
      },
      {
        "path": "$.turnoverTaxCarryForward",
        "expr": "$round($max([0, turnoverTax - regularTax]), 2)"
      },
      {
        "path": "$.netIncome",
        "expr": "$round($max([0, taxableIncome - incomeTax]), 2)"
      }
    ],
    "constraints": [],
    "viewDefinition": {
      "renderer": "builtin",
      "defaultView": "main",
      "views": [
        {
          "id": "main",
          "label": "Business income tax",
          "layout": "vertical",
          "components": [
            {
              "id": "turnover",
              "type": "numericField",
              "label": "Gross receipts for the year (BDT)",
              "bind": "$.annualTurnover",
              "helperText": "Sales or fees, excluding VAT and supplementary duty."
            },
            {
              "id": "expenses",
              "type": "numericField",
              "label": "Allowable business expenses (BDT)",
              "bind": "$.annualExpenses"
            },
            {
              "id": "category",
              "type": "selectField",
              "label": "Your tax-free threshold group",
              "bind": "$.taxpayerCategory",
              "options": [
                {
                  "value": "general",
                  "label": "Not in a group below"
                },
                {
                  "value": "womanOrSenior",
                  "label": "Woman, or aged 65 or over (৳4,50,000)"
                },
                {
                  "value": "disabledOrThirdGender",
                  "label": "Person with a disability, or third gender (৳5,25,000)"
                },
                {
                  "value": "warWounded",
                  "label": "Gazetted war-wounded freedom fighter or injured July fighter (৳5,50,000)"
                }
              ]
            },
            {
              "id": "children",
              "type": "numericField",
              "label": "Children or dependants with a disability",
              "bind": "$.disabledChildren",
              "helperText": "+৳50,000 each; only one parent claims it."
            },
            {
              "id": "newTp",
              "type": "checkboxField",
              "label": "First return (new taxpayer: minimum tax ৳1,000)",
              "bind": "$.newTaxpayer"
            },
            {
              "id": "ict",
              "type": "checkboxField",
              "label": "All of it is ICT or freelancing income received by bank transfer (Sixth Schedule para 21, to 30 June 2027)",
              "bind": "$.ictExempt",
              "helperText": "Listed ICT services, freelancing and content creation: exempt, with no turnover tax."
            },
            {
              "id": "tiles",
              "type": "group",
              "layout": "horizontal",
              "components": [
                {
                  "id": "net",
                  "type": "statTile",
                  "label": "Profit after tax (৳0 at a loss)",
                  "bind": "$.netIncome",
                  "format": "currency",
                  "currency": "BDT"
                },
                {
                  "id": "tax",
                  "type": "statTile",
                  "label": "Income tax",
                  "bind": "$.incomeTax",
                  "format": "currency",
                  "currency": "BDT"
                }
              ]
            },
            {
              "id": "breakdown",
              "type": "keyValueList",
              "label": "How that is worked out",
              "items": [
                {
                  "label": "Business income (receipts − expenses)",
                  "bind": "$.taxableIncome",
                  "format": "currency",
                  "currency": "BDT"
                },
                {
                  "label": "Tax-free threshold",
                  "bind": "$.taxFreeThreshold",
                  "format": "currency",
                  "currency": "BDT"
                },
                {
                  "label": "Tax at the Schedule 2 rates",
                  "bind": "$.slabTax",
                  "format": "currency",
                  "currency": "BDT"
                },
                {
                  "label": "Turnover tax: 1% of receipts",
                  "bind": "$.turnoverTax",
                  "format": "currency",
                  "currency": "BDT"
                },
                {
                  "label": "Turnover tax above the ordinary tax, carried forward",
                  "bind": "$.turnoverTaxCarryForward",
                  "format": "currency",
                  "currency": "BDT"
                }
              ]
            },
            {
              "id": "note",
              "type": "staticText",
              "text": "Income year 1 July 2026 to 30 June 2027 (tax year 2027-28), resident individual with business or professional income only. Tax is the larger of the Schedule 2 tax (at least ৳5,000 once income passes the threshold; ৳1,000 on a first return) and the s.163(6) turnover tax, which applies even with a loss; the turnover tax paid above the ordinary tax is carried forward against later years’ tax. Listed ICT and freelancing income received wholly by bank transfer is exempt to 30 June 2027 (para 21); a mix of exempt and taxable income, which cuts the turnover tax pro rata, is not modelled. Not modelled: other turnover rates (tobacco 3%, beverages 2.5%, 0.2% for a new factory’s first three years) and the businesses s.163(6) excludes (commission, delivery order, money exchange, gold and jewellery), the s.78 investment rebate, advance tax and tax deducted at source, the exemption for small manufacturing businesses (Sixth Schedule Part 1 para 24), wealth surcharge. Estimate, not tax advice."
            },
            {
              "id": "sources",
              "type": "sourceList",
              "label": "Sources",
              "layers": 2,
              "items": [
                {
                  "label": "Finance Act 2026 (Act 96), s.160 and Schedule 2 Part 1 para (ক): 2026-27 and 2027-28 rates",
                  "url": "https://bdlaws.minlaw.gov.bd/upload/act/2026-08-17-10-27-29-%E0%A6%A4%E0%A6%AB%E0%A6%B8%E0%A6%BF%E0%A6%B2_Act-No-96.pdf",
                  "date": "2026-11-01",
                  "covers": [
                    "taxFreeGeneral",
                    "taxFreeWomanSenior",
                    "taxFreeDisabledThirdGender",
                    "taxFreeWarWounded",
                    "bandWidth1",
                    "bandWidth2",
                    "bandWidth3",
                    "bandWidth4",
                    "rate0",
                    "rate1",
                    "rate2",
                    "rate3",
                    "rate4",
                    "rate5",
                    "minimumTax",
                    "minimumTaxNewTaxpayer",
                    "disabledChildAddOn"
                  ]
                },
                {
                  "label": "ITA 2023 Sixth Schedule Pt 1 para 21: ICT and freelancing exempt (Act 96 s.157(খ))",
                  "url": "https://bdlaws.minlaw.gov.bd/act-1725/section-59531.html",
                  "date": "2026-11-01",
                  "covers": []
                },
                {
                  "label": "Income Tax Act 2023 s.163(6) turnover tax (substituted by the Finance Act 2026, s.91)",
                  "url": "https://bdlaws.minlaw.gov.bd/act-1429/section-51993.html",
                  "date": "2026-11-01",
                  "covers": [
                    "turnoverTaxRate"
                  ]
                },
                {
                  "label": "Finance Act 2026, Bangladesh Gazette 30 June 2026 (NBR copy)",
                  "url": "https://nbr.gov.bd/uploads/acts/Finance_Act_2026.pdf",
                  "date": "2026-11-01",
                  "covers": []
                }
              ]
            }
          ]
        }
      ]
    },
    "tests": [
      {
        "description": "S1 ৳30 lakh receipts, ৳18 lakh expenses: ৳12 lakh profit, tax ৳30,000 + ৳60,000 + ৳20,000",
        "given": {
          "$.annualTurnover": 3000000,
          "$.annualExpenses": 1800000,
          "$.taxpayerCategory": "general",
          "$.disabledChildren": 0,
          "$.newTaxpayer": false,
          "$.ictExempt": false
        },
        "expect": {
          "$.taxableIncome": 1200000,
          "$.slabTax": 110000,
          "$.turnoverTax": 30000,
          "$.incomeTax": 110000,
          "$.netIncome": 1090000
        }
      },
      {
        "description": "S2 thin margin: ৳1 crore receipts, ৳5 lakh profit, turnover tax ৳1,00,000 exceeds ৳10,000",
        "given": {
          "$.annualTurnover": 10000000,
          "$.annualExpenses": 9500000,
          "$.taxpayerCategory": "general",
          "$.disabledChildren": 0,
          "$.newTaxpayer": false,
          "$.ictExempt": false
        },
        "expect": {
          "$.slabTax": 10000,
          "$.turnoverTax": 100000,
          "$.incomeTax": 100000,
          "$.turnoverTaxCarryForward": 90000,
          "$.netIncome": 400000
        }
      },
      {
        "description": "S3 profit below the threshold: turnover tax ৳10,000 still due",
        "given": {
          "$.annualTurnover": 1000000,
          "$.annualExpenses": 700000,
          "$.taxpayerCategory": "general",
          "$.disabledChildren": 0,
          "$.newTaxpayer": false,
          "$.ictExempt": false
        },
        "expect": {
          "$.taxableIncome": 300000,
          "$.slabTax": 0,
          "$.regularTax": 0,
          "$.incomeTax": 10000,
          "$.turnoverTaxCarryForward": 10000
        }
      },
      {
        "description": "S4 a loss: turnover tax applies regardless; profit after tax floored at 0",
        "given": {
          "$.annualTurnover": 2000000,
          "$.annualExpenses": 2500000,
          "$.taxpayerCategory": "general",
          "$.disabledChildren": 0,
          "$.newTaxpayer": false,
          "$.ictExempt": false
        },
        "expect": {
          "$.taxableIncome": 0,
          "$.incomeTax": 20000,
          "$.netIncome": 0
        }
      },
      {
        "description": "S5 ৳4,20,000 profit on ৳4,50,000 receipts: ৳2,000 lifted to the ৳5,000 minimum",
        "given": {
          "$.annualTurnover": 450000,
          "$.annualExpenses": 30000,
          "$.taxpayerCategory": "general",
          "$.disabledChildren": 0,
          "$.newTaxpayer": false,
          "$.ictExempt": false
        },
        "expect": {
          "$.slabTax": 2000,
          "$.turnoverTax": 4500,
          "$.incomeTax": 5000
        }
      },
      {
        "description": "S6 same as a new taxpayer: turnover tax ৳4,500 exceeds the ৳2,000 and the ৳1,000 minimum",
        "given": {
          "$.annualTurnover": 450000,
          "$.annualExpenses": 30000,
          "$.taxpayerCategory": "general",
          "$.disabledChildren": 0,
          "$.newTaxpayer": true,
          "$.ictExempt": false
        },
        "expect": {
          "$.incomeTax": 4500
        }
      },
      {
        "description": "S7 woman or 65+: threshold ৳4,50,000, tax ৳1,00,000",
        "given": {
          "$.annualTurnover": 3000000,
          "$.annualExpenses": 1800000,
          "$.taxpayerCategory": "womanOrSenior",
          "$.disabledChildren": 0,
          "$.newTaxpayer": false,
          "$.ictExempt": false
        },
        "expect": {
          "$.taxFreeThreshold": 450000,
          "$.incomeTax": 100000
        }
      },
      {
        "description": "S8 ৳1 crore profit: ৳6,90,000 + 30% of ৳64,00,000",
        "given": {
          "$.annualTurnover": 50000000,
          "$.annualExpenses": 40000000,
          "$.taxpayerCategory": "general",
          "$.disabledChildren": 0,
          "$.newTaxpayer": false,
          "$.ictExempt": false
        },
        "expect": {
          "$.slabTax": 2610000,
          "$.incomeTax": 2610000,
          "$.netIncome": 7390000
        }
      },
      {
        "description": "S9 ICT or freelancing income received by bank transfer: exempt, no turnover tax (para 21)",
        "given": {
          "$.annualTurnover": 3000000,
          "$.annualExpenses": 1800000,
          "$.taxpayerCategory": "general",
          "$.disabledChildren": 0,
          "$.newTaxpayer": false,
          "$.ictExempt": true
        },
        "expect": {
          "$.slabTax": 0,
          "$.turnoverTax": 0,
          "$.incomeTax": 0,
          "$.netIncome": 1200000
        }
      },
      {
        "description": "S10 two disabled children: threshold ৳5,00,000, tax ৳30,000 + ৳60,000",
        "given": {
          "$.annualTurnover": 3000000,
          "$.annualExpenses": 1800000,
          "$.taxpayerCategory": "general",
          "$.disabledChildren": 2,
          "$.newTaxpayer": false,
          "$.ictExempt": false
        },
        "expect": {
          "$.taxFreeThreshold": 500000,
          "$.incomeTax": 90000
        }
      },
      {
        "description": "S11 default: the ordinary tax exceeds the turnover tax, nothing carried forward",
        "given": {
          "$.annualTurnover": 3000000,
          "$.annualExpenses": 1800000,
          "$.taxpayerCategory": "general",
          "$.disabledChildren": 0,
          "$.newTaxpayer": false,
          "$.ictExempt": false
        },
        "expect": {
          "$.regularTax": 110000,
          "$.turnoverTaxCarryForward": 0
        }
      }
    ]
  }
}
