অধ্যায় ২৫ — Adjusting Entry
Volume 1 · Part 3 — Financial Statements · Chapter 25
পূর্বশর্ত: অধ্যায় ১৭ (recognition job), অধ্যায় ১৮ (amortization, accrual, reversal, চার job-এর ক্রম), অধ্যায় ২৪ (worksheet-এর adjustments column, pack-এর precondition)
১. Learning Objective
এই অধ্যায় শেষে আপনি পারবেন:
Adjusting entry-র সংজ্ঞা — period-এর শেষে, document নয়, হিসাব থেকে, সময়ের ফাঁক মেটাতে — আর যা adjusting নয়
সাতটি প্রকার: accrued expense, accrued revenue, deferral (prepaid/deferred), depreciation, provision/allowance,
estimate-এর সংশোধন, reclassification — প্রতিটির entry, basis, reversal হয় কি না
Reversing entry বনাম adjusting বনাম correcting — তিনটি আলাদা জিনিস, কখন কোনটা
Depreciation-এর মাসিক entry — asset register-এর ন্যূনতম কাঠামো (পুরোটা অধ্যায় ৩০)
Estimate ভুল হলে (accrual 12,000, bill 12,800) — সংশোধন কোন মাসে, materiality
মাসের শেষের checklist — ক্রম, নির্ভরতা, প্রতিটি ধাপ idempotent, ফল period_end_runs-এ
আধাআধি ভাঙলে আবার শুরু থেকে চালানো কেন নিরাপদ — আর কোন ধাপে নয়
Auto-generated বনাম manual adjusting entry — দ্বিতীয়টার review, approval, basis বাধ্যতামূলক
Adjusting entry-র নিজের যাচাই: GL == Σ schedule (1150, 2135, 1170, 2180, 15x5)সময়: পড়া ৪৫ মিনিট + অনুশীলন ৫০ মিনিট।
২. Concept Explanation
সংজ্ঞা — তিনটি শর্ত
অধ্যায় ২৪-এর worksheet-এর মাঝের column-এ সাতটা entry ছিল। তাদের মিল:
১. period-এর শেষ দিনে posting_date = period end
২. document থেকে নয়, হিসাব থেকে invoice/bill/receipt নেই; schedule, template, register, position আছে
৩. সময়ের ফাঁক মেটায় "ঘটেছে কিন্তু কাগজ নেই" বা "কাগজ আছে কিন্তু এ মাসের নয়"তিনটিই লাগে। মাসের ২০ তারিখের bill adjusting নয় (document)। ৩১ তারিখে হাতে লেখা “Dr 5260 / Cr 1110 — travel” adjusting নয় (ফাঁক মেটায় না, ঘটনা লেখে)। ০১ তারিখের reversal adjusting নয় (period-এর শুরু; নিচে)।
Accrual accounting-এর পুরো ধারণা (অধ্যায় ১৭) এই entry-গুলোতে বাস্তব হয়: document যে মাসে আসে আর ঘটনা যে মাসে ঘটে — পার্থক্যটা adjusting entry-তে লেখা। এগুলো না থাকলে হিসাব cash basis-এর কাছাকাছি — অধ্যায় ২৪-এর unadjusted ক্ষতি 1,45,700।
সাতটি প্রকার
# প্রকার entry (মাসের শেষে) basis reversal?
── ───────────────────── ──────────────────────────────── ────────────────────── ─────────
১ Accrued expense Dr Expense / Cr 2135 Accrued template / PO / estimate হ্যাঁ, ০১-এ
(খরচ হয়েছে, bill নেই) অধ্যায় ১৮
২ Accrued revenue Dr 1170 Unbilled / Cr Revenue contract position না — invoice-এ সমন্বয়
(কাজ হয়েছে, invoice নেই) অধ্যায় ১৭ (Dr A/R / Cr 1170)
৩ Deferral — expense Dr Expense / Cr 1150 Prepaid prepaid_items schedule না
(টাকা আগে, খরচ ধাপে) অধ্যায় ১৮ (amortization)
৩' Deferral — revenue Dr 2180 Deferred / Cr Revenue contract / obligation না
(invoice আগে, আয় ধাপে) অধ্যায় ১৩, ১৭ (recognition)
৪ Depreciation Dr 5290 / Cr 15x5 Accum. Dep. asset register না
(asset-এর ক্ষয়) অধ্যায় ৩০; এখানে ন্যূনতম
৫ Provision / allowance Dr Expense / Cr Provision (liability aging, নীতি, ঘটনা না; পরে ব্যবহার / release
(সম্ভাব্য দেনা, অনিশ্চিত) বা contra-asset) অধ্যায় ৫৯
৬ Estimate-এর সংশোধন আগের accrual/provision ± পার্থক্য নতুন তথ্য — (এ মাসে, আগের মাসে নয়)
৭ Reclassification Dr 2510 / Cr 2520 (loan current) schedule হ্যাঁ, বা প্রতি মাসে recompute
(উপস্থাপনার জন্য GL-এ) অধ্যায় ২১-এর পথ খ; A/R credit → liability (পথ খ)প্রথম চারটি Part 2 আর অধ্যায় ২১-এ লেখা হয়ে গেছে — এই অধ্যায় সেগুলোকে একটা পরিবারে আনে। ৫ পরে (অধ্যায় ৫৯); ৬ আর ৭ নতুন।
Reversing entry — adjusting-এর ছায়া
অধ্যায় ১৮-এর accrual-এর reversal (০১ তারিখে, স্বয়ংক্রিয়) — এটা adjusting নয়, adjusting-এর ফল। পার্থক্য পরিষ্কার রাখুন:
adjusting ৩১-১২ Dr 5230 12,500 / Cr 2135 12,500 period end; হিসাব; ফাঁক মেটায়
reversing ০১-০১ Dr 2135 12,500 / Cr 5230 12,500 period start; যান্ত্রিক; ফাঁক "খোলে" যাতে bill স্বাভাবিকভাবে post হয়
correcting যেকোনো আগের ভুল entry-র উল্টো + ঠিক ভুল; অধ্যায় ৪৩কোন adjusting-এর reversal হয়: যেগুলোর “আসল document পরে আসবে” — accrued expense (bill আসবে), কখনো accrued revenue (invoice আসবে — এই বইয়ে নয়, 1170 সমন্বয় invoice-এ)। যেগুলোর হয় না: deferral (schedule নিজেই কমায়), depreciation (কখনো document আসে না), provision (ব্যবহার বা release)।
Depreciation — ন্যূনতম, এই অধ্যায়ের জন্য
Laptop 2,40,000, ৩৬ মাস, straight-line → 6,667/মাস; furniture 80,000, ৬০ মাস → 1,333/মাস। Entry:
JV-12-0025 posting_date 31-12, source = depreciation
Dr 5290 Depreciation 8,000
Cr 1515 Accum. Dep. — Computer 6,667
Cr 1525 Accum. Dep. — Furniture 1,333যা লাগে — একটা asset register: প্রতিটি asset, cost, তারিখ, useful life, method, accumulated। Balance Sheet-এর 1515-এর নিচে “কোন asset-এর কত” (অধ্যায় ২১-এর “ছবির নিচে তালিকা”) এখান থেকেই। Disposal, revaluation, impairment, partial-month, component — অধ্যায় ৩০। এখানে শুধু মাসিক job আর GL == Σ register।
একটা সূক্ষ্মতা ডিসেম্বরে: furniture 80,000 → DN-এ 72,000 (অধ্যায় ১৯)। Depreciation base বদলাল — 72,000 ÷ 60 = 1,200। এই বইয়ে ডিসেম্বরে 1,333-ই রাখা হয়েছে (DN ২০-১২, মাসের depreciation মাসের শুরুর base-এ — নীতি); জানুয়ারি থেকে 1,200। অধ্যায় ৩০-এ নিয়ম।
Estimate ভুল — কোন মাসে ঠিক হয়
অধ্যায় ১৮: নভেম্বরের accrual 12,000, bill 12,800 — 800 ডিসেম্বরে। নিয়ম:
estimate-এর ভুল → যে মাসে জানা গেল, সেই মাসে (prospective) IAS 8: change in estimate
হিসাবের ভুল → যে মাসের, সেই মাসে (খোলা থাকলে); নইলে অধ্যায় ৪৩/২৩ (error)দুটোর পার্থক্য: 12,000 লেখার সময় যা জানা ছিল তাতে 12,000-ই ঠিক ছিল — estimate। 12,000-এর জায়গায় 21,000 টাইপ — error। Estimate-এর ভুল কখনো আগের মাস খুলে ঠিক করা হয় না — সব estimate-ই ভুল, শুধু কম-বেশি; খুলতে থাকলে কোনো মাস বন্ধ হবে না।
Materiality — 800 চুপচাপ; 8,000 (accrual-এর ৬৫%)? তবু এ মাসে, কিন্তু template-এর basis review। কখন “আগের মাস reopen”? প্রায় কখনো নয় — শুধু error, material, period খোলা, pack final নয় (অধ্যায় ২৬)।
Reclassification adjusting — GL-এ, না report-এ
অধ্যায় ২১-এ দুটো পথ ছিল — loan-এর current portion report-এ হিসাব (পথ ক) বা মাসের শেষে JV (পথ খ)। পথ খ নিলে এটা adjusting entry #৭:
৩১-১২ Dr 2510 Bank Loan 2,40,000 / Cr 2520 Current Portion of Loan 2,40,000
০১-০১ reversal (পরের মাসে আবার recompute)Reversal-সহ কারণ প্রতি মাসে অঙ্ক বদলায় — recompute সহজ, delta বের করা কঠিন। একই রীতিতে A/R-এর credit balance → 2170 (পথ খ)। এই বইয়ে পথ ক (report-এ); পথ খ-এর জন্য এই এক প্রকার যথেষ্ট। যেটাই নিন — একটা।
Auto বনাম manual
সাতটির মধ্যে চারটি স্বয়ংক্রিয় — schedule/register/position/template থেকে job (recognition, amortization, depreciation, template accrual, reclass)। বাকি manual — হিসাবরক্ষক লেখেন: এককালীন accrual (subcontractor 40,000), provision, estimate-সংশোধন। Manual-এর নিয়ম কড়া:
source_type ∈ adjusting set (manual_accrual, provision, estimate_change) — 'manual' নয়
basis TEXT NOT NULL কিসের ভিত্তিতে — PO নম্বর, email, হিসাব
reversal flag স্পষ্ট accrual হলে auto_reverse_on
approval দ্বিতীয় ব্যক্তি; threshold-এর উপরে (config)
period end posting_date নইলে adjusting নয়, সাধারণ JVঅধ্যায় ২৪-এর appendix-এ “adjusting entries + basis” — এই column-এর জন্য।
মাসের শেষের checklist — ক্রম কেন
অধ্যায় ১৮-এর চারটি job-এর ক্রম এবার পুরো checklist:
ধাপ কাজ নির্ভরতা ফল
─── ────────────────────────────────────── ──────────────────────────────── ─────────────────
০ period খোলা? আগের period-এর reversal হয়েছে? (period open, অধ্যায় ২৬) —
১ সব document post? draft entry-র তালিকা — count; ০ হওয়া উচিত
২ Bank reconciliation (প্রতিটি account) ১ reconciled? (অধ্যায় ১২)
৩ Subledger == GL: A/R, A/P, advance, VAT ১ যাচাই ৩০, ৫১ …
৪ Revenue recognition ১, ৩ (invoice সব post) entries, Σ
৫ Prepaid amortization ১ entries, Σ
৬ Accruals — template + manual ১, ২ (bank-এ যা গেছে, accrual নয়) entries, Σ
৭ Depreciation ১ (asset-এর bill সব post) entries, Σ
৮ Provision / estimate-সংশোধন (manual) ৪–৭ (আগে স্বয়ংক্রিয়, তারপর হাতে) entries, approval
৯ Reclass (পথ খ হলে) ৪–৮ entries
১০ Adjusted TB + যাচাই (1150, 2135, 1170, 2180, 15x5 == Σ schedule) ৪–৯ ✓/✗
১১ Reporting pack (অধ্যায় ২৪) ১০ সব ✓ pack draft
১২ Review → final → lock (অধ্যায় ২৬) ১১ closedক্রমের যুক্তি: document আগে, হিসাব পরে, যাচাই শেষে। Accrual (৬) bank reconciliation (২)-এর পরে — কারণ যে bill-এর টাকা ব্যাংক থেকে গেছে (direct debit) সেটা accrual নয়, reconciliation থেকে post হয়। Depreciation (৭) সব asset bill post-এর পরে। Manual (৮) স্বয়ংক্রিয়গুলোর পরে — হিসাবরক্ষক দেখেন কী হয়েছে, তারপর কী বাকি।
Idempotent — আধাআধি ভাঙলে
ধাপ ৬ চলার মাঝে server গেল। ৩টা accrual post হয়েছে, ২টা হয়নি। আবার চালালে? প্রতিটি ধাপ idempotent — দ্বিতীয়বার চালালে যা হয়ে গেছে তা আবার হয় না:
recognition obligation-ধরে: recognized_to_date, period — একই (obligation, period) দুবার নয়
amortization prepaid_item-ধরে: (item, period) UNIQUE
accrual template-ধরে: (template, period) UNIQUE; manual: নিজের নম্বর
depreciation asset-ধরে: (asset, period) UNIQUE
reclass (rule, period) UNIQUEপ্রতিটি job-এর entry-তে একটা idempotency_key = (source_type, source_id, period) — journal_entries-এ UNIQUE (অধ্যায় ৪৬-এর আগাম)। আবার চালালে বাকি ২টা হয়, আগের ৩টা skip। “শুরু থেকে আবার চালানো নিরাপদ” — এটাই checklist-এর প্রথম নকশা-নিয়ম।
যেখানে নয়: manual ধাপ (৮) — মানুষ দুবার একই accrual লিখতে পারেন; UI-তে “এই period-এ এই account-এ এই অঙ্কের accrual আছে” সতর্কতা, আর basis-এ duplicate খোঁজা।
৩. Accounting Rule
Adjusting entry
posting_date = period end; document নয়, হিসাব; সময়ের ফাঁক
source_type ∈ {recognition, amortization, accrual, manual_accrual, depreciation, provision, estimate_change, reclass}
'manual' কখনো adjusting নয়প্রকার ও entry
| প্রকার | Dr | Cr | basis | reversal |
|---|---|---|---|---|
| Accrued expense | Expense | 2135 Accrued | template / PO / estimate | হ্যাঁ |
| Accrued revenue | 1170 Unbilled | Revenue | contract position | না (invoice-এ) |
| Prepaid amortization | Expense | 1150 Prepaid | prepaid_items | না |
| Revenue recognition | 2180 Deferred (বা 1170) | Revenue | obligation | না |
| Depreciation | 5290 | 15x5 Accum. Dep. | asset register | না |
| Provision | Expense | Provision liability / contra-asset | নীতি, aging | না |
| Estimate change | ± আগের accrual/provision-এর account | নতুন তথ্য | — | |
| Reclass (পথ খ) | 2510 | 2520 | schedule | হ্যাঁ |
Estimate বনাম error
তখন যা জানা ছিল তাতে ঠিক → estimate → যে মাসে জানা গেল, সেই মাসে (prospective)
তখনই ভুল → error → ওই মাসে (খোলা) / correction (অধ্যায় ৪৩) / prior-period (অধ্যায় ২৩)Checklist
document → reconciliation → subledger == GL → recognition → amortization → accrual → depreciation → manual → reclass
→ adjusted TB + schedule যাচাই → pack → lock
প্রতিটি স্বয়ংক্রিয় ধাপ idempotent: (source_type, source_id, period) UNIQUE
manual: basis NOT NULL, approval, period-end dateযাচাই — GL == Σ schedule
1150 == Σ prepaid_items open 2135 == Σ accruals unreversed 1170 == Σ max(−position, 0)
2180 == Σ max(position, 0) 15x5 == Σ asset.accumulated 2520 == Σ schedule ১২ মাস (পথ খ)৪. Real Business Example
ডিসেম্বর ২০২৫ — checklist চালানো
হিসাবরক্ষক ০২-০১-এ শুরু করলেন। প্রতিটি ধাপের ফল period_end_runs-এ:
PERIOD-END RUN — ডিসেম্বর ২০২৫ run #3 (আগের দুটো আধাআধি — নিচে)
ধাপ কাজ শুরু শেষ ফল অবস্থা
─── ──────────────────────── ──────── ──────── ─────────────────────────────────────────── ──────
০ period open? 02-01 02-01 Dec open; Nov closed; reversals 01-12 ✓ (২টা) ✓
১ draft entries 02-01 02-01 ২টা draft: JV-12-0019 (test), PB-12-0030 ✗ → 0
→ JV-12-0019 মুছল; PB-12-0030 post ✓
২ bank reconciliation 02-01 03-01 Prime ✓ (outstanding 24,000); City ✓; cash ✓ ✓
৩ subledger == GL 03-01 03-01 A/R −11,500 == Σ party ✓; A/P 22,000 ✓;
2160 1,00,000 ✓; 1140 0 ✓; VAT ✓ ✓
৪ recognition 03-01 03-01 JV-12-0026 নদী 3,00,000 (2180 1,20,000 + 1170
1,80,000); JV-12-0027 ABC 10,000 ✓ 2 entries
৫ amortization 03-01 03-01 JV-12-0021 PI-0007 5,000 ✓ 1 entry
৬ accruals 03-01 03-01 template: JV-12-0022 DESCO 12,500, JV-12-0023 ISP 8,000
manual: JV-12-0024 subcontractor 40,000
basis "PO-0031, কাজ গৃহীত 28-12", approved CFO ✓ 3 entries
৭ depreciation 03-01 03-01 JV-12-0025 8,000 (laptop 6,667, furniture 1,333) ✓ 1 entry
৮ provision / estimate 03-01 03-01 কিছু নেই; নভেম্বরের DESCO estimate ভুল 800 —
ডিসেম্বরের 5230-তে থাকল (materiality) ✓ 0
৯ reclass — — পথ ক — report-এ; ধাপ skip (config) —
১০ adjusted TB + যাচাই 03-01 03-01 TB 55,08,940 ✓; 1150 50,000 == PI-0007 ✓;
2135 60,500 == 3 accruals ✓; 1170 1,80,000 ==
নদী position ✓; 2180 80,000 == ABC ✓;
1515 13,333 + 1525 2,667 == register ✓ ✓
১১ reporting pack 04-01 04-01 pack v1 draft → reviewed (অধ্যায় ২৪) ✓
১২ final → lock — — অপেক্ষা: subcontractor bill (১০-০১) — CFO চান দেখে pendingদুটো আধাআধি run — কী হয়েছিল
run #1 02-01 17:40 ধাপ ১-এ থামল: draft ২টা। হিসাবরক্ষক বাড়ি গেলেন। status: blocked at 1
run #2 03-01 10:05 ধাপ ৬-এ server restart — DESCO post হয়েছে, ISP হয়নি, manual হয়নি
status: failed at 6; posted: JV-12-0022
run #3 03-01 10:30 শুরু থেকে: ধাপ ০–৫ আবার — সব skip (idempotency key মিলল: recognition (নদী, Dec),
(ABC, Dec); amortization (PI-0007, Dec) — ০টা নতুন entry)
ধাপ ৬: DESCO skip (template, Dec আছে); ISP post; manual — হিসাবরক্ষক লিখলেন
ধাপ ৭–১১ স্বাভাবিকRun #3 শুরু থেকে চালানো নিরাপদ ছিল — কারণ ধাপ ৪, ৫, ৬-এর প্রতিটি entry-র key ছিল। যদি না থাকত: নদীর 3,00,000 দুবার, PI-0007 দুবার — ডিসেম্বরের লাভ 3,95,800। Idempotency এখানে “ভালো অভ্যাস” নয়, শুদ্ধতার শর্ত।
সাতটি entry — basis সহ (pack-এর appendix)
Ref source_type Dr / Cr basis reverse
────────── ────────────── ────────────────────────────────────── ──────────────────────────────────── ───────
JV-12-0021 amortization 5130 5,000 / 1150 5,000 PI-0007: 60,000 ÷ 12, মাস 2/12 —
JV-12-0022 accrual 5230 12,500 / 2135 12,500 template DESCO: শেষ bill 12,800 → 12,500 01-01
JV-12-0023 accrual 5240 8,000 / 2135 8,000 template ISP: চুক্তি 8,000 01-01
JV-12-0024 manual_accrual 5270 40,000 / 2135 40,000 PO-0031, acceptance 28-12, approved CFO 01-01
JV-12-0025 depreciation 5290 8,000 / 1515 6,667, 1525 1,333 register: FA-0001 (36m), FA-0002 (60m) —
JV-12-0026 recognition 2180 1,20,000, 1170 1,80,000 / 4110 3,00,000 contract C-0007 milestone 2, 100% —
JV-12-0027 recognition 2180 10,000 / 4120 10,000 obligation ABC maint. 4/12 —প্রতিটি সারির শেষ দুই column — basis, reverse — auditor-এর দুটো প্রশ্ন, আগেই উত্তর দেওয়া।
জানুয়ারিতে — estimate-এর সংশোধন দুটো
১০-০১ subcontractor-এর bill 46,000 (+VAT) এল; accrual ছিল 40,000; reversal ০১-০১-এ হয়ে গেছে
PB-01-0004 Dr 5270 46,000, Dr 1160 6,900 / Cr 2110 52,900 ← স্বাভাবিক
জানুয়ারির 5270: −40,000 + 46,000 = 6,000 ← estimate-এর ভুল, জানুয়ারিতে; ডিসেম্বর অপরিবর্তিত
6,000 / 40,000 = 15% — template নয়, manual; পরের বার PO-র সাথে VAT-বহির্ভূত অঙ্ক নিশ্চিত
১৪-০১ DESCO bill 12,100; accrual 12,500 → −400 জানুয়ারিতে ← আবার ছোট; template basis ঠিক আছেকোনোটাতেই ডিসেম্বর খোলা হলো না — pack reviewed, লাভ 90,800 থাকল। CFO-র “subcontractor bill দেখে final করব” — দেখলেন, 6,000-এর জন্য reopen নয়, final করলেন ১০-০১।
৫. Implementation — Software ও Database
period_end_runs — checklist-এর state
period_end_runs
id, company_id, period_id, run_no
started_at, started_by, finished_at
status VARCHAR(20) -- running | blocked | failed | completed
current_step SMALLINT
UNIQUE (company_id, period_id, run_no)
period_end_run_steps
run_id, step_no, step_key (draft_check | bank_recon | subledger_check | recognition | amortization
| accrual | depreciation | manual_adjust | reclass | tb_check | pack | lock)
started_at, finished_at
status VARCHAR(20) -- pending | running | done | skipped | blocked | failed
result JSON -- {entries: [...], total: …, checks: {...}, message}
blocked_reason TEXTperiod_end_steps (config, company-ধরে)
step_key, step_no, enabled, depends_on (step_keys), kind (auto | manual | check), handlerChecklist data — কোন company-তে reclass নেই (পথ ক), কোনটায় provision আছে; ক্রম ও নির্ভরতা table-এ, orchestration generic।
Orchestration — শুরু থেকে, প্রতিবার
runPeriodEnd(company, period, by):
যাচাই: period.status == 'open'; আগের period closed বা soft_closed (অধ্যায় ২৬)
run = INSERT period_end_runs (run_no = আগেরটা + 1, status = running)
প্রতিটি step (step_no ক্রমে, enabled):
যদি depends_on-এর কোনোটা done নয় → step blocked, run blocked, থামুন
step.status = running
try:
result = handler(company, period) -- idempotent
step.status = result.blocked ? 'blocked' : 'done'
যদি blocked → run.status = 'blocked', থামুন (draft আছে, reconciliation বাকি …)
catch:
step.status = 'failed'; run.status = 'failed'; throw
run.status = 'completed'প্রতিবার ধাপ ০ থেকে — resume নয়। কারণ: ধাপ ৩ (subledger == GL) run #2-এ ✓ ছিল; মাঝে কেউ post করলে run #3-এ ✗ হতে পারে। Skip-এর কাজ handler-এর (idempotency), orchestration-এর নয়। Handler-গুলো সস্তা হলে (আর হওয়া উচিত — সব period-ধরে query) পুনরাবৃত্তির দাম নেই।
Handler — চারটি স্বয়ংক্রিয়, একই ছাঁচে
handler_recognition(company, period): -- অধ্যায় ১৭-এর recognizeRevenue()
প্রতিটি active obligation ob:
amt = দরকারি recognition (position থেকে)
যদি amt == 0: চলুন
key = ('recognition', ob.id, period.id)
যদি journal_entries WHERE idempotency_key = key আছে: skip, result.skipped += 1
নইলে post(JV(posting_date = period.end, source = recognition, key)), result.entries += …
return result
handler_amortization: প্রতিটি prepaid_item, key = ('amortization', item.id, period.id) -- অধ্যায় ১৮
handler_accrual: প্রতিটি template, key = ('accrual', template.id, period.id), auto_reverse_on = next.start
+ manual accruals-এর জন্য: এই period-এ manual_accrual যার approval নেই → blocked
handler_depreciation: প্রতিটি asset (active, cost > 0), key = ('depreciation', asset.id, period.id)
amount = monthlyDepreciation(asset, period) — অধ্যায় ৩০; এখানে cost ÷ monthsjournal_entries (+)
idempotency_key VARCHAR(120) NULL
UNIQUE (company_id, idempotency_key)অধ্যায় ৪৬-এর Idempotency-র প্রথম ব্যবহার। Key entry-র সাথে; reversal (reversal_of_id) নিজের key ('reversal', original.id) — অধ্যায় ১৮-এর postReversals()-ও idempotent একই কৌশলে।
Check handler — blocked, failed নয়
handler_draft_check: n = COUNT journal_entries WHERE period AND status = 'draft'; n > 0 → blocked (তালিকা)
handler_bank_recon: প্রতিটি bank account: bank_reconciliations WHERE period AND status = 'reconciled'; নইলে blocked
handler_subledger_check: অধ্যায় ১৪-এর ৩০, ১৬-এর …, ১৯-এর ৫১ — সব চালান; ✗ → blocked, কোনটা
handler_tb_check: TB balanced; 1150/2135/1170/2180/15x5 == Σ schedule; ✗ → blockedBlocked = মানুষের কাজ বাকি; failed = কোড/ডেটা ভাঙা। UI-তে আলাদা রং; blocked-এ “কী করতে হবে” লিংক (draft-এর তালিকা, reconciliation পাতা)।
Manual adjusting entry — document-এর মতো
manual_adjustments
id, company_id, period_id
kind VARCHAR(30) -- manual_accrual | provision | estimate_change | reclass_manual
lines (JV-এর মতো)
basis TEXT NOT NULL
auto_reverse BOOLEAN -- accrual হলে true default
threshold_approval BOOLEAN -- amount > config → দ্বিতীয় approval লাগবে
prepared_by, approved_by, approved_at
status draft | approved | posted
journal_entry_id
postManualAdjustment(m):
যাচাই: m.status == 'approved'; approved_by ≠ prepared_by (threshold-এর উপরে)
posting_date == period.end; basis নয় খালি
duplicate সতর্কতা: একই period, account, ±5% অঙ্কে অন্য manual_adjustment?
post(JV(source_type = m.kind, auto_reverse_on = m.auto_reverse ? next.start : NULL))Handler ৮ (manual_adjust) — যা approved কিন্তু posted নয়, post; যা draft, blocked (তালিকা)। Manual-ও checklist-এর ভিতর দিয়ে — আলাদা পথ নেই।
Estimate change — একটা kind, নিজের নিয়ম
estimate_change:
refers_to → আগের accrual/provision entry (FK)
amount → ± পার্থক্য; posting_date = এই period-এর শেষ
basis → নতুন তথ্য
যাচাই: refers_to-র period ≠ এই period (এই period-এরটা বদলাতে হলে সেটাই edit — post-এর আগে — বা reversal)
আগের period closed হলেও ঠিক আছে — এটাই prospective-এর মানেReversal-সহ accrual-এর জন্য estimate_change লাগে না — bill নিজেই পার্থক্য দেখায় (section ৪-এর 6,000)। Reversal-ছাড়া (provision, depreciation-এর life বদল) — লাগে।
রাতের যাচাই
৮৪. প্রতিটি খোলা period: idempotency_key duplicate → ০টি (UNIQUE-এ আটকায়; তবু)
৮৫. adjusting source_type-এর entry যার posting_date ≠ period.end → ০টি (যাচাই ৮৩-এর কড়া রূপ)
৮৬. manual_adjustments.status = 'posted' কিন্তু journal_entry_id NULL, বা basis খালি → ০টি
৮৭. accrual (auto_reverse) যার reversal পরের period-এ নেই, period খোলা → সতর্কতা (postReversals চলেনি?)
৮৮. GL == Σ schedule (1150, 2135, 1170, 2180, 15x5) — প্রতি রাতে, শুধু মাসের শেষে নয়
৮৯. period_end_runs status = 'running' > ২ ঘণ্টা → সতর্কতা (আটকে আছে)Test হিসেবে
test "checklist শুরু থেকে দুবার — দ্বিতীয়বার ০ নতুন entry":
runPeriodEnd(Dec); n = count(entries, Dec)
runPeriodEnd(Dec); assert count(entries, Dec) == n
assert run#2.steps[recognition].result.skipped == 2
test "আধাআধি ভাঙা → আবার → ঠিক":
inject_failure(step accrual, after 1st template)
assert raises runPeriodEnd(Dec); assert posted == [DESCO]
runPeriodEnd(Dec)
assert posted == [DESCO, ISP]; DESCO একবার; 2135 == 20,500 (+ manual পরে)
test "blocked ≠ failed":
draft(JV)
r = runPeriodEnd(Dec); assert r.status == 'blocked'; r.steps[draft_check].blocked_reason includes JV
test "accrual bank reconciliation-এর পরে":
unreconcile(Prime, Dec)
r = runPeriodEnd(Dec); assert r.steps[accrual].status == 'pending' (depends_on blocked)
test "manual adjusting-এ basis ও approval বাধ্যতামূলক":
assert rejects manualAdjustment(accrual 40,000, basis = '')
assert rejects post(manualAdjustment(approved_by = prepared_by, amount > threshold))
test "adjusting শুধু period end-এ":
assert rejects post(JV(source = accrual, posting_date = 15-12))
test "estimate-এর ভুল আগের মাস খোলে না":
close(Nov); bill(Dec, DESCO 12,800, accrual ছিল 12,000)
assert Δ 5230(Nov) == 0; 5230(Dec) includes +800
test "GL == Σ schedule প্রতিটি adjusting পরিবারে":
runPeriodEnd(Dec)
assert GL(1150) == Σ prepaid open; GL(2135) == Σ accruals unreversed; GL(1170) == Σ unbilled position
assert GL(2180) == Σ deferred position; GL(1515) + GL(1525) == Σ register.accumulated
test "depreciation register থেকে, asset-ধরে key":
assets = [laptop 2,40,000/36, furniture 80,000/60]
runPeriodEnd(Dec); assert JV(depreciation).lines == [1515 6,667, 1525 1,333, 5290 8,000]
runPeriodEnd(Dec); assert count(depreciation entries, Dec) == 1৬. Financial Statement Impact
Adjusting entry-ই সেই জিনিস যা তিন statement-কে “cash-এর কাছাকাছি” থেকে “কাজের হিসাব”-এ নিয়ে যায়:
প্রকার Income Statement Balance Sheet Cash Flow
───────────────── ─────────────────── ─────────────────────────── ───────────────────
accrued expense খরচ এ মাসে (+) 2135 (+) কিছু নয়; indirect: Δ2135 add back
accrued revenue আয় এ মাসে (+) 1170 (+) কিছু নয়; indirect: Δ1170 বিয়োগ
amortization খরচ ধাপে (+) 1150 (−) কিছু নয়; Δ1150 add back
recognition আয় ধাপে (+) 2180 (−) কিছু নয়; Δ2180 বিয়োগ
depreciation খরচ (+) 15x5 (−, asset নিট কমে) কিছু নয়; add back
provision খরচ (+) liability / contra-asset (+) কিছু নয়; add back
reclass কিছু নয় লাইন বদল, মোট এক কিছু নয়শেষ column-টা দেখুন: কোনো adjusting entry Cash Flow-এর মোট বদলায় না — সবগুলো indirect method-এ যোগ-বিয়োগে কাটাকাটি (অধ্যায় ২২-এর non-cash)। এটা একটা যাচাই: checklist-এর ধাপ ৪–৯-এর আগে ও পরে Δcash এক — না হলে কোনো “adjusting” entry cash account ছুঁয়েছে, যেটা adjusting নয়।
৭. Common Developer Mistakes
| ভুল | কী ঘটে | সঠিক পথ |
|---|---|---|
| Job দুবার চললে দুবার post | লাভ দ্বিগুণ; 2135 দ্বিগুণ | idempotency_key UNIQUE, handler skip |
| Checklist resume (“ধাপ ৬ থেকে”) | ধাপ ৩-এর যাচাই বাসি | শুরু থেকে; handler-এ skip |
| Accrual reconciliation-এর আগে | ব্যাংক থেকে যাওয়া bill-ও accrue — দুবার | depends_on |
| Depreciation asset bill-এর আগে | এ মাসের laptop বাদ | depends_on draft_check; register bill থেকে |
| Manual JV = adjusting (তারিখ ৩১ বলে) | worksheet-এ সব JV; basis নেই | source_type set; manual_adjustments document |
| Manual accrual-এ basis ঐচ্ছিক | ”40,000 কিসের?” — কেউ জানে না | NOT NULL; appendix |
| Estimate-এর ভুলে আগের মাস reopen | কোনো মাস বন্ধ হয় না; pack-এর সংখ্যা বদলায় | prospective; materiality; template basis review |
| Reversal ভুলে গেলে accrual + bill দুবার | খরচ দ্বিগুণ (অধ্যায় ১৮) | auto_reverse_on; যাচাই ৮৭; period open-এ postReversals |
| Reversal-কে adjusting ধরা | worksheet-এ ০১ তারিখ | period end শুধু; যাচাই ৮৫ |
| Adjusting entry cash account ছোঁয় | ”accrual” আসলে payment | Δcash অপরিবর্তিত যাচাই (section ৬) |
| Blocked আর failed এক | মানুষের কাজ আর bug এক তালিকায় | দুই status, দুই রং, blocked-এ কী করতে হবে |
| Checklist কোডে hardcode | company-ধরে আলাদা ধাপ → if-else জঙ্গল | period_end_steps data; depends_on |
| GL == Σ schedule শুধু মাসের শেষে | ২৯ তারিখে ভুল, ৩১-এ ধরা, সময় নেই | প্রতি রাতে (৮৮) |
| Provision “মেলানোর জন্য” | লাভ ইচ্ছেমতো | নীতি, basis, approval; অধ্যায় ৫৯ |
| run ‘running’ চিরকাল (crash) | পরের run শুরু হয় না | timeout (৮৯); stale run → failed |
প্রথম আর সপ্তমটা মূল। Idempotency ছাড়া checklist চালানোই বিপজ্জনক — আর checklist চালানোই যদি বিপজ্জনক হয়, কেউ চালাবে না, হাতে করবে, আর হাতে করলে অধ্যায় ১৮-এর সব নিয়ম কাগজে থাকে। আর estimate-এর ভুলে মাস খোলা — যে system-এ এটা সহজ, সেখানে কোনো মাসের সংখ্যা কখনো স্থির হয় না, আর অধ্যায় ২৪-এর pack-এর কোনো অর্থ নেই।
৮. Exercises
সেট ক — entry ও প্রকার
১। প্রতিটির জন্য: adjusting কি না; হলে প্রকার, entry, basis, reversal:
(ক) ৩১-১২ অফিস ভাড়া জানুয়ারির, আজ দেওয়া হলো 65,000
(খ) ৩১-১২ ডিসেম্বরের বিদ্যুৎ, bill ১৪-০১-এ আসবে, অনুমান 12,500
(গ) ৩১-১২ audit fee বছরে 75,000, bill মার্চে — ডিসেম্বরে কত?
(ঘ) ৩১-১২ laptop-এর depreciation
(ঙ) ৩১-১২ ৯০ দিনের বেশি পুরনো A/R 60,000-এর ২০% allowance
(চ) ৩১-১২ নভেম্বরের accrual 12,000 আসলে 21,000 হওয়ার কথা ছিল (টাইপো)
(ছ) ৩১-১২ cash গণনায় 300 কম
(জ) ২০-১২ গ্রাহকের advance invoice-এ সমন্বয়
২। ৩১-০১-২০২৬-এর checklist চালান (হাতে): reversal ০১-০১ (তিনটি);
recognition (নদী invoice হলো — 1170 → A/R; ABC 10,000); amortization
5,000; accrual DESCO 12,000, ISP 8,000; depreciation (furniture এখন
72,000 ÷ 60 = 1,200) 7,867; subcontractor bill 46,000 (document)।
জানুয়ারির 5230, 5240, 5270, 5290? 2135 ৩১-০১-এ?
৩। Audit fee (১-এর গ): তিনটি নীতি — ডিসেম্বরে পুরো 75,000; প্রতি মাসে
6,250; bill এলে। প্রতিটিতে ডিসেম্বর ও মার্চের Income Statement। কোনটা
accrual accounting? কোনটা "smoothing"? আপনার system default কোনটা?সেট খ — checklist
৪। ধাপ ৬ (accrual) ধাপ ২ (bank reconciliation)-এর উপরে নির্ভর করে —
উদাহরণ দিন যেখানে উল্টো ক্রমে দুবার খরচ হয়।
৫। Run #2 ধাপ ৭ (depreciation)-এ ভাঙল, ৩টা asset-এর ২টা post হয়েছে।
Run #3-এ কী হবে? যদি idempotency key (asset, period) না থেকে
(source_type, period) হতো?
৬। Handler-গুলো "period-ধরে query" — recognition 500 contract, amortization
200 item, depreciation 2,000 asset। প্রতিটি asset-এ একটা JV না সব
asset এক JV (2,000 line)? drill-down, reversal, idempotency — কোনটায় কী
সুবিধা?
৭। Checklist-এর কোন ধাপ parallel চলতে পারে (৪, ৫, ৭)? নির্ভরতা graph
আঁকুন। Parallel চালালে idempotency key যথেষ্ট? (অধ্যায় ৪৭-এর আগাম)সেট গ — কোনটা ভুল
৮। JV 31-12: Dr 5230 / Cr 1120 12,500 — "accrual"
৯। recognition job: DELETE previous recognition entries WHERE period; INSERT new
১০। accrual template: reversal ৩১-১২-এই (একই দিন) — "নেট শূন্য, পরিষ্কার"
১১। নভেম্বরের accrual 12,000 → bill 12,800: reopen Nov, UPDATE accrual = 12,800
১২। manual_adjustments.basis VARCHAR(50)
১৩। period_end_runs: run #3 শুরু হলো ধাপ ৬ থেকে, "১–৫ তো হয়ে গেছে"
১৪। depreciation: asset register নেই; JV প্রতি মাসে হাতে 8,000সেট ঘ — নকশা
১৫। period_end_steps company-ধরে config — কিন্তু ধাপ ৩ (subledger == GL) কেউ
disable করলে? কোন ধাপ mandatory, কোনটা optional — কে ঠিক করে?
১৬। Provision (অধ্যায় ৫৯-এর আগাম): warranty provision বিক্রির ২% — auto
(template থেকে) না manual? release কখন? estimate_change কোথায় লাগে?
আজ কোন column রাখবেন?
১৭। Multi-company (৫টা company, একই server): runPeriodEnd() ৫ বার না ১
বার? blocked এক company-তে — বাকিরা থামবে? period_end_runs-এ কী
বদলাবে?
১৮। Checklist-এর UI: ১২ ধাপ, প্রতিটির status, blocked-এ "কী করতে হবে",
failed-এ log, done-এ entries-এর তালিকা। "আবার চালান" button কখন
enabled? কে চালাতে পারে (অধ্যায় ৪৮)?উত্তর আছে Workbook-এর Answer Key, অধ্যায় ২৫-এ।
৯. Developer Challenge
PeriodEndService — অধ্যায় ১৭, ১৮-এর job-গুলো, depreciation, manual adjustment, আর check-গুলো একটা checklist-এ, data-চালিত, idempotent, resumable-by-rerun।
যা যা নকশা করবেন:
১.
period_end_steps(config),period_end_runs,period_end_run_steps;runPeriodEnd()— শুরু থেকে প্রতিবার, depends_on, blocked/failed আলাদা, timeout; UI-র জন্য status feed।২.
journal_entries.idempotency_keyUNIQUE; চারটি auto handler (recognition, amortization, accrual, depreciation) একই ছাঁচে — key, skip, result;postReversals()-ও key দিয়ে; exercise ৬-এর “asset-ধরে JV না এক JV” — সিদ্ধান্ত ও যুক্তি।৩. Asset register ন্যূনতম —
fixed_assets(cost, start, months, method, accumulated, account, dep_account),monthlyDepreciation(); GL == Σ register; অধ্যায় ৩০-এর জন্য কোন column আজ ফাঁকা রাখছেন (disposal, revaluation, component)।৪.
manual_adjustmentsdocument — kind, basis NOT NULL, threshold approval (দুজন), duplicate সতর্কতা, auto_reverse;estimate_changerefers_to; checklist-এর ধাপ ৮-এর ভিতর দিয়েই।৫. Check handler — draft, reconciliation, subledger == GL (Part 2-র সব যাচাই এক জায়গায়, code-ধরে), TB + schedule; blocked_reason-এ “কী করতে হবে” লিংক।
৬. Δcash অপরিবর্তিত যাচাই (section ৬) — ধাপ ৪–৯-এর আগে ও পরে; adjusting entry cash ছুঁলে failed।
৭. রাতের যাচাই ৮৪–৮৯; test — section ৫-এর নয়টি, আর: (ক) ২,০০০ asset-এর depreciation এক query (N+1 নয়); (খ) parallel ধাপ (exercise ৭) দুটো একসাথে — key-তে আটকায়; (গ) manual accrual threshold-এর নিচে এক approval, উপরে দুই।
১ আর ২ নম্বরটাই আসল পরীক্ষা। “শুরু থেকে আবার চালানো নিরাপদ” — এই এক বাক্য মানতে পারলে অধ্যায় ৪৬ (Idempotency) আপনার লেখা হয়ে গেল, আর মাসের শেষ একটা button হলো। না পারলে মাসের শেষ একটা ভয়ের দিন থাকবে, আর ভয়ের দিনে মানুষ হাতে করে — আর হাতে করলে এই বইয়ের Part 2 কাগজে থাকে।
১০. Summary Card
সংজ্ঞা
adjusting = period end + হিসাব (document নয়) + সময়ের ফাঁক; source_type ∈ adjusting set; 'manual' নয়
reversing (০১, যান্ত্রিক) ≠ adjusting ≠ correcting (ভুল, অধ্যায় ৪৩)সাত প্রকার
accrued expense Dr Exp / Cr 2135 template/PO reverse ✓
accrued revenue Dr 1170 / Cr Rev position invoice-এ সমন্বয়
amortization Dr Exp / Cr 1150 prepaid_items —
recognition Dr 2180 / Cr Rev obligation —
depreciation Dr 5290 / Cr 15x5 register —
provision Dr Exp / Cr Prov নীতি release
estimate change ± আগেরটা, এ মাসে নতুন তথ্য prospective — আগের মাস খোলে না
reclass (পথ খ) Dr 2510 / Cr 2520 schedule reverse ✓Checklist
০ open → ১ draft → ২ bank recon → ৩ subledger==GL → ৪ recognition → ৫ amortization → ৬ accrual → ৭ depreciation
→ ৮ manual → ৯ reclass → ১০ TB + schedule → ১১ pack → ১২ lock
document আগে, হিসাব পরে, যাচাই শেষে; data (period_end_steps), depends_on; blocked ≠ failed
প্রতিবার শুরু থেকে; handler idempotent: (source_type, source_id, period) UNIQUEManual
document (manual_adjustments): basis NOT NULL, approval (threshold → দুজন), auto_reverse, period end, duplicate সতর্কতাযাচাই
1150 == Σ prepaid · 2135 == Σ accruals · 1170/2180 == Σ position · 15x5 == Σ register — প্রতি রাতে
adjusting entry Δcash বদলায় নাDeveloper checklist
□ period_end_steps / runs / run_steps; runPeriodEnd() শুরু থেকে; depends_on; timeout
□ idempotency_key UNIQUE; চার handler + reversal একই ছাঁচে
□ fixed_assets ন্যূনতম; monthlyDepreciation(); GL == Σ register
□ manual_adjustments document; estimate_change refers_to
□ check handler: draft, recon, subledger, TB + schedule; blocked_reason
□ Δcash অপরিবর্তিত যাচাই
□ রাতে: ৮৪–৮৯পরের অধ্যায়
Checklist-এর শেষ ধাপ — ১২, lock — এই অধ্যায়ে “pending” রেখে এসেছি। অধ্যায় ২৬ — Opening, Closing ও Period Closing: period-এর জীবনচক্র (open → soft-closed → closed → locked), কে খুলতে পারে, কী log হয়; বছরের শেষে closing entry (4xxx/5xxx → 3300 → 3200) — একবার, idempotent, উল্টানো যায়; পরের বছরের opening — ledger চলমান, না OB entry; আর ১৩তম period, audit adjustment, comparative column বছর পেরিয়ে। Part 3-র শেষ অধ্যায় — এর পরে Volume 1 শেষ।