Skip to Content
Go Realm v1 is released 🎉
Accountingবই (Print Edition)অধ্যায় ২৫: Adjusting Entry

অধ্যায় ২৫ — 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

প্রকারDrCrbasisreversal
Accrued expenseExpense2135 Accruedtemplate / PO / estimateহ্যাঁ
Accrued revenue1170 UnbilledRevenuecontract positionনা (invoice-এ)
Prepaid amortizationExpense1150 Prepaidprepaid_itemsনা
Revenue recognition2180 Deferred (বা 1170)Revenueobligationনা
Depreciation529015x5 Accum. Dep.asset registerনা
ProvisionExpenseProvision liability / contra-assetনীতি, agingনা
Estimate change± আগের accrual/provision-এর accountনতুন তথ্য
Reclass (পথ খ)25102520scheduleহ্যাঁ

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 TEXT
period_end_steps (config, company-ধরে) step_key, step_no, enabled, depends_on (step_keys), kind (auto | manual | check), handler

Checklist 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 ÷ months
journal_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; ✗ → blocked

Blocked = মানুষের কাজ বাকি; 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 কোডে hardcodecompany-ধরে আলাদা ধাপ → 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_key UNIQUE; চারটি 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_adjustments document — kind, basis NOT NULL, threshold approval (দুজন), duplicate সতর্কতা, auto_reverse; estimate_change refers_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) UNIQUE

Manual

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 শেষ।