অধ্যায় ২৯ — HRM ও Payroll Accounting
Volume 2 · Part 4 — Application-specific Accounting · Chapter 29
পূর্বশর্ত: অধ্যায় ৭ (Journal Entry — compound entry, payroll-এর উদাহরণ), অধ্যায় ১৪ (Subledger-এর তিন স্তর), অধ্যায় ১৭ (Period cost), অধ্যায় ১৮ (Accrual), অধ্যায় ১৫ (TDS-এর কাঠামো)
১. Learning Objective
এই অধ্যায় শেষে আপনি পারবেন:
Payroll-এর পুরো চক্র — HRM data → compute → approve → post → pay → remit — আর কোন ধাপে entry, বলতে
Gross, deduction, net, employer cost — চারটি আলাদা সংখ্যা, কোনটা খরচ, কোনটা দেনা, ঠিক করতে
একটা payroll run-এর compound entry লিখতে: তিন খরচ, চার credit — তিন রকম পাওনাদার
কর্মী, সরকার, fund — তিনটি দেনা, তিনটি সময়, তিনটি subledger — আলাদা রাখতে
বেতন যে মাসের কাজ সেই মাসের খরচ — payment-এর মাস নয় — posting_date ঠিক করতে
মাঝমাসে যোগদান/বিদায়, বিনা বেতনে ছুটি — prorate-এর নিয়ম ও তার হিসাব
Staff loan ও advance — asset, payroll-এ কিস্তিতে আদায় — entry ও schedule
Festival bonus ও gratuity — বছরে একবার দেওয়া, মাসে মাসে খরচ — accrual ও provision
Billable বনাম admin বেতন — cost center দিয়ে একই run দুই account-এ
কর্মী-ধরে subledger (2120) আর GL-এর একটা line — তিন স্তর মেলাতে
Posted run কখনো বদলায় না — arrears ও off-cycle run দিয়ে সংশোধন
Bank file, ব্যর্থ transfer, payslip snapshot, আর payroll data-র গোপনীয়তা — নকশায়সময়: পড়া ৫৫ মিনিট + অনুশীলন ৬০ মিনিট।
২. Concept Explanation
সবচেয়ে বড় খরচ, যার bill নেই
Software company-র Income Statement-এ (অধ্যায় ২০) সবচেয়ে বড় লাইন 5110 আর 5210 — বেতন, মোট খরচের ৬০%-এর বেশি। অথচ এর কোনো supplier bill নেই, কোনো GRN নেই, three-way match নেই। Bill-টা আপনার system নিজে বানায় — payroll run। তাই এখানে অধ্যায় ১৫-এর “bill ঠিক তো?” প্রশ্নটা হয়ে যায় “হিসাব ঠিক তো?” — আর সেই হিসাবের কাঁচামাল HRM-এ: কে কবে যোগ দিলেন, কার বেতন কত, কে ক’দিন ছুটিতে ছিলেন।
Business Flow Financial Event? Entry
───────────── ──────────────── ─────
HRM: join, structure, না — master data —
attendance, leave
↓
Payroll compute না — খসড়া —
↓
Approve না — কিন্তু এর আগে post নয় —
↓
Post (মাসের শেষ দিন) হ্যাঁ — খরচ হলো, তিন দেনা জন্মাল Dr 5xxx / Cr 2120, 2150, 2170, 1180
↓
Pay (পরের মাসের ৩–৫) হ্যাঁ — কর্মীর দেনা শোধ Dr 2120 / Cr 1120
↓
Remit TDS (নির্ধারিত) হ্যাঁ — সরকারের দেনা শোধ Dr 2150 / Cr 1120
Remit PF (নির্ধারিত) হ্যাঁ — fund-এর দেনা শোধ Dr 2170 / Cr 1120Post একবার, payment তিনবার তিন জায়গায় — এটাই payroll-এর কাঠামো।
চারটি সংখ্যা
একজন কর্মীর “বেতন” বলতে চারটি আলাদা সংখ্যা:
GROSS কর্মী যা অর্জন করলেন basic + house rent + medical + conveyance + overtime + arrears
→ খরচ (5110 / 5210)
DEDUCTIONS gross থেকে যা কাটা গেল income tax (TDS), PF কর্মীর অংশ, loan কিস্তি, advance, absence
→ খরচ নয়! gross-এর ভাগ, অন্য কারো কাছে দেনা / asset কমা
NET কর্মীর হাতে gross − deductions
→ 2120 Salary Payable
EMPLOYER COST gross-এর উপরে প্রতিষ্ঠানের PF প্রতিষ্ঠানের অংশ, gratuity, bonus accrual, welfare
→ খরচ (5215–5219), কর্মী দেখেন নাসবচেয়ে সাধারণ ভুল দ্বিতীয় সারিতে: deduction খরচ কমায় না। ১,২০,০০০ gross-এর কর্মীর TDS ৮,০০০ কাটলে খরচ ১,২০,০০০-ই — ৮,০০০ কর্মীর tax, আপনি শুধু সংগ্রাহক (অধ্যায় ১৫-এর ভাড়ার TDS-এর মতোই)। PF-এর কর্মীর অংশ ৬,০০০ — কর্মীর টাকা, fund-এ যাবে, খরচ ১,২০,০০০-ই। খরচ বদলায় শুধু চতুর্থ সারিতে — employer cost বাড়ায়।
প্রতিষ্ঠানের মোট খরচ = gross + employer cost (১,২০,০০০ + ৬,০০০ + …)
কর্মীর হাতে = gross − deductions (১,২০,০০০ − ১৯,০০০)
দুটোর মাঝে = deductions + employer cost → তিন পাওনাদারএকটা entry, তিন পাওনাদার
অধ্যায় ৭-এর compound entry — এবার পুরো:
Dr 5110 Developer Salary — Billable 5,00,000 ← gross, billable কর্মী
Dr 5210 Salary & Allowance 2,00,000 ← gross, admin
Dr 5215 Employer PF Contribution 36,000 ← employer cost
Cr 2150 Tax Deducted at Source 40,000 ← সরকার
Cr 2170 Provident Fund Payable 72,000 ← fund: কর্মীর 36,000 + প্রতিষ্ঠানের 36,000
Cr 1180 Staff Advance & Loan 18,000 ← asset কমল (আদায়)
Cr 2120 Salary Payable 6,06,000 ← কর্মীচারটি credit, তিন রকম:
2120 কর্মীর কাছে দেনা ১২ জন, প্রত্যেকের আলাদা অঙ্ক শোধ: ৩–৫ তারিখ, bank transfer
2150 সরকারের কাছে দেনা একটা অঙ্ক, কিন্তু কর্মী-ধরে report শোধ: নির্ধারিত তারিখে (দেশভেদে)
2170 fund-এর কাছে দেনা দুই অংশ, কর্মী-ধরে হিসাব শোধ: trust-এ, মাসিক
1180 দেনা নয় — asset কমা কর্মী আগে টাকা নিয়েছিলেন, ফেরত schedule-ধরেDeveloper-এর দৃষ্টিতে: GL-এ 2120-তে একটাই line — 6,06,000। কিন্তু ১২ জনের প্রত্যেকে জানতে চান “আমার কত”। অধ্যায় ১৪-এর তিন স্তর: GL 2120 → কর্মী-ধরে subledger → run line (component-ধরে)। Entry aggregated, subledger detailed, দুটো এক transaction-এ। Section ৫।
Period cost — কাজের মাস, payment-এর মাস নয়
সেপ্টেম্বরের বেতন ৫ অক্টোবরে দেওয়া হয়। খরচ কোন মাসের? সেপ্টেম্বরের — অধ্যায় ১৭: বেতন period cost, যে মাসে কাজ। তাই payroll run-এর posting_date = মাসের শেষ দিন, payment-এর তারিখ যা-ই হোক। অধ্যায় ১৮-এর accrual-এর ভাষায়: payroll run নিজেই accrual (Cr 2120), payment-ই তার settlement — আলাদা করে accrue করার কিছু নেই।
সেপ্টেম্বর ৩০ তারিখে period বন্ধ করার আগে run post হওয়া চাই — অধ্যায় ২৫-এর checklist-এর একটা সারি: “payroll posted?”।
Prorate — মাঝমাসে
১৬-০৯ যোগদান, মাসিক 40,000 → earned = 40,000 × 15 ÷ 30 = 20,000 (calendar days)
২ দিন বিনা বেতনে ছুটি, 60,000 → earned = 60,000 × 28 ÷ 30 = 56,000দুটো নীতিগত প্রশ্ন, দুটোই company_settings-এ:
দিন গোনা calendar days (30/31) | working days (22) | fixed 30 — একবার ঠিক, সব কর্মীতে এক
কী prorate সব component | শুধু basic | component-ধরে flag — structure-এ
PF-এর base earned basic (prorated) | full basic — fund-এর নিয়মProrate-এর পরে component-গুলো আলাদা আলাদা কমে — কারণ PF basic-এর উপরে, tax কিছু component-এ ছাড়। “gross × 28/30” এক লাইনে করলে PF ভুল।
Loan ও advance — asset, কিস্তিতে ফেরত
কর্মীকে ৬০,০০০ loan, ১২ কিস্তি:
দেওয়ার দিন Dr 1180 Staff Advance & Loan 60,000 / Cr 1120 Bank 60,000 ← asset; খরচ নয়
প্রতি run Cr 1180 5,000 (deduction line) ← asset কমে, net কমে
শেষ কিস্তির পরে 1180-এ ওই কর্মীর balance 0Loan খরচ নয় — কর্মী ফেরত দেবেন। Deduction-ও খরচ নয়। 1180 কর্মী-ধরে subledger — অধ্যায় ১৪-এর মতো; কর্মী চলে গেলে বাকি balance final settlement-এ কাটা (নইলে 5xxx-এ write-off — অধ্যায় ৫৯)।
Bonus ও gratuity — একবার দেওয়া, মাসে মাসে খরচ
ঈদে bonus এক মাসের basic — বছরে দুবার ৫০% করে, ধরুন। জুন মাসে ৩,৬০,০০০ দিলে জুনের লাভ ধসে যায়, বাকি এগারো মাস bonus “বিনামূল্যে”। অধ্যায় ১৮-এর accrual:
প্রতি মাস Dr 5216 Festival Bonus 30,000 / Cr 2175 Accrued Bonus 30,000 ← Σ basic ÷ 12
bonus-এর মাসে Dr 2175 Accrued Bonus 3,60,000 / Cr 2120 Salary Payable 3,60,000 ← run-এর component; খরচ নয়, দেনা শোধGratuity — চাকরি ছাড়ার সময় প্রতি বছরের জন্য অর্ধেক মাসের basic। কখন দেবেন জানা নেই, কিন্তু প্রতিটি মাসের কাজ সেই দায় বাড়াচ্ছে — provision:
প্রতি মাস Dr 5217 Gratuity Expense 15,000 / Cr 2530 Gratuity Provision 15,000 ← non-current liability
কর্মী গেলে Dr 2530 ... / Cr 2120 ← final settlementসরলীকৃত হিসাব — আসল provision-এ actuarial অনুমান, discount — অধ্যায় ৫৯। এখানে কাঠামোটা: যা বছরে একবার বা কখনো দেওয়া হয়, তার খরচ মাসে মাসে।
Billable বনাম admin — একটা run, দুটো account
Developer-এর বেতন 5110 (Direct Cost — gross margin-এর উপরে), accountant-এর 5210 (Operating)। একই run, একই component, আলাদা account। নিয়ম কর্মীতে নয় — cost center-এ (employees.cost_center_id → cost_centers.salary_account_id), অধ্যায় ৩৪। Project-ধরে ভাগ (একজন developer তিন project-এ) — timesheet, অধ্যায় ৩৫। এ অধ্যায়ে cost center পর্যন্ত।
Posted run বদলায় না
৫ অক্টোবর HR জানাল — সালমার ২ দিনের ছুটির ১ দিন আসলে অনুমোদিত ছিল। সেপ্টেম্বরের run post হয়ে গেছে, বেতন চলে গেছে। কী করবেন?
ভুল সেপ্টেম্বরের run edit → re-post (posted entry বদলানো — অধ্যায় ৪৩)
ঠিক অক্টোবরের run-এ arrears component +2,000, narration "Sept leave correction"
জরুরি হলে off-cycle run, অক্টোবরে, শুধু সালমা, শুধু 2,000 (একই কাঠামো, একই entry)Payslip-ও বদলায় না — সেপ্টেম্বরের payslip-এ ৫৬,০০০-ই থাকবে, অক্টোবরেরটায় arrears line। অধ্যায় ২০-এর statement_runs-এর মতো snapshot ও hash — কর্মী ছয় মাস পরে একই payslip download করবেন।
Bank file, আর যে transfer ফেরে
১২ জনের net এক bank file-এ। Entry Dr 2120 6,06,000 / Cr 1120 — কিন্তু একজনের account নম্বর ভুল, ১৪,০০০ ফেরত এল:
ফেরত Dr 1120 Bank 14,000 / Cr 2120 Salary Payable 14,000 ← ওই কর্মীর subledger আবার 14,000
ঠিক করে Dr 2120 14,000 / Cr 1120 14,000 ← আবার transferPayment allocation কর্মী-ধরে — কার transfer গেল, কার ফিরল। “মোট ৬,০৬,০০০ গেছে” যথেষ্ট নয়।
গোপনীয়তা — GL-এ নাম নেই
Payroll data প্রতিষ্ঠানের সবচেয়ে সংবেদনশীল data। GL-এর 2120-তে একটা aggregated line — কর্মীর নাম নেই, সেটাই ইচ্ছাকৃত। Subledger (কে কত) আলাদা অনুমতিতে (অধ্যায় ৪৮)। Ledger দেখার অধিকার মানে payroll দেখার অধিকার নয়। Bank file-এ নাম থাকে — সেটা payment module-এর, GL-এর নয়।
যা এই অধ্যায়ে নেই
Income tax slab, rebate, investment allowance tax engine — এখানে অঙ্কটা দেওয়া, হিসাব নয় (অধ্যায় ৫৬-এর আগাম)
Attendance, leave, shift, overtime-এর হিসাব HRM — এখানে শুধু ফল (দিন, ঘণ্টা)
Gratuity/leave encashment-এর actuarial valuation অধ্যায় ৫৯
Project-ধরে বেতন ভাগ (timesheet) অধ্যায় ৩৫
Multi-country payroll, expatriate এ বইয়ে নেই৩. Accounting Rule
Entry
| ঘটনা | Debit | Credit |
|---|---|---|
| Payroll run post (মাসের শেষ দিন) | Salary (gross, cost center-ধরে), Employer PF | TDS Payable, PF Payable (দুই অংশ), Staff Loan (আদায়), Salary Payable (net) |
| Bonus accrual (মাসিক) | Festival Bonus Expense | Accrued Bonus |
| Bonus দেওয়া (run-এ) | Accrued Bonus | Salary Payable |
| Gratuity provision (মাসিক) | Gratuity Expense | Gratuity Provision |
| Loan / advance দেওয়া | Staff Advance & Loan | Bank |
| Net pay | Salary Payable | Bank |
| Transfer ফেরত | Bank | Salary Payable |
| TDS remit | TDS Payable | Bank |
| PF remit (দুই অংশ) | PF Payable | Bank |
| Final settlement | Salary Payable, Gratuity Provision, Accrued Bonus | Staff Loan (বাকি), TDS, Bank |
চার সংখ্যা
gross = Σ earning components (prorated) → খরচ
deductions = TDS + PF (কর্মী) + loan + advance + absence → খরচ নয়
net = gross − deductions → 2120
employer = PF (প্রতিষ্ঠান) + gratuity + bonus accrual → খরচ, gross-এর বাইরে
মোট খরচ = gross + employer; net ≥ 0 (নইলে run আটকায়)সময়
posting_date = মাসের শেষ দিন (কাজের মাস) payment-এর তারিখ নয়
payment = পরের মাস; remit = দেশের নিয়মে
period close-এর checklist: payroll postedProrate
দিন গোনা: একটা নীতি, সব কর্মীতে; component-ধরে prorate flag; PF base = earned basic (নীতি)Subledger
GL 2120 == Σ কর্মী-ধরে balance == Σ posted run net − Σ payment (কর্মী-ধরে allocation)
GL 1180 == Σ কর্মী-ধরে loan balance
GL 2170 == Σ run-এর PF (দুই অংশ) − Σ remit; 2150-এর salary অংশ == Σ run TDS − Σ remitঅলঙ্ঘনীয়
Posted run বদলায় না — arrears / off-cycle। Deduction খরচ কমায় না। GL-এ কর্মীর নাম নেই।৪. Real Business Example
সেপ্টেম্বর ২০২৬ — ১২ জনের বেতন
একই company। ১২ জন কর্মী — ৮ জন developer (billable, cost center DEV), ৪ জন admin/finance (cost center ADM)। COA-তে নতুন:
1180 Staff Advance & Loan ASSET post ← control, কর্মী-ধরে
2175 Accrued Bonus LIAB. post
2530 Gratuity Provision LIAB. post ← non-current
5215 Employer PF Contribution EXPENSE post
5216 Festival Bonus EXPENSE post
5217 Gratuity Expense EXPENSE post
(2120, 2150, 2170, 5110, 5210 — আগে থেকেই)নীতি: PF basic-এর ১০% কর্মী + ১০% প্রতিষ্ঠান; prorate calendar days, সব component; PF base earned basic; bonus বছরে দুবার ৫০% basic (Σ basic ÷ 12 মাসিক accrual); gratuity বছরে অর্ধেক মাসের basic (Σ basic ÷ 24)।
১৬-০৯ — জামাল যোগ দিলেন, junior developer, ৪০,০০০; relocation advance ১০,০০০, দুই কিস্তিতে
PV-09-0014
Dr 1180 Staff Advance & Loan [জামাল] 10,000
Cr 1120 Bank 10,000
1180 subledger: রহিম (loan, জুন) 45,000; জামাল 10,000; অন্য ২ জন 32,000 → Σ 87,000২৮-০৯ — HR run compute করল; তিন জনের হিসাব বিস্তারিত
রহিম — senior developer, DEV, পুরো মাস
basic 60,000 house rent 30,000 medical+conveyance 30,000 gross 1,20,000
PF কর্মী 10% × 60,000 = 6,000 TDS (tax table) 8,000 loan কিস্তি 5,000
net = 1,20,000 − 6,000 − 8,000 − 5,000 = 1,01,000
employer: PF 6,000
সালমা — accountant, ADM, ২ দিন বিনা বেতনে ছুটি
earned = 60,000 × 28 ÷ 30 = 56,000 → basic 28,000 house rent 14,000 অন্যান্য 14,000
PF 10% × 28,000 = 2,800 TDS 1,500 loan —
net = 56,000 − 2,800 − 1,500 = 51,700
employer: PF 2,800
জামাল — junior developer, DEV, ১৬-০৯ থেকে
earned = 40,000 × 15 ÷ 30 = 20,000 → basic 10,000 house rent 5,000 অন্যান্য 5,000
PF 1,000 TDS 0 advance কিস্তি 5,000
net = 20,000 − 1,000 − 5,000 = 14,000
employer: PF 1,000
বাকি ৯ জন (যোগফল)
gross 5,04,000 (basic 2,62,000; DEV ৬ জন 3,60,000, ADM ৩ জন 1,44,000)
PF 26,200 TDS 30,500 loan 8,000
net = 5,04,000 − 26,200 − 30,500 − 8,000 = 4,39,300Run-এর যোগফল:
PR-2026-09 DEV ADM মোট
──────────────────────────────── ──── ─── ───
gross 5,00,000 2,00,000 7,00,000 ← 1,20,000 + 20,000 + 3,60,000 | 56,000 + 1,44,000
Σ basic 3,60,000
PF কর্মী (10%) 36,000
TDS 40,000
loan / advance আদায় 18,000
net 6,06,000 ← 7,00,000 − 36,000 − 40,000 − 18,000
PF প্রতিষ্ঠান (10%) 36,000
মোট খরচ (gross + employer) 7,36,000২৯-০৯ — Finance approve করল (HR compute করেছে; approve অন্য মানুষ; ৫ লাখের উপরে CFO — approval_limits)। Approve-এ কিছু যাচাই: সব net ≥ 0; কোনো কর্মী দুবার নেই; আগস্টের তুলনায় gross ±১০%-এর বাইরে গেলে ব্যাখ্যা (জামাল নতুন — ব্যাখ্যা আছে)।
৩০-০৯ — Post
JV-09-0031 source = payroll_run PR-2026-09, idempotency_key = ('payroll_run', 2026-09), posting_date 30-09
Dr 5110 Developer Salary — Billable 5,00,000 cost_center DEV
Dr 5210 Salary & Allowance 2,00,000 cost_center ADM
Dr 5215 Employer PF Contribution 36,000 (DEV 26,000 + ADM 10,000 — dimension)
Cr 2150 Tax Deducted at Source 40,000 tds_kind salary
Cr 2170 Provident Fund Payable 72,000
Cr 1180 Staff Advance & Loan 18,000
Cr 2120 Salary Payable 6,06,000
───────── ─────────
7,36,000 7,36,000 ✓
JV-09-0032 bonus accrual: Dr 5216 30,000 / Cr 2175 30,000 ← 3,60,000 ÷ 12
JV-09-0033 gratuity: Dr 5217 15,000 / Cr 2530 15,000 ← 3,60,000 ÷ 24Deduction-গুলো খরচে নেই — ৭,০০,০০০-ই gross খরচ। ১৮,০০০-এর loan আদায় asset কমাল, কারো খরচ নয়।
০৩-১০ — Bank file, ১২ transfer
PV-10-0002 source = payroll_payment, ১২টি allocation (কর্মী-ধরে)
Dr 2120 Salary Payable 6,06,000
Cr 1120 Bank — Prime 6,06,000০৫-১০ — জামালের transfer ফেরত (account নম্বরে ভুল — HR-এ typo)
PV-10-0005
Dr 1120 Bank 14,000
Cr 2120 Salary Payable [জামাল] 14,000
2120 subledger: জামাল 14,000; বাকি সবাই 0
০৭-১০ নম্বর ঠিক (HR, verified by Finance — অধ্যায় ১৬-এর supplier bank account-এর নিয়ম কর্মীর জন্যও)
PV-10-0008 Dr 2120 [জামাল] 14,000 / Cr 1120 14,000 → 2120 0০৫-১০ — সালমার ছুটি: ১ দিন অনুমোদিত ছিল, HR ভুল করেছিল
সেপ্টেম্বরের run অক্ষত। অক্টোবরের run-এ সালমার লাইনে arrears +2,000 (60,000 ÷ 30), narration “Sept 2026 leave correction, HR ticket #412”। PF সেই ২,০০০-এর basic অংশে (১,০০০ × ১০% = ১০০) — অক্টোবরে।
১০-১০ — TDS remit; ১৫-১০ — PF remit
PV-10-0011 Dr 2150 TDS Payable (salary) 40,000 / Cr 1120 40,000 ← challan নম্বর সংরক্ষণ
PV-10-0016 Dr 2170 PF Payable 72,000 / Cr 1120 72,000 ← trust-এর receipt(2150-এ অধ্যায় ১৫-এর ভাড়ার TDS-ও আছে — tds_kind dimension-এ আলাদা; দুটোর remit আলাদা challan-এ। অধ্যায় ৫৬।)
তিন স্তর — ৩০ সেপ্টেম্বর ও ০৫ অক্টোবর
স্তর ১ GL 2120 30-09: 6,06,000 Cr 05-10: 14,000 Cr
স্তর ২ কর্মী-ধরে রহিম 1,01,000, সালমা 51,700, জামাল 14,000, … 05-10: জামাল 14,000, বাকি 0
স্তর ৩ run line রহিম: basic +60,000, HR +30,000, other +30,000, PF −6,000, TDS −8,000, loan −5,000
payment allocation PV-10-0002 → রহিম 1,01,000, … ; PV-10-0005 ← জামাল (ফেরত); PV-10-0008 → জামালঅধ্যায় ১৪-এর সূত্র: GL == Σ subledger == Σ run net − Σ allocation। জামালের ১৪,০০০ তিন স্তরেই এক।
Payslip — রহিম, সেপ্টেম্বর ২০২৬
EARNINGS DEDUCTIONS
Basic 60,000 Provident Fund (10%) 6,000
House Rent 30,000 Income Tax 8,000
Medical & Conv. 30,000 Loan Instalment (4/12) 5,000
──────────────────────── ──────────────────────────────
Gross 1,20,000 Total 19,000
NET PAY 1,01,000
Employer PF (info) 6,000 Loan balance after 40,000
snapshot hash a91f… PR-2026-09 / posted 30-09-2026Employer PF “info” — কর্মীর হাতে নয়, কিন্তু কর্মী জানেন। Loan balance — 1180 subledger থেকে।
৫. Implementation — Software ও Database
Master — HRM-এর যা accounting-এর লাগে
employees salary_structures
id, company_id, emp_code id, employee_id
name, join_date, leave_date effective_from, effective_to
cost_center_id FK → salary_account_id (একটা কর্মীর সময়ে সময়ে structure বদলায়; overlap নয়)
bank_account_no, bank_verified_by, verified_at
pf_member BOOLEAN salary_structure_lines
tax_id structure_id, component_id, amount | pct_of_basic
status active | notice | leftpay_components
code basic | house_rent | medical | conveyance | overtime | arrears | bonus |
pf_employee | income_tax | loan | advance | absence | pf_employer | gratuity
kind earning | deduction | employer_cost
calc fixed | pct_of_basic | per_day | per_hour | from_schedule | from_tax_table | manual
prorate BOOLEAN
pf_base BOOLEAN -- basic: true
taxable BOOLEAN
gl_account_id FK -- earning: cost center থেকে override; deduction: 2150 / 2170 / 1180; employer: 5215–5217
liability_party employee | government | fund | assetComponent-এর gl_account_id — এটাই posting rule; run-এ copy। Earning-এর account cost center override করে (5110 / 5210)।
Run ও line — subledger
payroll_runs payroll_run_lines
id, company_id id, run_id, employee_id
period_year, period_month component_id
run_type regular | off_cycle | final amount DECIMAL(18,4) -- চিহ্ন: earning +, deduction −
status draft | computed | approved | base_amount DECIMAL(18,4) -- pct-এর base (basic)
posted | paid | cancelled days_or_hours DECIMAL(10,4) -- prorate / overtime
posting_date DATE gl_account_id FK -- সেই সময়ের mapping, copy
computed_by, approved_by, approved_at cost_center_id FK
journal_entry_id loan_id FK NULL -- loan কিস্তি
idempotency_key ('payroll_run', company, period, run_type, seq)
input_hash -- structure + attendance-এর hash; বদলালে computed বাতিল
UNIQUE (company_id, period_year, period_month, run_type, seq)
INDEX (run_id, employee_id)payroll_run_lines স্তর ৩ — প্রতিটি কর্মীর প্রতিটি component। GL entry এখান থেকে GROUP BY gl_account_id, cost_center_id।
employee_ledger (স্তর ২ — 2120, 1180-এর কর্মী-ধরে)
employee_id, account_id (2120 | 1180), entry_date, source_type, source_id, debit, credit
→ balance(employee, 2120) = Σ credit − Σ debit; অধ্যায় ১৪-এর customer subledger-এর মতোstaff_loans staff_loan_schedules
id, employee_id, principal, disbursed_on, loan_id, instalment_no, due_period, amount, status (due | deducted | waived), run_line_id
instalments, per_instalment, balance, statuscompute() — খসড়া, entry নয়
computeRun(run):
যাচাই: run.status IN (draft, computed); period open; একই period-এ আরেকটা regular run posted নয়
employees = active in period (join_date ≤ period.end AND (leave_date IS NULL OR leave_date ≥ period.start))
lines = []
প্রতিটি e in employees:
s = structure(e, period.end); days = paidDays(e, period) -- HRM থেকে: calendar − unpaid leave; join/leave prorate
factor = policy.prorate_basis == 'calendar' ? days ÷ daysIn(period) : …
basic = s.basic × (component.prorate ? factor : 1)
প্রতিটি earning c in s: amt = c.calc == pct_of_basic ? basic × pct : c.amount; amt ×= c.prorate ? factor : 1
lines += (e, c, +amt, account = e.cost_center.salary_account or c.gl_account)
arrears/overtime/bonus: from HRM inputs (approved), manual lines with reason
pf_base = Σ lines WHERE pf_base; if e.pf_member: lines += (e, pf_employee, −pf_base × 10%, 2170)
lines += (e, pf_employer, +pf_base × 10%, 5215) -- employer_cost
tax = taxTable(e, Σ taxable, ytd) -- অধ্যায় ৫৬; এখানে black box
lines += (e, income_tax, −tax, 2150)
প্রতিটি due schedule in loans(e, period): lines += (e, loan, −amount, 1180, loan_id)
net = Σ earning − Σ deduction
if net < 0: run.errors += (e, "net negative"); -- loan কিস্তি পিছিয়ে দিন, বা run আটকান
run.lines = lines; run.input_hash = hash(structures, attendance, loans); run.status = computedCompute যতবার খুশি — entry নেই। input_hash — approve-এর পরে attendance বদলালে approved বাতিল, আবার compute।
approve() ও post()
approveRun(run, by):
যাচাই: run.status == computed; by ≠ run.computed_by; Σ net ≤ approval_limit(by)
run.errors empty; input_hash == hash(now)
variance: প্রতিটি কর্মীর gross vs আগের মাস ±10% → ব্যাখ্যা লাগে (join/leave/arrears হলে auto)
run.status = approved
postRun(run):
যাচাই: approved; period(run.posting_date) open; entries(idempotency_key) empty
BEGIN
entry = JournalEntry(voucher 'JV', posting_date = last day of period,
source = ('payroll_run', run.id), idempotency_key = run.idempotency_key,
narration = "{period} বেতন, {n} জন")
groups = run.lines GROUP BY (gl_account_id, cost_center_id)
প্রতিটি (acct, cc, Σamt) in groups:
kind = component kind:
earning → Dr acct Σamt (5110 / 5210, dims cc)
employer_cost → Dr acct Σamt (5215) AND Cr 2170 Σamt (PF) / Cr 2530 (gratuity)
deduction → Cr acct |Σamt| (2150 / 2170 / 1180)
entry.line(Cr 2120, Σ net)
assert entry.balanced()
post(entry)
-- স্তর ২: কর্মী-ধরে
প্রতিটি e: employee_ledger += (e, 2120, credit = net(e), source = run)
প্রতিটি loan line: employee_ledger += (e, 1180, credit = amt, source = run); schedule.status = deducted; loan.balance −= amt
run.journal_entry_id = entry.id; run.status = posted
COMMITEntry-তে ৭টা line, subledger-এ ১২ + কিস্তির সারি — একই transaction। GL-এ কর্মীর নাম নেই; employee_ledger-এ আছে, আলাদা অনুমতিতে।
Payment — bank file ও allocation
payRun(run, bank_account, by):
যাচাই: run.status == posted; by has 'payroll.pay'; প্রতিটি কর্মীর bank_verified_by ≠ NULL, ≠ HR-এর যিনি নম্বর দিলেন
file = bankFile(প্রতিটি e: (e.bank_account_no, net(e))) -- format ব্যাংকের
entry: Dr 2120 Σ net / Cr bank source = payroll_payment
প্রতিটি e: payment_allocations += (payment, e, net(e)); employee_ledger += (e, 2120, debit = net(e))
run.status = paid
returnTransfer(payment, e, amount, reason): -- ব্যাংক ফেরত দিল
entry: Dr bank / Cr 2120 amount; employee_ledger += (e, 2120, credit = amount, source = return)
allocation.status = returned; কর্মীর bank_verified_by = NULL (আবার verify)অধ্যায় ১৪-এর allocations table-ই — document_type = payroll_run, party = employee। একই কাঠামো, একই তিন-মুখী যাচাই।
Remittance
statutory_remittances
id, kind (tds_salary | pf), period, amount, paid_on, challan_no, journal_entry_id
remit(kind, period): amount = Σ run lines (kind, period); entry Dr 2150/2170 / Cr bank; challan_no বাধ্যতামূলক
report: কর্মী-ধরে TDS (সরকারের form), কর্মী-ধরে PF (trust-এর statement) ← run_lines থেকে, entry থেকে নয়Bonus, gratuity, final settlement
monthlyProvisions(period): -- period close-এর checklist-এ
bonus: Dr 5216 / Cr 2175 Σ basic(active) ÷ 12 idempotency ('bonus_accrual', period)
gratuity: Dr 5217 / Cr 2530 Σ basic(eligible) ÷ 24 idempotency ('gratuity_prov', period)
bonusRun(period): run_type = off_cycle; component bonus, gl_account = 2175 (খরচ নয় — accrual ছাড়া); TDS bonus-এর উপরে; net → 2120
finalSettlement(e): run_type = final; earned till leave_date + leave encashment + gratuity (Dr 2530) + bonus accrued (Dr 2175)
− loan balance (Cr 1180, পুরোটা) − TDS; net → 2120; e.status = leftPayslip snapshot
payslips: run_id, employee_id, rendered (PDF/JSON), hash, generated_at
নিয়ম: run posted হলে তৈরি, কখনো re-render নয়; arrears পরের payslip-এ; কর্মী নিজেরটাই দেখেনAPI / Service
POST /payroll/runs {period, run_type} → draft
POST /payroll/runs/{id}/compute → computed; errors তালিকা (net < 0, structure নেই, bank unverified)
GET /payroll/runs/{id}/preview → কর্মী-ধরে gross/deductions/net, আগের মাসের সাথে variance
POST /payroll/runs/{id}/approve … /post … /pay
POST /payroll/payments/{id}/returns {employee_id, amount, reason}
GET /payroll/employees/{id}/ledger → 2120, 1180 কর্মী-ধরে (payroll.view_employee)
GET /payroll/reconciliation?period= → যাচাই ১০৮–১১৩
GET /payroll/statutory?kind=&period= → TDS / PF report, remit status
GET /payslips/{run}/{employee} → snapshot; কর্মী নিজে / payroll.view_allRun-এর line client পাঠায় না — compute server-এ; manual line (arrears, overtime) শুধু HRM-approved input থেকে, reason সহ।
রাতের যাচাই
১০৮. closing(2120) == Σ employee_ledger(2120) == Σ posted run net − Σ payment allocation + Σ returns
১০৯. closing(1180) == Σ employee_ledger(1180) == Σ staff_loans.balance
১১০. প্রতিটি posted run: journal entry Dr Σ == run lines earning + employer; Cr 2120 == Σ net; entry ↔ lines মেলে
১১১. 2120 / 1180 / 2170 / 2150(salary)-এ posted line যার source_type ∉ (payroll_run, payroll_payment, payroll_return,
loan_disbursement, statutory_remittance, opening_balance) → ০টি
১১২. period closed অথচ ওই period-এর regular run posted নয় → ব্যর্থ; run posted কিন্তু ৭ দিন পরেও paid নয় → সতর্কতা
১১৩. 2170 / 2150(salary)-এ গত period-এর balance remit হয়নি due date-এর পরে → সতর্কতা; কর্মী left অথচ 1180 balance > 0 → সতর্কতা১১২-এর প্রথম অংশ অধ্যায় ২৫-এর checklist-এর সাথে — payroll ছাড়া মাস বন্ধ হয় না।
Test হিসেবে
test "run entry: চার সংখ্যা, balanced":
run = compute(Sept, 12 employees); approve; post
assert Δ 5110 == +5,00,000 and Δ 5210 == +2,00,000 and Δ 5215 == +36,000
assert Δ 2150 == −40,000 and Δ 2170 == −72,000 and Δ 1180 == −18,000 and Δ 2120 == −6,06,000
assert entry.lines.count == 7 -- কর্মী-ধরে নয়
assert Σ employee_ledger(2120) == 6,06,000 and employee_ledger(2120, রহিম) == 1,01,000
test "deduction খরচ কমায় না":
assert Δ (all 5xxx) == 7,36,000 -- gross + employer; TDS/PF/loan বাদ যায়নি
test "prorate: যোগদান মাঝমাসে, component-ধরে":
জামাল join 16-09, 40,000
assert gross(জামাল) == 20,000 and basic == 10,000 and pf == 1,000
test "unpaid leave: PF earned basic-এ":
সালমা 2 days unpaid
assert gross == 56,000 and pf_employee == 2,800 (not 3,000)
test "net < 0 → run আটকায়":
loan instalment 30,000, gross 25,000
assert compute(run).errors contains (e, "net negative") and rejects approve(run)
test "posting_date = মাসের শেষ দিন, payment পরের মাসে":
post(run Sept) on 02-10 → assert entry.posting_date == 30-09
pay(run) on 03-10 → assert payment.posting_date == 03-10 and movement(5110, Oct) == 0
test "posted run edit নয়; arrears পরের run-এ":
assert rejects editLine(posted_run, সালমা, absence)
oct = compute(Oct); assert line(oct, সালমা, arrears) == +2,000
test "একই period দুবার post নয়":
post(run); assert rejects post(run) and rejects post(compute(Sept, regular)) -- idempotency
test "transfer ফেরত: কর্মীর subledger ফেরে, GL মেলে":
pay(run); returnTransfer(payment, জামাল, 14,000)
assert employee_ledger(2120, জামাল) == 14,000 and closing(2120) == 14,000
assert employees[জামাল].bank_verified_by IS NULL
test "approve ≠ compute; সীমা":
assert rejects approve(run, by = run.computed_by)
assert rejects approve(run, by = user with limit 5,00,000) -- net 6,06,000
test "input বদলালে approved বাতিল":
approve(run); HRM.updateAttendance(সালমা); assert run.status == computed
test "loan: asset, কিস্তি, শেষে শূন্য":
disburse(রহিম, 60,000, 12)
assert Δ 1180 == +60,000 and Δ (5xxx) == 0
12 × post(run); assert loan.balance == 0 and employee_ledger(1180, রহিম) == 0
test "bonus: accrual মাসে মাসে, দেওয়ার মাসে খরচ নয়":
6 × monthlyProvisions; assert closing(2175) == 1,80,000
bonusRun(Eid, 1,80,000); assert Δ 5216 (this month) == 30,000 (শুধু accrual) and Δ 2175 == −1,80,000 + 30,000
test "GL-এ নাম নেই; ledger অনুমতিতে":
assert journal_lines WHERE source = payroll_run has no employee dimension
assert rejects GET /payroll/employees/{রহিম}/ledger as user without payroll.view_employee
test "2120-এ হাতে JV নয়":
assert rejects post(JV(Dr 5210 / Cr 2120))৬. Financial Statement Impact
INCOME STATEMENT (সেপ্টেম্বর ২০২৬)
5110 Developer Salary — Billable 5,00,000 ← Direct Cost: gross margin-এর উপরে
5215 Employer PF (DEV অংশ) 26,000
5210 Salary & Allowance 2,00,000 ← Operating
5215 Employer PF (ADM অংশ) 10,000
5216 Festival Bonus 30,000
5217 Gratuity Expense 15,000
মোট কর্মী-খরচ 7,81,000 (কারো হাতে গেছে 6,06,000)
BALANCE SHEET (৩০ সেপ্টেম্বর ২০২৬)
1180 Staff Advance & Loan 69,000 (87,000 − 18,000) — current (১২ মাসের ভিতরে)
2120 Salary Payable 6,06,000 ← current; ৫ দিনে শূন্য
2150 TDS Payable (salary অংশ) 40,000 ← current
2170 PF Payable 72,000 ← current
2175 Accrued Bonus (জমছে) ← current (বছরের মধ্যে)
2530 Gratuity Provision (জমছে) ← non-current
CASH FLOW (সেপ্টেম্বর)
operating: loan −10,000 (জামাল); বেতন — কিছুই না (অক্টোবরে 6,06,000 + 40,000 + 72,000)Income Statement-এ ৭,৮১,০০০ খরচ, Cash Flow-এ শূন্য — অধ্যায় ২২-এর সবচেয়ে বড় working capital adjustment: increase in salary & statutory payables। আর 5215 দুই cost center-এ ভাগ — gross margin-এ developer-এর PF-ও ঢোকে; না ঢোকালে billable cost কম দেখায়।
৭. Common Developer Mistakes
| ভুল | কী ঘটে | সঠিক পথ |
|---|---|---|
| খরচ = net (Dr 5210 6,06,000) | খরচ ১,৩০,০০০ কম; TDS/PF দেনা নেই | খরচ gross + employer; deduction credit-এ |
| Employer PF কর্মীর deduction-এ | net ভুল, কর্মী কম পান | employer_cost আলাদা kind |
| posting_date = payment date | সেপ্টেম্বরের খরচ অক্টোবরে; period cost ভাঙে | মাসের শেষ দিন |
| Entry কর্মী-ধরে (১২ × ৭ line) | GL-এ নাম, ledger ফোলে, গোপনীয়তা নেই | GROUP BY account/cc; নাম subledger-এ |
| Subledger নেই — শুধু GL | ”আমার কত” বলা যায় না; ফেরত transfer হারায় | employee_ledger, allocation |
| Posted run edit | audit ভাঙে, payslip বদলায়, TDS report ভুল | arrears / off-cycle |
| Prorate gross-এ এক লাইনে | PF/tax base ভুল | component-ধরে, flag |
| Loan খরচে | asset নেই, কর্মী গেলে আদায় ভুলে যায় | 1180, schedule |
| Bonus দেওয়ার মাসে খরচ | এক মাসে লাভ ধস | মাসিক accrual 2175 |
| PF দুই অংশ আলাদা account না রাখা / এক করে | trust-এর statement মেলে না | 2170-এ dimension part = employee/employer |
| Salary TDS আর vendor TDS মিশে | দুই challan, এক balance — কোনটা কত | tds_kind dimension |
| Bank file-এর অঙ্ক GL থেকে না নিয়ে HR sheet থেকে | দুই সংখ্যা | run lines → entry → file, এক উৎস |
| ব্যর্থ transfer-এ entry নেই | 2120 শূন্য অথচ কর্মী পাননি | return entry, allocation returned |
| কর্মীর bank account HR একাই বদলায় | সবচেয়ে সহজ payroll fraud | verify আলাদা মানুষ, ৩০ দিনের পতাকা (অধ্যায় ১৬) |
| Compute আর approve একজন | নিজের বেতন বাড়ানো | segregation; approval_limits |
| Attendance বদলালে approved run থেকে যায় | পুরনো হিসাব post | input_hash |
| Payslip re-render | ছয় মাস পরে অন্য সংখ্যা | snapshot + hash |
| Period close, payroll বাদ | মাসের সবচেয়ে বড় খরচ নেই | checklist; যাচাই ১১২ |
| 2120/1180-এ হাতে JV | subledger ≠ GL | control account; যাচাই ১১১ |
প্রথম আর চতুর্দশ সবচেয়ে ব্যয়বহুল। প্রথমটা Income Statement-কে মাসে ১,৩০,০০০ মিথ্যা বলায় আর সরকারের দেনা লুকায়। চতুর্দশটা টাকা হারায় — payroll fraud প্রায় সবসময় bank account নম্বর দিয়ে হয়, আর যিনি বদলান তিনি বেশ কিছুদিন ধরা পড়েন না, কারণ “মোট ৬,০৬,০০০ মিলে গেছে”।
৮. Exercises
সেট ক — হিসাব ও entry
১। একজন কর্মী: basic 40,000, house rent 20,000, medical 5,000; PF 10%+10%; TDS 2,500;
loan কিস্তি 3,000। gross, deductions, net, employer cost, প্রতিষ্ঠানের মোট খরচ।
২। ১ নম্বরের entry (একজনের জন্য)।
৩। ওই কর্মী ২০ তারিখে যোগ দিলেন (৩০ দিনের মাস)। সব সংখ্যা আবার। PF কত?
৪। ৩ দিন বিনা বেতনে ছুটি, ২ ঘণ্টা overtime (ঘণ্টায় basic ÷ 240)। gross?
৫। ৩ জনের run: net 30,000, 45,000, −2,000 (loan বড়)। কী করবেন? দুটো বিকল্প।
৬। Bonus: Σ basic 3,60,000, বছরে দুবার ৫০%। মাসিক accrual entry। ঈদে দেওয়ার entry
(TDS 5% ধরুন)। ঈদের মাসে 5216-এ কত?
৭। একজন কর্মী ছাড়লেন: earned 25,000, leave encashment 15,000, gratuity provision তার
জন্য 90,000, loan balance 20,000, TDS 3,000। Final settlement-এর entry।সেট খ — সময় ও subledger
৮। Run post ০২-১০-এ, payment ০৫-১০, TDS remit ১০-১০, PF ১৫-১০। প্রতিটির posting_date।
সেপ্টেম্বরের Income Statement-এ কী, Cash Flow-এ কী?
৯। ৩০-০৯: GL 2120 6,06,000। ০৫-১০: payment 6,06,000, ফেরত 14,000 (জামাল), ২০,০০০
(রহিম — ব্যাংক ভুল)। ০৭-১০: জামাল আবার। ৩১-১০-এ 2120 কত, কার? তিন স্তর লিখুন।
১০। সালমার arrears অক্টোবরে +2,000। PF/TDS-এ কী প্রভাব? সেপ্টেম্বরের TDS report
(সরকারকে দেওয়া) বদলাবে?
১১। 2170-এ ৩১-১০-এ balance 72,000 + 74,000 (অক্টোবর) − 72,000 (remit)। ঠিক? trust-এর
statement-এ কর্মী-ধরে কী থাকা উচিত?সেট গ — কোনটা ভুল
১২। Dr 5210 6,06,000 / Cr 2120 6,06,000
১৩। Dr 5210 7,00,000 / Dr 5215 36,000 / Cr 2120 7,36,000 — "TDS, PF পরে"
১৪। Dr 5210 5,000 / Cr 1120 5,000 — কর্মীকে advance
১৫। posting_date 05-10, narration "September salary"
১৬। journal_lines-এ employee_id column, ১২ × ৭ line
১৭। UPDATE payroll_run_lines SET amount = 58,000 WHERE run = Sept AND employee = সালমা
১৮। Dr 5216 3,60,000 / Cr 2120 3,60,000 — ঈদের bonus, accrual ছিল
১৯। HR user: employees.bank_account_no UPDATE অনুমতি, verify-ওসেট ঘ — নকশা
২০। একজন developer তিন project-এ (৫০/৩০/২০%)। 5110-এর ১,২০,০০০ project-ধরে ভাগ —
run-এ না পরে? timesheet কে দেয়? না দিলে? (অধ্যায় ৩৫-এর আগাম)
২১। Tax engine black box — কিন্তু YTD লাগে (slab বছরের আয়ে)। কোন table, কী state?
মাঝবছরে যোগ দেওয়া কর্মীর আগের চাকরির আয়?
২২। Off-cycle run-এর idempotency_key কী? একই মাসে দুটো off-cycle (arrears, bonus)?
regular run-এর সাথে সংঘর্ষ কীভাবে আটকাবেন?
২৩। Payroll approve করেন CFO, কিন্তু CFO-ও কর্মী — নিজের বেতন নিজে approve? কী নিয়ম?
১২ জনের প্রতিষ্ঠানে বাস্তবসম্মত সমাধান?
২৪। Bank file-এর format ব্যাংক-ধরে আলাদা; একটা ব্যাংক per-employee reference চায়।
allocation table-এ কী রাখবেন যাতে ফেরত এলে reference থেকে কর্মী খুঁজে পান?উত্তর আছে Workbook-এর Answer Key, অধ্যায় ২৯-এ।
৯. Developer Challenge
একটি PayrollService নকশা করুন — HRM থেকে GL পর্যন্ত — Part 4-এর তৃতীয় project (Projects ও Exit Criteria: Payroll-to-accounting integration)।
যা যা নকশা করবেন:
১. Master —
employees(cost center → salary account, bank verify),salary_structures(effective-dated, overlap নয়),pay_components(kind, calc, prorate, pf_base, taxable, gl_account, liability_party)। Component যোগ করলে কোড বদলায় না — test: নতুন “transport allowance” component শুধু data দিয়ে।২.
computeRun()— prorate নীতি (calendar/working/fixed) একটা function-এ; component-ধরে; PF base; loan schedule; tax engine interface (taxTable(employee, taxable, ytd));net < 0errors;input_hash। Compute idempotent, entry নেই।৩.
approveRun()/postRun()— segregation,approval_limits, variance ব্যাখ্যা; entryGROUP BY (account, cost_center),Cr 2120 Σ net;employee_ledgerএকই transaction-এ;idempotency_keyperiod-ধরে; posting_date মাসের শেষ দিন। Section ৫-এর পনেরোটি test সবুজ।৪. Payment — bank file (format adapter), অধ্যায় ১৪-এর
allocationsreuse (document_type = payroll_run), ফেরত transfer, কর্মীর bank account verify-এর নিয়ম (অধ্যায় ১৬-এর supplier-এর মতোই — একই table নকশা?)।৫. Arrears / off-cycle / final settlement — তিনটি
run_type, একই compute/post; posted run immutable; payslip snapshot + hash; কর্মী ছাড়লে loan balance, gratuity, bonus accrual একসাথে।৬. Provisions — bonus accrual, gratuity; bonus run-এ
Dr 2175, খরচ নয়; period close checklist-এ hook।৭. Statutory —
statutory_remittances, TDS ও PF report run_lines থেকে (entry থেকে নয় — entry-তে নাম নেই);tds_kinddimension 2150-এ; due date সতর্কতা।৮. গোপনীয়তা — GL-এ নাম নেই;
employee_ledger, payslip, run preview আলাদা অনুমতি; audit log কে কার payroll দেখলেন (অধ্যায় ৪৫, ৪৮)।৯. রাতের যাচাই ১০৮–১১৩; আর: (ক) run post চলাকালে HRM attendance update — কোনটা জেতে? (খ) ৫,০০০ কর্মীর run compute < ৩০ সেকেন্ড, post একটা transaction-এ — সম্ভব? না হলে কী? (গ) অধ্যায় ৩৫-এর জন্য
payroll_run_lines-এproject_idsplit-এর জায়গা।৩ আর ৮ একসাথে আসল পরীক্ষা। Entry aggregated আর subledger detailed — একই transaction-এ, একই সংখ্যা, অথচ দুটো আলাদা অনুমতিতে। যদি সুবিধার জন্য GL line-এ
employee_idরাখেন, ছয় মাস পরে ledger report-এ সবার বেতন সবাই দেখবেন; যদি subledger না রাখেন, প্রথম ফেরত আসা transfer-এই “কার টাকা” প্রশ্নের উত্তর থাকবে না। GL মোট, subledger নাম, একই transaction, আলাদা দরজা — এটা পারলে অধ্যায় ৩৬-এর Subledger Architecture-এ payroll হবে সবচেয়ে পরিষ্কার উদাহরণ।
১০. Summary Card
চার সংখ্যা
gross খরচ (5110 / 5210, cost center-ধরে)
deductions খরচ নয় — TDS 2150, PF 2170, loan 1180, absence (gross-এই কম)
net 2120 Salary Payable → কর্মীর হাতে
employer cost খরচ — PF 5215 → 2170, bonus 5216 → 2175, gratuity 5217 → 2530Entry
run (মাসের শেষ দিন) Dr 5110, 5210 (gross) Dr 5215 (employer)
Cr 2150 (TDS) Cr 2170 (PF দুই অংশ) Cr 1180 (loan) Cr 2120 (net)
pay Dr 2120 / Cr 1120 ফেরত: Dr 1120 / Cr 2120 [কর্মী]
remit Dr 2150 / Cr 1120; Dr 2170 / Cr 1120
bonus মাসিক Dr 5216 / Cr 2175; দেওয়ার মাসে Dr 2175 / Cr 2120তিন স্তর
GL 2120 (এক line, নাম নেই) == Σ employee_ledger == Σ run net − Σ allocation + Σ return
GL 1180 == Σ employee loan balanceনিয়ম
posting_date = কাজের মাসের শেষ দিন; payment পরের মাসে
prorate component-ধরে; PF earned basic-এ
posted run বদলায় না — arrears / off-cycle; payslip snapshot
compute ≠ approve; approval_limits; bank account verify আলাদা মানুষDeveloper checklist
□ pay_components: kind, calc, prorate, pf_base, taxable, gl_account — data, কোড নয়
□ salary_structures effective-dated
□ computeRun: entry নেই; net < 0 → error; input_hash
□ approve: by ≠ computed_by; limit; variance ব্যাখ্যা
□ post: GROUP BY (account, cost_center); Cr 2120 Σ net; employee_ledger একই transaction; idempotency period-ধরে
□ posting_date মাসের শেষ দিন
□ payment allocation কর্মী-ধরে; ফেরত entry; bank verify
□ loan 1180 + schedule; bonus 2175; gratuity 2530
□ arrears / off-cycle / final — run_type; posted immutable
□ payslip snapshot + hash
□ statutory report run_lines থেকে; tds_kind dimension
□ GL-এ employee_id নেই; ledger আলাদা অনুমতি; audit log
□ 2120 / 1180 control: হাতে JV block
□ রাতে: ১০৮ 2120, ১০৯ 1180, ১১০ entry ↔ lines, ১১১ অচেনা source, ১১২ period/payroll, ১১৩ remit dueপরবর্তী অধ্যায়
অধ্যায় ৩০ — Fixed Asset Accounting: অধ্যায় ১৫-এর তিন প্রশ্নের দ্বিতীয়টা — “বহু বছর ব্যবহার হবে” — এতদিন শুধু Dr 1510 লিখে রেখে দিয়েছি; laptop-এর ৩,৬০,০০০ Balance Sheet-এ বসে আছে, অথচ প্রতি মাসে তার একটা অংশ ক্ষয় হচ্ছে। সেই ক্ষয়ের নাম depreciation — মাসে মাসে খরচ, bill ছাড়া, payment ছাড়া, শুধু সময়ের জন্য। আর একটা register: প্রতিটি asset-এর জন্ম (capitalization), জীবন (depreciation, transfer, impairment), মৃত্যু (disposal — লাভ না ক্ষতি)। Inventory-র মতোই একটা subledger যার অঙ্ক system হিসাব করে — কিন্তু এবার প্রতিটি সারি বছরের পর বছর বাঁচে।