<div id="root">
</div>
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}

.App {
  text-align: center;
}

.input-group {
  margin: 10px 20px;
}

.input-group label {
  min-width: 170px;
  display: inline-block;
}

input {
  line-height: 30px;
  padding: 5px 10px;
  border: 1px solid #eee;
  width: 300px;
  max-width: calc(100% - 30px);
  margin: auto;
}

table {
  border-collapse: collapse;
  border-spacing: 0;
  margin: auto;
}

th,td {
  border: 1px solid #ddd;
  padding: 10px 15px;
  text-align: left;
}

th:first-child,
td:first-child {
  text-align: left;
}

th,
td:last-child {
  text-align: center;
}
const personalDeduction = 11000000;
const dependentsDeduction = 4400000;

function App() {
  const [salary, setSalary] = React.useState(20000000);
  const [person, setPerson] = React.useState(1);

  const getListTaxes = (incomeTaxes) => {
    const listTaxes = [];
    listTaxes.push({
      base: 1,
      text: 'Đến 5 triệu đồng (trđ)',
      percent: '5%',
      value: incomeTaxes > 5000000 ? 250000 : incomeTaxes * 5/100
    });

    if (incomeTaxes > 5000000) {
      listTaxes.push({
        base: 2,
        text: 'Trên 5 trđ đến 10 trđ',
        percent: '10%',
        value: incomeTaxes > 10000000 ? 500000 : incomeTaxes * 10/100 - 250000 - 250000
      });
    }

    if (incomeTaxes > 10000000) {
      listTaxes.push({
        base: 3,
        text: 'Trên 10 trđ đến 18 trđ',
        percent: '15%',
        value: incomeTaxes > 18000000 ? 1200000 : incomeTaxes * 15/100 - 750000 - 750000
      });
    }

    if (incomeTaxes > 18000000) {
      listTaxes.push({
        base: 4,
        text: 'Trên 18 trđ đến 32 trđ',
        percent: '20%',
        value: incomeTaxes > 32000000 ? 2800000 : incomeTaxes * 20/100 - 1950000 - 1650000
      });
    }

    if (incomeTaxes > 32000000) {
      listTaxes.push({
        base: 5,
        text: 'Trên 32 trđ đến 52 trđ',
        percent: '25%',
        value: incomeTaxes > 52000000 ? 5000000 : incomeTaxes * 25/100 - 4750000 - 3250000
      });
    }

    if (incomeTaxes > 52000000) {
      listTaxes.push({
        base: 6,
        text: 'Trên 52 trđ đến 80 trđ',
        percent: '30%',
        value: incomeTaxes > 80000000 ? 8400000 : incomeTaxes * 30/100 - 9750000 - 5850000
      });
    }

    if (incomeTaxes > 80000000) {
      listTaxes.push({
        base: 7,
        text: 'Trên 80 trđ',
        percent: '35%',
        value: incomeTaxes * 35/100 - 18150000 - 9850000
      });
    }

    return listTaxes;
  }

  const formatCurrency = (number) => {
    return new Intl.NumberFormat('vn', { style: 'currency', currency: 'vnd' }).format(number);
  }

  const renderPersonalTax = () => {
    const incomeTaxes = salary - personalDeduction - dependentsDeduction * person;
    const taxes = incomeTaxes > 0 ? getListTaxes(incomeTaxes) : [];
    const taxesFee = taxes.reduce((num, item) => {
      return item.value + num
    }, 0);

    // eslint-disable-next-line no-unused-expressions
    return (
      <table>
        <tbody>
          <tr>
            <td colSpan="3">Tổng thu nhập</td>
            <td><b>{formatCurrency(salary)}</b></td>
          </tr>
          <tr>
            <td colSpan="3">Giảm trừ cá nhân</td>
            <td>{formatCurrency(personalDeduction)}</td>
          </tr>
          <tr>
            <td colSpan="3">Giảm trừ phụ thuộc</td>
            <td>{formatCurrency(dependentsDeduction * person)}</td>
          </tr>
          <tr>
            <td colSpan="3">Số tiền tính thuế thu nhập cá nhân</td>
            <td>{formatCurrency(incomeTaxes > 0 ? incomeTaxes : 0)}</td>
          </tr>
          <tr>
            <td colSpan="3">Thuế phải nộp</td>
            <td>{formatCurrency(taxesFee)}</td>
          </tr>
          <tr>
            <td colSpan="3">Số tiền được lĩnh</td>
            <td><b>{formatCurrency(salary - taxesFee)}</b></td>
          </tr>
          {
            taxes.length > 0 &&
            <>
              <tr>
                <th>Bậc</th>
                <th>Thu nhập tính thuế/tháng</th>
                <th>Thuế suất</th>
                <th>Số tiền</th>
              </tr>
              {
                taxes.map(item => (
                  <tr key={item.base}>
                    <td>{item.base}</td>
                    <td>{item.text}</td>
                    <td>{item.percent}</td>
                    <td>{formatCurrency(item.value)}</td>
                  </tr>
                ))
              }
            </>
          }
        </tbody>
      </table>
    )
  }

  return (
    <div className="App">
      <div className="input-group">
        <label>Tổng thu nhập:</label>
        <input placeholder="Tổng thu nhập" type="number" value={salary} onChange={(e) => {setSalary(e.target.value)}} />
      </div>
      <div className="input-group">
        <label>Số người phụ thuộc:</label>
        <input placeholder="Người phụ thuộc" type="number" value={person} onChange={(e) => {setPerson(e.target.value)}}/>
      </div>
      {renderPersonalTax()}
    </div>
  );
}


function tick() {
  ReactDOM.render(
    <App />,
    document.getElementById('root')
  );
}

tick();
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://unpkg.com/react/umd/react.development.js
  2. https://unpkg.com/react-dom/umd/react-dom.development.js