Technical Lab · 0016

Odoo HR & Payroll Bangladesh — PF, Gratuity & leave setup.

How to configure Odoo's HR and Payroll modules for Bangladesh labor law compliance — Provident Fund, Gratuity provisions, leave types, salary structures, and income tax deduction on salary.

HR and Payroll is the Odoo module that touches every employee — and where compliance failure has the most direct legal consequences. In Bangladesh, the Labor Act 2006 (amended 2018) sets mandatory minimums for leave, Provident Fund, and Gratuity that every employer must meet. Odoo can be configured to enforce all of them — but it does not arrive pre-configured for Bangladesh.

This guide covers the complete setup sequence: employee records, leave types, salary structures, PF rules, Gratuity provisioning, income tax deduction, and payroll processing. I've drawn on live deployments in RMG factories (400+ employees), SME trading companies, and Dhaka-based service businesses.

A payroll error affects real people. Test every salary rule against actual employee data before go-live.

Bangladesh labor law baseline

Before configuring anything in Odoo, confirm the legal baseline your payroll must meet. Under the Bangladesh Labor Act 2006 (as amended), the mandatory minimum obligations are:

ObligationLegal minimumWho it applies to
Earned Leave 1 day per 18 working days (approx. 10–11 days/year for factory workers; varies for staff) All workers after 12 months of service
Sick Leave 14 days per year with full pay All employees
Casual Leave 10 days per year with full pay All employees
Maternity Leave 16 weeks (8 pre + 8 post delivery) with full pay Female employees with ≥6 months service
Festival Leave 11 days per year (Eid ul-Fitr, Eid ul-Adha, and national holidays) All employees
Provident Fund 5% employee contribution + 5% employer contribution of basic salary (where PF scheme exists) Employees covered by company PF scheme
Gratuity 30 days' wages per year of service (workers); 1 month basic per year (staff) Employees with ≥1 year of service on termination
Industry-specific

BGMEA/BKMEA member factories are additionally governed by the Minimum Wage Board gazette notification, which sets minimum wages by grade for RMG workers. If your factory is a BGMEA member, your Odoo salary structure must enforce these minimums. Underpaying by grade is a compliance failure — not just a payroll error. The practical setup: pull the current Minimum Wage Board gazette for your sector, create one Job Position per gazetted grade, record the gazetted floor wage on each, and review every contract's basic wage against its grade floor before confirming it. Treat any contract below the floor as a blocker, not a warning.

Employee master setup

Each employee record in Odoo (Employees → New) must capture these Bangladesh-specific fields:

Field / TabWhat to configure
Job Position / Grade Link to a Job Position that determines salary band and PF eligibility. Create grades that match your company's grading structure (Grade A, B, C or Officer, Senior Officer, Manager).
Date of Joining Critical for Gratuity calculation and leave entitlement accrual. Odoo calculates years of service from this date.
NID / Passport Store National ID number in the "Private Information" tab. Required for bank transfers, PF registration, and income tax filing.
Bank Account Add under Private Information → Save → Salary tab → Bank Account. This is the account Odoo uses for direct payroll payment. Required if you batch-pay salaries via bank transfer.
TIN (Tax ID) Employee TIN for income tax computation and Form-16 equivalent. Store in the Private Information tab under "Tax ID".
Contract Every employee must have an active contract (Employees → Employee → Contracts tab → New). The contract sets the salary structure, wage, and PF/Gratuity eligibility. Payroll will not run for an employee without a confirmed contract.

Leave types & allocation

Odoo's Leave module (Time Off) manages requests, approvals, and balance tracking. Configure these leave types for Bangladesh:

Mandatory — Labor Act

Earned Leave (Annual)

10–11 days/year

Accrual type: "Based on worked time" — 1 day per 18 working days. Configure as carried-forward leave. Unused balance must be encashed or carried to next year.

Mandatory — Labor Act

Sick Leave

14 days/year

Allocation type: Fixed (14 days at start of each leave year). Sick leave cannot be carried forward. Paid at full basic salary.

Mandatory — Labor Act

Casual Leave

10 days/year

Allocation type: Fixed (10 days at start of leave year). Cannot be accumulated or encashed. Used for short-notice personal emergencies.

Mandatory — Female Employees

Maternity Leave

16 weeks

Create as a separate leave type with "No allocation" (applied on request). Fully paid. Requires medical certificate. Cannot be denied to eligible employees.

Company Policy

Festival / Public Holiday

11 days/year

Configure as Public Holidays in the Work Schedule (not leave allocations). These are non-working days on the company calendar — they don't consume leave balance.

Common in SMEs

Without Pay Leave

As requested

Create as a separate leave type with "No allocation" — the leave is unpaid and triggers a salary deduction on the payslip. Odoo calculates the deduction automatically if the "Leave Deduction" option is enabled on the salary structure.

Set the leave approval workflow on each leave type: one-step (direct manager) or two-step (manager then HR). For large manufacturing operations with 400+ employees, I recommend a two-step approval for Earned Leave and Maternity Leave; single-step for Casual and Sick.

Salary structure

The salary structure defines every earning and deduction line on the payslip. In Bangladesh, the typical staff salary structure looks like this:

Sample Bangladesh Payslip — Monthly Staff (BDT)
Earnings
Basic Salary 30,000
House Rent Allowance (50% of Basic) 15,000
Medical Allowance 1,500
Transport Allowance 2,500
Gross Salary 49,000
Deductions
Employee PF (5% of Basic) –1,500
Income Tax (TDS on Salary) –1,200
Net Payable 46,300
Employer Contributions (not on payslip — company cost)
Employer PF (5% of Basic) 1,500
Gratuity Provision (1/12 of annual entitlement) 2,500

In Odoo, each line is a salary rule within the salary structure. Go to Payroll → Configuration → Salary Structures → New. Add rules for each earning and deduction. Rules are ordered — Basic Salary must exist before HRA can reference it (since HRA = 50% × Basic).

Provident Fund (PF) setup

PF in Odoo is two salary rules: one employee deduction, one employer contribution.

RuleCodeTypeComputationAccount
Employee PF EMP_PF Deduction (negative) -5% × Basic Salary PF Payable (2XXX)
Employer PF COM_PF Not on payslip — company cost 5% × Basic Salary PF Payable (2XXX)

Both amounts accumulate in the PF Payable account. At month-end, the total PF Payable balance is remitted to the employee's PF trust or fund. The journal entry: Debit PF Payable → Credit Bank. After remittance, the PF Payable account balances to zero.

PF eligibility

In most Bangladesh companies, PF applies only after a probation period (typically 3–6 months). In Odoo, handle this by creating two contract templates: one "Probation" template with a salary structure that has no PF rules, and one "Confirmed" template that includes PF. When an employee passes probation, update their contract to the Confirmed template.

Gratuity provision

Gratuity in Bangladesh is a terminal benefit — paid only when the employee leaves after completing at least one year of service. In Odoo, track Gratuity as a monthly provision (accrual), not a payslip deduction.

The monthly accrual entry:

Accrual amount = (Last Basic Salary ÷ 12) × years of service. For most companies, this is approximated as 1/12 of annual basic salary per month. The Gratuity Provision account on the balance sheet grows each month. When an employee leaves after qualifying for Gratuity, the actual payment is settled against the provision: Debit Gratuity Provision → Credit Bank.

Odoo does not have a native Gratuity provision module for Bangladesh. Implement this as either (a) a manual monthly journal entry, or (b) a salary rule marked as "Does not appear on payslip" with the appropriate account mapping — the rule calculates the provision per employee and posts the accrual automatically during payroll processing.

Note · Manufacturing company, post-migrationYear-end financial close
One company I reviewed had run Odoo Payroll cleanly for a full year — payslips, PF, TDS all correct — but had never set up the Gratuity provision. Because Gratuity is a terminal benefit, nothing in the monthly cycle reminded anyone it was missing. The gap only surfaced at year-end, when the auditor asked where the accrued Gratuity liability was on the balance sheet. The answer was: nowhere. The company had to book a large retrospective provision in a single period, distorting that year's profit. Gratuity is invisible until someone resigns or an auditor asks — provision it from the first payroll run, not the first claim.

Income tax on salary

Income tax deduction at source (TDS on salary) must be applied monthly from the salary of every employee who earns above the tax-free threshold. For the 2025–26 tax year, the threshold is BDT 3,50,000 annual income (BDT 29,167/month gross).

Configure TDS as a salary rule:

The progressive tax slabs for Bangladesh FY2025–26 are:

Annual Income (BDT)Tax Rate
Up to 3,50,000Nil
3,50,001 – 4,50,0005%
4,50,001 – 7,50,00010%
7,50,001 – 11,50,00015%
11,50,001 – 16,50,00020%
Above 16,50,00025%

Implement this as a Python-based salary rule in Odoo. The rule annualises the employee's current month gross salary, applies the slab calculation, and returns 1/12 of the annual tax liability. At year-end, reconcile the total TDS deducted against the employee's actual tax return to handle any over- or under-deduction.

Compliance link

Salary TDS must be remitted to the NBR via treasury challan by the 15th of the following month. This is tracked separately from VAT compliance — see my guide on NBR VAT compliance in Odoo for the broader NBR filing structure. Salary TDS remittance uses Treasury Form-Challan, not the Mushak forms.

Running payroll in Odoo

Once salary structures, PF rules, and leave deductions are configured, the monthly payroll process in Odoo is:

  1. Close attendance / leave — ensure all leave requests for the month are approved or rejected. Any approved Unpaid Leave affects the salary deduction calculation.
  2. Create payslip batch — Payroll → Payslip Batches → New. Set the period (e.g., May 2026). Click "Generate Payslips" — Odoo creates one draft payslip per active employee with a confirmed contract.
  3. Review payslips — open any payslip and verify the computed values. Pay particular attention to employees who had salary changes, promotions, or joined mid-month (partial month calculation).
  4. Validate the batch — once satisfied, Confirm the batch. Odoo posts the journal entries: Salary Expense (P&L) → Salaries Payable (BS), Employee PF deduction, Employer PF contribution, TDS deduction, and Gratuity accrual.
  5. Pay salaries — generate the salary payment in Accounting → Vendor Bills or use Batch Payments. Debit Salaries Payable → Credit Bank. For companies paying via mobile banking (bKash, Nagad), export the payment file from Odoo and upload to the mobile banking portal.
  6. Remit statutory deductions — by the 15th of the following month: PF to PF fund, TDS to NBR treasury challan.

For change management during payroll go-live — convincing finance teams and employees to trust the new system — see my field notes on change management in ERP deployments. Payroll is the module that generates the most resistance: everyone checks their payslip.

Next step

Payroll configuration for Bangladesh compliance is one of the more technically involved parts of an Odoo implementation. For a sense of where it sits in the overall project budget, try the Odoo cost estimator. If you're setting up for the first time or migrating from a legacy payroll system, reach out for a configuration review →

Frequently asked questions

How do I configure Provident Fund in Odoo for Bangladesh?

PF is configured as two salary rules: Employee PF (–5% of Basic, posted to PF Payable) and Employer PF (+5% of Basic, also to PF Payable, but not shown on the employee's payslip — it's a company cost). Both accumulate in the PF Payable account monthly. Remit the combined balance to the PF fund by the 15th of the following month. Exclude employees in probation by using a separate contract template without PF rules.

How is Gratuity calculated and provisioned in Odoo?

Under Bangladesh Labor Law, Gratuity = 1 month's basic salary × years of service (for staff), paid on termination after 1+ year of service. In Odoo, provision it monthly via a journal entry: Debit Gratuity Expense (P&L) → Credit Gratuity Provision (Balance Sheet). Accrual = 1/12 of annual entitlement. On the employee's last day, settle the Gratuity Provision balance: Debit Provision → Credit Bank.

What leave types are legally required in Bangladesh?

Under the Bangladesh Labor Act: Earned Leave (10–11 days/year, accrual-based), Sick Leave (14 days/year, fixed allocation), Casual Leave (10 days/year, fixed allocation), Maternity Leave (16 weeks for eligible female employees). Public holidays (11 national days) are configured as non-working days on the Work Schedule — they do not consume leave allocation.

Can Odoo handle income tax (TDS) on salary for Bangladesh?

Yes, with a custom Python-based salary rule that implements the NBR's progressive income tax slabs. The rule annualises the monthly gross, applies the current-year tax table, divides by 12, and posts the monthly TDS to an Income Tax Payable account. This must be recalculated if an employee's salary changes mid-year (Odoo handles the recalculation automatically on the next payslip run).