Skip to Content
Go Realm v1 is released 🎉
Accountingবই (Print Edition)অধ্যায় ১৯: Advance, Credit Note ও Debit Note

অধ্যায় ১৯ — Advance, Credit Note ও Debit Note

Volume 1 · Part 2 — Core Business Accounting · Chapter 19

পূর্বশর্ত: অধ্যায় ১৩ (Sales — cancel বনাম credit note), অধ্যায় ১৪ ও ১৬ (allocation, unapplied, advance-এর সমন্বয়), অধ্যায় ১৫ (Purchase — buildDocumentEntry)


১. Learning Objective

এই অধ্যায় শেষে আপনি পারবেন:

Advance দুই দিকে — customer advance (liability), advance to supplier (asset) — পুরো জীবনচক্র লিখতে Advance, deferred revenue, unapplied receipt — তিন "cousin"-কে আলাদা করতে Credit note (আপনি গ্রাহককে) আর debit note (আপনি supplier-কে) — কখন, কেন, entry কী — বলতে Reversal বনাম credit note: "document ভুল ছিল" বনাম "নতুন ঘটনা ঘটেছে" — সিদ্ধান্ত নিতে Note-কে মূল invoice/bill-এর সাথে line-ধরে বাঁধতে, আর সীমা (invoice-এর বেশি নয়) রাখতে Payment হয়ে যাওয়া invoice-এ credit note — party-র credit balance — সামলাতে (ফেরত / পরের invoice) VAT-এ note-এর প্রভাব: output VAT কমে (CN), input VAT কমে (DN) — note-এর মাসে Supplier-এর credit note আর আপনার debit note — একই ঘটনা, দুই কাগজ — একবার লেখা buildDocumentEntry(doc, ±1) দিয়ে চারটি document (SV, PB, CN, DN) এক rule-এ চালাতে Advance aging, credit note register, party credit balance report — তিনটি তৈরি করতে

সময়: পড়া ৫০ মিনিট + অনুশীলন ৫৫ মিনিট।


২. Concept Explanation

যা যা “অধ্যায় ১৯-এ” বলে রেখেছি

অধ্যায় ১৩ deferred বনাম advance — "invoice হলে সমন্বয় (অধ্যায় ১৯)" অধ্যায় ১৪ সালমার advance 50,000 → JV Dr 2160 / Cr A/R "অধ্যায় ১৯-এর আগাম" অধ্যায় ১৫ laptop ফেরত → DN-10-0006 "অধ্যায় ১৯-এর আগাম" অধ্যায় ১৬ রফিকের advance 40,000 → JV Dr A/P / Cr 1140 অধ্যায় ১৩ invoice ভুল, গ্রাহকের হাতে চলে গেছে → "reversal নয়, credit note"

এগুলো তিনটি document-এর গল্প — advance (টাকা document-এর আগে), credit note (invoice-এর পরে কমানো), debit note (bill-এর পরে কমানো)। তিনটির মিল: কোনোটাই নিজে বিক্রি বা ক্রয় নয়; আগের বা পরের একটা document-কে বদলায়।

Advance — টাকা আগে, document পরে

Customer advance (2160, liability): গ্রাহক টাকা দিলেন, invoice হয়নি। গ্রাহকের কাছে আপনার দেনা — সেবা বা ফেরত।

টাকা এল: Dr 1120 Bank Cr 2160 Customer Advance [গ্রাহক] invoice হলো: Dr 1130 A/R [গ্রাহক] Cr Revenue / 2180, Cr 2140 (স্বাভাবিক) সমন্বয়: Dr 2160 [গ্রাহক] Cr 1130 A/R [গ্রাহক] ← advance খরচ হলো (বা ফেরত: Dr 2160 [গ্রাহক] Cr 1120 Bank)

Advance to supplier (1140, asset): আয়না।

টাকা গেল: Dr 1140 Advance [supplier] Cr 1120 Bank bill এল: Dr Expense/Asset, 1160 Cr 2110 A/P [supplier] (স্বাভাবিক) সমন্বয়: Dr 2110 A/P [supplier] Cr 1140 Advance [supplier] (বা ফেরত: Dr 1120 Bank Cr 1140 Advance [supplier])

দুটো নকশা-সিদ্ধান্ত। প্রথম: advance-এর account-ও party-ধরে — 2160 আর 1140 control account-এর মতো subledger রাখে (কার advance কত)। দ্বিতীয়: সমন্বয় একটা allocation — অধ্যায় ১৪/১৬-এর source_type = 'advance' — সাথে একটা JV যা control account থেকে advance account-এ সরায়। Allocation table বলে কোন invoice-এ, JV বলে GL-এ কত

তিন cousin — advance, deferred, unapplied

তিনটিই “গ্রাহকের কাছে দেনা”, তিনটিই Balance Sheet-এ liability, তিনটি আলাদা:

advance (2160) deferred (2180) unapplied (1130 Cr) ───────────── ────────────── ─────────────── ─────────────────── invoice আছে? না হ্যাঁ হ্যাঁ, কিন্তু মেলে না টাকা এসেছে? হ্যাঁ হয়তো হ্যাঁ কাজ হয়েছে? না না হ্যাঁ (invoice-এর) কী হবে invoice-এ সমন্বয় recognition allocate / ফেরত কে তৈরি করে গ্রাহক, ইচ্ছাকৃত আপনি, আগে invoice ভুল / বেশি payment অধ্যায় ১৯ ১৩, ১৭ ১৪

Unapplied receipt আর advance-এর পার্থক্য সবচেয়ে সূক্ষ্ম — দুটোই “টাকা এল, invoice-এ বাঁধা নেই”। পার্থক্য অভিপ্রায়: advance ইচ্ছাকৃত, ভবিষ্যৎ কাজের জন্য, চুক্তি/quotation-এর বিপরীতে; unapplied দুর্ঘটনা। Software-এ: receipt-এ is_advance পতাকা → Cr 2160, নইলে Cr 1130। পতাকাটা মানুষ দেন — receipt-এর সময়।

Credit note — invoice-এর পরে কমানো

Invoice গেছে, গ্রাহক বলছেন: একটা module পাইনি / দাম বেশি ধরা হয়েছে / পণ্য ফেরত দিচ্ছি / আপনি ছাড় দিতে রাজি হয়েছেন। Invoice ঠিকই ছিল তখন; এখন একটা নতুন ঘটনা। তাই invoice বদলানো নয় — একটা নতুন document, credit note:

CN-12-0001 (against SV-09-0003, করিম) Dr 4180 Sales Returns & Allowances 20,000 ← contra-revenue, এ মাসে Dr 2140 VAT Payable 3,000 ← output VAT কমল Cr 1130 A/R [করিম] 23,000 ← পাওনা কমল allocation: SV-09-0003 credit_note 23,000 → open কমল

তিনটি নিয়ম:

১. সবসময় একটা মূল invoice-এর বিপরীতে, line-ধরে — কোন line, কত পরিমাণ/অঙ্ক ২. মোট credit ≤ মূল invoice (এক invoice-এ বহু CN হতে পারে, যোগফল সীমার ভিতরে) ৩. নিজের gapless নম্বর (CN-), নিজের তারিখ, নিজের মাস — VAT return-এ এ মাসেই

Revenue কমে 4180-এ, note-এর মাসে — সেপ্টেম্বরের 4110 বদলায় না। সেপ্টেম্বর ছাপা হয়ে গেছে; ডিসেম্বরে জানা গেল, ডিসেম্বরেই। (Contract/deferred line-এর CN — 2180 কমে, billed_to_date কমে, revenue নয়; অধ্যায় ১৭-এর position।)

Debit note — bill-এর পরে কমানো

আয়না। Supplier-এর bill post হয়েছে; laptop ত্রুটিপূর্ণ, ফেরত:

DN-10-0006 (against PB-10-0003, টেক সাপ্লাই) Dr 2110 A/P [টেক সাপ্লাই] 1,38,000 ← দেনা কমল Cr 1510 Computer Equipment 1,20,000 ← মূল account-ই কমে Cr 1160 VAT Receivable 18,000 ← input VAT কমল

Sales-এ contra account (4180) — কারণ “কত বিক্রি, কত ফেরত” আলাদা দেখা দরকার। Purchase-এ মূল account-ই কমে — asset ফেরত গেলে asset কমে, খরচ ফেরত গেলে খরচ কমে। (Inventory-তে stock-ও কমে — অধ্যায় ২৭।)

নামের ফাঁদ: একই ঘটনায় supplier আপনাকে “credit note” পাঠান, আপনি নিজের খাতায় “debit note” লেখেন। দুটো কাগজ, একটা entry। আপনার DN আগে (মাল ফেরতের দিনে); তার CN এলে শুধু নম্বর লিখে রাখুন — counterparty_note_no। অধ্যায় ১৬-এ statement মেলেনি ঠিক এই কারণে: আপনার DN ছিল, তার CN ছিল না।

উল্টো দিকও আছে — কম দেখা যায়: আপনি গ্রাহককে debit note (কম bill করেছিলেন, বাড়তি charge) আর supplier আপনাকে debit note (কম bill করেছিল)। কাঠামো একই, চিহ্ন উল্টো। Software-এ চারটিই একটা notes table — section ৫।

Reversal বনাম credit note — সিদ্ধান্তের গাছ

অধ্যায় ১৩-এর cancelInvoice() আর এই অধ্যায়ের credit note — কোনটা কখন:

invoice-এ সমস্যা ├── document-টাই ভুল ছিল (ভুল গ্রাহক, দুবার, ভুল অঙ্ক টাইপ) │ │ │ ├── গ্রাহকের হাতে যায়নি, period খোলা → CANCEL (reversal, একই মাস) │ │ invoice cancelled, নম্বর থাকে │ │ │ └── গ্রাহকের হাতে গেছে / period বন্ধ → CREDIT NOTE পুরো + নতুন invoice │ (তার খাতায় আপনার invoice আছে — │ মুছবেন না, কাটুন) └── document ঠিক ছিল, পরে কিছু ঘটল (ফেরত, বিতর্ক, ছাড়) → CREDIT NOTE, আংশিক বা পুরো, নিজের মাসে

মূল প্রশ্ন: কাগজটা কি পৃথিবীতে বেরিয়ে গেছে? বেরিয়ে গেলে মুছে ফেলা যায় না — গ্রাহকের A/P-তে, তার VAT return-এ আছে। শুধু কাটা যায়, নতুন কাগজ দিয়ে। Reversal মানে “ঘটেনি”; credit note মানে “ঘটেছিল, এখন কমল”। অধ্যায় ৪৩-এ পুরো architecture।

Payment হয়ে যাওয়া invoice-এ credit note

সালমার invoice অক্টোবরে paid। ডিসেম্বরে ১০,০০০ + VAT-এর concession। CN-এর entry একই — কিন্তু allocate করার মতো open invoice নেই:

Dr 4180 10,000 / Dr 2140 1,500 / Cr 1130 [সালমা] 11,500 allocation: কিছু না — SV-10-0001 open 0 সালমার subledger: 11,500 Cr ← credit balance, unapplied note

অধ্যায় ১৪-এর unapplied receipt-এর মতোই: subledger-এ credit, statement-এ বার্তা, দুটো পথ — ফেরত (Dr 1130 / Cr Bank) বা পরের invoice-এ allocate (allocations: document = নতুন invoice, source = credit_note)। ৩০ দিনের বেশি পড়ে থাকলে সতর্কতা — গ্রাহকের টাকা আপনার কাছে।

Proforma — যে invoice invoice নয়

Advance চাওয়ার জন্য “proforma invoice” পাঠানো হয় — quotation-এর ভাইয়ের মতো। এটা accounting document নয়: entry নেই, A/R নেই, VAT নেই, gapless নম্বরের sequence আলাদা (PF-)। Developer-রা এটাকে sales_invoices-এ status = proforma করে রাখেন, তারপর কেউ post করে ফেলে। আলাদা table, বা quotations-এর একটা প্রকার। Advance এলে proforma-র reference থাকে, entry advance-এর।

VAT — note-এর মাসে

Credit note output VAT কমায়, debit note input VAT কমায় — note-এর তারিখের মাসে, মূল invoice-এর মাসে নয়। VAT return-এ আলাদা লাইন (“adjustment”)। দেশভেদে শর্ত: CN-এ মূল invoice-এর নম্বর ও তারিখ লেখা বাধ্যতামূলক, নির্দিষ্ট সময়ের (৬ মাস / ১ বছর) পরে VAT সমন্বয় নয় — config, অধ্যায় ৫৫। Advance-এ VAT — কিছু দেশে advance পাওয়ার সময়েই output VAT দিতে হয়; এই বইয়ে invoice-এ; ব্যতিক্রম অধ্যায় ৫৫।


৩. Accounting Rule

Advance

ঘটনাDebitCredit
Customer advance এলBankCustomer Advance [গ্রাহক]
Invoice-এ সমন্বয়Customer Advance [গ্রাহক]A/R [গ্রাহক]
Advance ফেরতCustomer Advance [গ্রাহক]Bank
Supplier-কে advanceAdvance to Supplier [supplier]Bank
Bill-এ সমন্বয়A/P [supplier]Advance to Supplier [supplier]
Advance ফেরত পেলেনBankAdvance to Supplier [supplier]

Note

ঘটনাDebitCredit
Credit note গ্রাহককেSales Returns & Allowances (বা Deferred), VAT PayableA/R [গ্রাহক]
Debit note supplier-কেA/P [supplier]মূল account (Expense/Asset/Inventory), VAT Receivable
Debit note গ্রাহককে (বাড়তি charge)A/R [গ্রাহক]Revenue, VAT Payable
Credit note supplier থেকে, তার bill কমেA/P [supplier]মূল account, VAT Receivable

সীমা

Σ CN (invoice) ≤ invoice.grand_total line-ধরে: qty ≤ মূল qty − আগের ফেরত Σ DN (bill) ≤ bill.grand_total মূল document cancelled হলে note নয়

Reversal না note

document ভুল + বেরোয়নি + period খোলা → cancel (reversal, একই মাস) নইলে → note, নিজের মাসে

Revenue/VAT-এর মাস

CN: 4180 (contra) note-এর মাসে; মূল মাসের revenue অপরিবর্তিত deferred/contract line হলে 2180 কমে, billed_to_date কমে DN: মূল account কমে, note-এর মাসে VAT: note-এর মাসে, adjustment হিসেবে

Unapplied note

open invoice নেই → party credit balance → ফেরত বা পরের invoice-এ allocate ৩০ দিনে সতর্কতা

৪. Real Business Example

ডিসেম্বর ২০২৫ — পুরনো সুতো বাঁধার মাস

১ ডিসেম্বরে A/R-এর open items (অধ্যায় ১৪-এর অক্টোবর থেকে; নভেম্বরে নদী গ্রুপের invoice ও receipt কাটাকাটি):

SV-09-0003 করিম ট্রেডার্স open 38,000 (due 15-10 — ৪৭ দিন overdue) unapplied রহিম (3,100) ──────── GL 1130 34,900 অধ্যায় ১৬-এ নভেম্বরে করিমের 38,000 আশা করা হয়েছিল — আসেনি। কারণ এ মাসে জানা গেল।

০২-১২ — করিম: “একটা module পাইনি, ৩৮,০০০ দেব না”

ফোন, আলোচনা: module-টা সত্যিই delivery হয়নি (২০,০০০ + VAT)। Invoice সেপ্টেম্বরে ঠিকই ছিল — তখন পরিকল্পনায় ছিল। Document ভুল নয়; নতুন ঘটনা: credit note

CN-12-0001 against SV-09-0003, line 2 (module B), reason: not_delivered Dr 4180 Sales Returns & Allowances 20,000 Dr 2140 VAT Payable 3,000 Cr 1130 A/R [করিম] 23,000 allocation: SV-09-0003 credit_note 23,000 → open 15,000

সেপ্টেম্বরের revenue ৩,৮০,০০০-ই থাকল; ডিসেম্বরের Income Statement-এ 4180-এ ২০,০০০। Reversal করলে সেপ্টেম্বর বদলাত — আর সেপ্টেম্বরের VAT return জমা হয়ে গেছে।

০৫-১২ — রহিম ৩,১০০ ফেরত চাইলেন (অধ্যায় ১৪-এর unapplied)

PV-12-0002 refund, party = customer Dr 1130 A/R [রহিম] 3,100 Cr 1120 Bank — Prime 3,100 রহিমের subledger: 0

Refund হলো payments-এ kind = payment, party_type = customer — supplier-কে payment-এর মতোই, শুধু control account 1130। Allocation: unapplied receipt RV-10-0004-এর বিপরীতে (source = refund)।

০৮-১২ — সাগর লিমিটেড: জানুয়ারির project-এর advance ১,০০,০০০

RV-12-0003 is_advance = true, reference: proforma PF-12-0002 Dr 1120 Bank — Prime 1,00,000 Cr 2160 Customer Advance [সাগর] 1,00,000 A/R স্পর্শ হয়নি। 2160 subledger: সাগর 1,00,000

Proforma PF-12-0002 — কোনো entry নেই, sales_invoices-এ নেই।

১০-১২ — করিম ১৫,০০০ দিলেন

RV-12-0004 Dr 1120 Bank 15,000 Cr 1130 A/R [করিম] 15,000 allocation: SV-09-0003 receipt 15,000 → open 0 → paid SV-09-0003: 1,38,000 = receipt 1,00,000 + CN 23,000 + receipt 15,000 ✓

১৫-১২ — সালমা: paid invoice-এ concession ১০,০০০ + VAT

CN-12-0002 against SV-10-0001 (paid), reason: price_adjustment Dr 4180 Sales Returns & Allowances 10,000 Dr 2140 VAT Payable 1,500 Cr 1130 A/R [সালমা] 11,500 allocation: নেই — open invoice নেই সালমার subledger: 11,500 Cr ← unapplied credit note statement-এ: "আপনার হিসাবে 11,500 জমা; পরের invoice-এ সমন্বয় হবে"

১৮-১২ — টেক সাপ্লাইয়ের credit note “CN-TS-0412” এল (laptop ফেরতের)

আমাদের খাতায়: DN-10-0006, 1,38,000 — অক্টোবরেই লেখা তার CN: 1,38,000, 15-12 entry: নেই DN-10-0006.counterparty_note_no = 'CN-TS-0412', counterparty_note_date = 15-12 supplier statement (অধ্যায় ১৬): এবার মিলবে

২০-১২ — অফিস মার্টের একটা চেয়ার ভাঙা: ৮,০০০ + VAT ফেরত; bill নভেম্বরে paid

DN-12-0003 against PB-11-0002, line 3, qty 1, reason: damaged Dr 2110 A/P [অফিস মার্ট] 9,200 Cr 1520 Furniture & Fixtures 8,000 Cr 1160 VAT Receivable 1,200 allocation: নেই — PB-11-0002 paid অফিস মার্টের subledger: 9,200 Dr ← supplier আমাদের দেবে

Asset কমল ৮,০০০ (ফেরত), input VAT কমল, আর supplier-এর কাছে পাওনা। A/P-তে debit balance — অধ্যায় ১৬-এর unapplied payment-এর ভাই।

২২-১২ — SV-12-0009 ভুল গ্রাহকের নামে issue হলো, PDF পাঠানোর আগেই ধরা পড়ল

document ভুল? হ্যাঁ (ভুল party) বেরিয়েছে? না period? ডিসেম্বর, খোলা → cancelInvoice(SV-12-0009) — অধ্যায় ১৩-এর reversal, একই দিনে নতুন SV-12-0010 ঠিক গ্রাহকের নামে

Credit note নয় — কারণ কাগজটা পৃথিবীতে যায়নি। একই ভুল ২ জানুয়ারিতে ধরা পড়লে (ডিসেম্বর বন্ধ): CN-01-0001 পুরো অঙ্কে + নতুন invoice — দুটোই জানুয়ারিতে।

২৮-১২ — অফিস মার্ট ৯,২০০ ফেরত দিল

RV-12-0007 party = supplier Dr 1120 Bank 9,200 Cr 2110 A/P [অফিস মার্ট] 9,200 allocation: DN-12-0003 refund 9,200 অফিস মার্ট: 0

৩১ ডিসেম্বর — তিন স্তর, দুই দিক

A/R 1130:

opening 34,900 − CN-12-0001 23,000 + PV-12-0002 (refund রহিম) 3,100 − RV-12-0004 15,000 − CN-12-0002 11,500 − SV-12-0009 + reversal 0 + SV-12-0010 … (ধরা যাক 0-এর জন্য বাদ) ─────── closing (11,500) Cr ← সালমার credit balance subledger: করিম 0, রহিম 0, সালমা 11,500 Cr, নদী 0 ✓ open items: কোনো open invoice নেই; unapplied CN 11,500 ✓

1130-এর ব্যালেন্স credit — Balance Sheet-এ asset-এর ঘরে ঋণাত্মক নয়, liability-তে reclassify (অধ্যায় ১৪-এর নিয়ম)। Auditor-এর ভাষায় “customer credit balances”।

2160 Customer Advance:

সাগর লিমিটেড 1,00,000 invoice নেই, project জানুয়ারিতে advance aging: 23 দিন — ঠিক আছে; ৯০ দিন পার হলে প্রশ্ন

A/P 2110 (অধ্যায় ১৬-এর ১,২৬,০০০ থেকে):

opening 1,26,000 − PV-11-0009 (PDC 05-12) 1,26,000 ← টেক সাপ্লাই বন্ধ + ডিসেম্বরের bill (অধ্যায় ১৮) … − DN-12-0003 9,200 + RV-12-0007 9,200 অফিস মার্ট: 0; টেক সাপ্লাই: 0 (DN-এর counterparty মিলেছে)

Credit / Debit Note Register — ডিসেম্বর

CREDIT NOTES (sales) — ডিসেম্বর ২০২৫ তারিখ Ref গ্রাহক against reason Net VAT মোট 02-12 CN-12-0001 করিম SV-09-0003 not_delivered 20,000 3,000 23,000 15-12 CN-12-0002 সালমা SV-10-0001 price_adj. 10,000 1,500 11,500 ────── ───── ────── 30,000 4,500 34,500 → VAT return: output VAT adjustment −4,500 → 4180: 30,000 == GL ✓ DEBIT NOTES (purchase) — ডিসেম্বর ২০২৫ 20-12 DN-12-0003 অফিস মার্ট PB-11-0002 damaged 8,000 1,200 9,200 → VAT return: input VAT adjustment −1,200 (DN-10-0006 অক্টোবরের register-এ; counterparty CN-TS-0412 এ মাসে link হলো — entry নয়)

৫. Implementation — Software ও Database

একটা notes table — চার দিক

notes id, company_id document_type VARCHAR(20) -- sales | purchase kind VARCHAR(10) -- credit | debit note_no VARCHAR(40) -- CN-12-0001 / DN-12-0003; (type,kind)-ধরে gapless party_id BIGINT FK -- customer বা supplier original_type VARCHAR(20) -- sales_invoice | purchase_invoice original_id BIGINT FK NOT NULL -- মূল document — বাধ্যতামূলক reason_code VARCHAR(30) -- return | not_delivered | price_adjustment -- | discount | damaged | shortage | cancellation reason TEXT NOT NULL note_date DATE posting_date DATE subtotal, tax_total, grand_total DECIMAL(18,4) counterparty_note_no VARCHAR(60) NULL -- supplier-এর CN নম্বর (purchase debit note-এ) counterparty_note_date DATE NULL status VARCHAR(20) -- draft | approved | posted | cancelled approved_by, journal_entry_id UNIQUE (company_id, document_type, kind, note_no) INDEX (original_type, original_id)
note_lines id, note_id, line_no original_line_id BIGINT FK NOT NULL -- মূল invoice/bill-এর line quantity DECIMAL(18,4) -- ফেরতের পরিমাণ (থাকলে) unit_price, line_net, tax_amount DECIMAL(18,4) account_id BIGINT FK -- CN: 4180 / 2180; DN: মূল line-এর account

চারটি সমন্বয় (document_type × kind) একটাই table-এ। কোন জোড়া কী:

sales credit CN গ্রাহককে A/R কমে সাধারণ sales debit DN গ্রাহককে A/R বাড়ে বাড়তি charge, কম purchase debit DN supplier-কে A/P কমে সাধারণ purchase credit supplier-এর DN A/P বাড়ে supplier কম bill করেছিল, কম

Posting — একই rule, direction

অধ্যায় ১৫-এর buildDocumentEntry(doc, direction)-এ note ঢোকে direction উল্টে:

directionOf(doc): sales_invoice → +1 (party Dr, lines Cr) purchase_invoice → −1 (party Cr, lines Dr) note(sales, credit) → −1 (invoice-এর উল্টো) note(sales, debit) → +1 note(purchase, debit) → +1 (bill-এর উল্টো) note(purchase, credit) → −1 postNote(note, by): যাচাই: note.status == 'approved' original.status NOT IN ('draft', 'cancelled') প্রতিটি line: original_line ∈ original.lines quantity ≤ original_line.qty − Σ আগের note qty (একই line) Σ note.grand_total (এই + আগের, same original) ≤ original.grand_total period(note.posting_date) খোলা; নইলে খোলা period, log purchase debit note-এ VAT সমন্বয়ের সময়সীমা (config) lineAccount(l): sales credit: original_line.obligation_id ? 2180 : 4180 -- contract → deferred purchase debit: original_line.debit_account_id -- মূল account sales debit: original_line.revenue_account_id purchase credit: original_line.debit_account_id entry = buildDocumentEntry(note, directionOf(note)) post(entry) -- contract line হলে position ঠিক করুন (অধ্যায় ১৭) প্রতিটি line WHERE obligation_id: contract.billed_to_date −= l.line_net -- allocation: মূল document open থাকলে open = original.open_amount a = min(note.grand_total, open) যদি a > 0: allocate(note, [(original, a)]) -- source = credit_note / debit_note -- বাকি (note.grand_total − a): party credit balance — unapplied note note.status = 'posted'

buildDocumentEntry()-তে TDS-এর line উল্টো চিহ্নে যায় — note-এও তাই: TDS-সহ bill-এর DN-এ 2150-ও কমে (TDS ইতিমধ্যে সরকারকে দেওয়া থাকলে — জটিল, অধ্যায় ৫৬; এখানে সতর্কতা)।

Advance — receipt-এর একটা পতাকা

payments (+) is_advance BOOLEAN NOT NULL DEFAULT false reference_doc VARCHAR(60) NULL -- proforma / quotation / contract নম্বর applied_to_date DECIMAL(18,4) NOT NULL DEFAULT 0 refunded_to_date DECIMAL(18,4) NOT NULL DEFAULT 0 CHECK (applied_to_date + refunded_to_date <= amount) open_advance(p) = p.amount − applied_to_date − refunded_to_date

postPayment()-এ (অধ্যায় ১১): is_advance হলে control account-এর বদলে advance account:

receipt, customer, is_advance → Cr 2160 (party) নইলে Cr 1130 payment, supplier, is_advance → Dr 1140 (party) নইলে Dr 2110

2160 আর 1140 — দুটোই party subledger রাখে (posted_lines.party_id), control account-এর মতো যাচাই: GL 2160 == Σ open_advance (customer)

Advance-এর সমন্বয়

Invoice issue-র সময় (অধ্যায় ১৩-এর issueInvoice()-এর পরে):

applyAdvance(invoice, advance_payment, amount, by): যাচাই: advance.party_id == invoice.customer_id amount ≤ open_advance(advance) amount ≤ invoice.open_amount entry = JV(posting_date = invoice.invoice_date, source_type = 'advance_adjustment') Dr 2160 (party) amount Cr 1130 (party) amount post(entry) INSERT allocations (sales_invoice, invoice, 'advance', advance.id, amount) advance.applied_to_date += amount invoice.open_amount −= amount (allocate()-এর ভিতরে)

Supplier-এ আয়না — Dr 2110 / Cr 1140, source = 'advance', bill-এ। UI: invoice তৈরির সময় গ্রাহকের open advance দেখান, default পুরোটা allocate, ব্যবহারকারী বদলাতে পারেন।

Refund:

refundAdvance(advance, amount, by): payment(kind = payment, party = customer, refund_of = advance.id) Dr 2160 (party) / Cr Bank advance.refunded_to_date += amount

Unapplied note — credit balance

CN-এর যে অংশ কোনো invoice-এ বাঁধা নেই:

unapplied_note(n) = n.grand_total − Σ allocations WHERE source = (credit_note, n.id) পরে নতুন invoice এলে: allocate(note, [(new_invoice, amount)]) -- source = credit_note, doc = নতুন invoice -- GL entry নেই: CN post-এ 1130 আগেই কমেছে; শুধু কোন invoice-এ, তা এখন ঠিক হলো ফেরত: payment(kind = payment, party = customer, refund_of_note = n.id) Dr 1130 (party) / Cr Bank allocations: source = refund

অধ্যায় ১৪-এর receipt_allocations-এর source_type তালিকায় দুটো যোগ: refund, আর credit_note এখন দুই দিকে — মূল invoice-এ (open কমাতে) ও নতুন invoice-এ (unapplied note খরচ করতে)। CHECK-এ (অধ্যায় ১৬) refund যোগ করুন।

Reversal না note — কোডে

canCancel(invoice): return invoice.sent_at IS NULL -- PDF/email যায়নি and period(invoice.invoice_date) খোলা and invoice.open_amount == invoice.grand_total -- কোনো allocation নেই UI: "Cancel" button শুধু canCancel() হলে; নইলে "Issue credit note"

sent_at — invoice email/print হওয়ার timestamp (অধ্যায় ১৩-এ ছিল না; যোগ করুন)। এটাই “কাগজ পৃথিবীতে গেছে কি না”।

Report

১. CN register / DN register — মাস-ধরে, reason-ধরে; VAT return-এর adjustment ২. Advance aging — open_advance > 0, বয়স; ৯০ দিনে সতর্কতা (টাকা নিয়ে কাজ হয়নি) ৩. Party credit balances — A/R-এ Cr, A/P-এ Dr; Balance Sheet reclassification-এর তালিকা ৪. Return rate — reason 'return'/'damaged'-এর CN ÷ sales, গ্রাহক/item-ধরে (ব্যবসার প্রশ্ন) ৫. Counterparty pending — purchase DN যার counterparty_note_no নেই, ৬০ দিনের বেশি

রাতের যাচাই

৫০. প্রতিটি original: Σ notes.grand_total (posted) ≤ original.grand_total ৫১. GL 2160 == Σ open_advance (customer); GL 1140 == Σ open_advance (supplier) ৫২. notes.status = 'posted' কিন্তু journal_entry_id IS NULL → ০ সারি ৫৩. unapplied note ৩০ দিনের বেশি → সতর্কতা; advance ৯০ দিনের বেশি invoice ছাড়া → সতর্কতা ৫৪. purchase debit note, counterparty_note_no NULL, ৬০ দিন → সতর্কতা (supplier-কে তাগাদা) ৫৫. GL 4180 == Σ sales credit note lines (account 4180) ৫৬. note-এর party ≠ original-এর party → ০ সারি

Test হিসেবে

test "credit note মূল মাসের revenue বদলায় না": inv = issue(Sep, 4110, 3,80,000) cn = post(creditNote(inv, Dec, line 20,000 VAT15)) assert revenue(4110, Sep) == 3,80,000 assert Δ 4180 (Dec) == +20,000; Δ 2140 == −3,000; Δ 1130 == −23,000 assert inv.open_amount == 15,000 test "CN invoice-এর বেশি নয়": assert rejects creditNote(inv, line 1,50,000) -- inv 1,38,000 test "paid invoice-এ CN → credit balance, পরে allocate GL ছাড়া": inv paid; cn = post(creditNote(inv, 11,500)) assert subledger(সালমা) == −11,500; unapplied_note(cn) == 11,500 g = snapshot(); inv2 = issue(সালমা, 50,000) allocate(cn, [(inv2, 11,500)]) assert snapshot() == g; inv2.open_amount == 38,500 test "একই rule চার দিক": প্রতিটি doc in [SV, PB, CN(sales), DN(purchase)]: e = buildDocumentEntry(doc, directionOf(doc)) assert e.balanced() assert CN.line(1130).credit > 0; DN.line(2110).debit > 0 test "advance: 2160-এ, A/R নয়; invoice-এ সমন্বয়": adv = receive(সাগর, 1,00,000, is_advance) assert Δ 2160 == −1,00,000 (Cr); Δ 1130 == 0 inv = issue(সাগর, 2,30,000); applyAdvance(inv, adv, 1,00,000) assert Δ 2160 == +1,00,000; inv.open_amount == 1,30,000; open_advance(adv) == 0 test "cancel শুধু বেরোনোর আগে": inv = issue(...); assert canCancel(inv) send(inv); assert not canCancel(inv) test "supplier-এর CN এলে entry নেই": dn = post(debitNote(bill, 1,38,000)); g = snapshot() linkCounterparty(dn, 'CN-TS-0412', 15-12) assert snapshot() == g

৬. Financial Statement Impact

INCOME STATEMENT (ডিসেম্বর) 4110 Software Dev. Income (নদী গ্রুপ 3,00,000 — অধ্যায় ১৭) 4180 Sales Returns & Allowances (30,000) ← contra; net revenue-র নিচে (1520 asset 8,000 কমল — Income Statement-এ নয়) BALANCE SHEET (৩১ ডিসেম্বর) 1130 A/R 0 (সালমার 11,500 Cr → liability-তে) Customer credit balances 11,500 ← reclassified 2160 Customer Advance 1,00,000 (সাগর) 2140 VAT Payable −4,500 এ মাসের CN-এ 1160 VAT Receivable −1,200 DN-এ 1520 Furniture −8,000 CASH FLOW (operating) advance এল +1,00,000 ← টাকা এসেছে, আয় নয় refund গেল −3,100 supplier ফেরত দিল +9,200

Income Statement-এ revenue দুই লাইনে দেখানোর রীতি: gross revenue − returns & allowances = net revenue। 4180 আলাদা রাখার কারণ এটাই — ম্যানেজমেন্ট জানতে চায় কত ফেরত আসছে, কেন। Purchase-এ contra নেই — asset ফেরত গেলে asset-ই কমে; Balance Sheet-এ শুধু ৭২,০০০-এর furniture।

Cash Flow-তে advance-এর ১,০০,০০০ ডিসেম্বরে operating inflow — যদিও আয় জানুয়ারি-ফেব্রুয়ারিতে হবে। অধ্যায় ১৭-এর তিন সংখ্যার গল্প, উল্টো দিক থেকে: এবার cash আগে, revenue পরে।


৭. Common Developer Mistakes

ভুলকী ঘটেসঠিক পথ
ভুল invoice “edit” করা post-এর পরেগ্রাহকের কাগজ আর আপনার খাতা আলাদা; audit trail নেইcancel (reversal) বা CN — immutable
বেরিয়ে যাওয়া invoice cancelগ্রাহকের A/P-তে আছে, আপনার নেই; VAT return মেলে নাsent_at → শুধু CN
CN-এ মূল মাসের revenue কমানোছাপা report বদলায়, VAT return জমা হয়ে গেছে4180, note-এর মাসে
CN মূল invoice ছাড়া (“free-standing”)কিসের credit? VAT return-এ reference নেইoriginal_id NOT NULL, line-ধরে
CN invoice-এর বেশিঋণাত্মক invoiceΣ ≤ original, যাচাই ৫০
Advance A/R-এ Cr (unapplied-এর মতো)দেনা asset-এর ভিতরে লুকায়, aging নষ্টis_advance → 2160
Advance revenue-তেটাকা এল, আয় হলো — কাজ হয়নি2160, invoice-এ সমন্বয়
Advance সমন্বয়ে JV নেই, শুধু allocation2160 কখনো কমে নাJV Dr 2160 / Cr 1130 + allocation
Proforma sales_invoices-একেউ post করে ফেলে, gapless নম্বর নষ্টআলাদা table / quotation
Supplier-এর CN এলে দ্বিতীয় entryদুবার কমলআপনার DN একবার, counterparty নম্বর link
Supplier-এর CN-এর অপেক্ষায় DN না লেখামাল গেছে, দেনা কমেনি, statement মেলে নাDN ফেরতের দিনে
Paid invoice-এ CN → “Misc Income”গ্রাহকের টাকা আপনার আয়credit balance, ফেরত/পরের invoice
CN-এর জন্য আলাদা posting কোডপঞ্চম copy, পঞ্চম bugbuildDocumentEntry(note, ±1)
Note-এ VAT মূল invoice-এর মাসেVAT return সংশোধনnote-এর মাসে, adjustment
Credit balance report নেইBalance Sheet-এ A/R কম দেখায়, liability লুকায়party credit balances, reclassify

প্রথম দুটোই মূল। “Edit” button-টা যে system-এ আছে, সেখানে বাকি সব নিয়ম অর্থহীন — কারণ যেকোনো সংখ্যা যেকোনো সময় বদলানো যায়। Post হওয়া document immutable; বদলাতে হলে নতুন document — এটাই এই অধ্যায়ের এক বাক্য, আর অধ্যায় ৪৩ ও ৪৫-এর ভিত্তি।


৮. Exercises

সেট ক — entry ও allocation

১। গ্রাহক advance 60,000 দিলেন ০৫-১২। invoice ২০-১২, 1,15,000 (VAT সহ)। গ্রাহক বাকিটা দিলেন ০৫-০১। তিনটি entry + allocation। ৩১-১২-এ 2160, 1130? ২। ১ নম্বরে গ্রাহক project বাতিল করলেন ১০-১২, advance ফেরত চাইলেন, আপনি 10,000 কেটে রাখলেন (চুক্তি অনুযায়ী)। entry? 10,000 কোন account? ৩। Invoice 2,30,000 (VAT সহ), ২টা line। গ্রাহক line 2-এর অর্ধেক ফেরত দিলেন (net 40,000)। CN লিখুন — line-ধরে, VAT সহ। invoice open কত? ৪। ৩ নম্বরের invoice আগেই paid। CN-এর পরে কী? গ্রাহক ফেরত চাইলেন — entry। গ্রাহক বললেন "পরের invoice-এ কাটুন" — পরের invoice 50,000 এলে allocation ও open। ৫। Supplier-এর bill 92,000 (VAT সহ), paid। ৮,০০০ + VAT-এর মাল ফেরত। DN লিখুন। supplier ফেরত না দিয়ে পরের bill-এ কাটলেন (পরের bill 46,000) — allocation। ৬। Supplier-কে advance 40,000; bill এল 50,000, TDS 10%। সমন্বয়ের JV, allocation, open, payment (অধ্যায় ১৬-এর রফিক — নিজে আবার লিখুন)।

সেট খ — reversal না note

৭। প্রতিটির জন্য cancel না CN, কেন: (ক) invoice ভুল অঙ্কে, ২ ঘণ্টা আগে, email যায়নি (খ) invoice ভুল অঙ্কে, গ্রাহক email পেয়েছেন, একই দিন (গ) invoice ঠিক, গ্রাহক ৩ সপ্তাহ পরে পণ্য ফেরত দিলেন (ঘ) invoice দুবার issue হয়েছে (duplicate), দ্বিতীয়টা পাঠানো হয়নি, কিন্তু মাস বন্ধ (ঙ) invoice ঠিক গ্রাহক, ভুল VAT হার, পাঠানো হয়েছে ৮। (ঘ)-এর জন্য CN দিলে 4180-এ একটা অঙ্ক বসবে যেটা "ফেরত" নয়, "duplicate"। Return rate report নষ্ট হবে। সমাধান? ৯। Contract invoice (অধ্যায় ১৭) 2,40,000 deferred-এ। গ্রাহক চুক্তি কমালেন, CN 40,000। entry কোন account-এ — 4180 না 2180? position কী হবে? recognized অংশে CN হলে?

সেট গ — কোনটা ভুল

১০। advance receipt: Dr Bank / Cr 4110 Revenue — "টাকা তো এসেছে" ১১। advance receipt: Dr Bank / Cr 1130 A/R [গ্রাহক] — "unapplied-এর মতো" ১২। CN: Dr 4110 Revenue / Dr 2140 / Cr A/R — ডিসেম্বরে, সেপ্টেম্বরের invoice-এ ১৩। CN: original_id NULL — "গ্রাহককে ছাড় দিচ্ছি, কোনো invoice-এ নয়" ১৪। DN: Dr 2110 / Cr 4180 — supplier-কে ফেরত, "return তো" ১৫। Supplier-এর CN এল → Dr 2110 / Cr 1510 — DN আগেই লেখা ছিল ১৬। UPDATE sales_invoices SET grand_total = … WHERE status = 'issued'

সেট ঘ — নকশা

১৭। notes table-এ চারটি (document_type, kind)। প্রতিটির direction, party account, line account — table আকারে। কোনটা সবচেয়ে কম দরকার, বাদ দিলে কী হারায়? ১৮। allocations.source_type-এ এখন: receipt, payment, discount, credit_note, debit_note, write_off, advance, refund। credit_note দুই দিকে (মূল invoice ও নতুন invoice) — CHECK constraint কীভাবে লিখবেন? একটা CN-এর Σ allocation ≤ CN total — কোথায় যাচাই? ১৯। Inventory-র item ফেরত (অধ্যায় ২৭-এর আগাম): CN-এ stock বাড়ে, COGS কমে। CN-এর কোন ধাপে? ফেরত মাল "ভালো" না "নষ্ট" — কে বলবে, কখন? note_lines-এ এখন কী column রেখে দেবেন? ২০। Advance-এ VAT (দেশভেদে): advance পাওয়ার সময়েই output VAT। entry কী হবে? invoice-এ সমন্বয়ের সময় VAT দুবার না হয় — কীভাবে? config কোথায়?

উত্তর আছে Workbook-এর Answer Key, অধ্যায় ১৯-এ।


৯. Developer Challenge

একটি AdjustmentDocumentService নকশা করুন — advance (দুই দিক), credit note, debit note — আর Part 2-র সব document-কে একটা DocumentPostingService-এ আনুন: SV, PB, CN, DN, receipt, payment, advance, refund।

যা যা নকশা করবেন:

১. notes + note_lines — চারটি (type, kind), gapless নম্বর (type, kind)-ধরে, original_id NOT NULL, line-ধরে qty/amount সীমা, counterparty_note_no। Contract line-এর CN-এ 2180 ও billed_to_date (অধ্যায় ১৭) — position ঋণাত্মক হয়ে গেলে (recognized > নতুন billed) কী?

২. directionOf(doc) + buildDocumentEntry() — Part 2-র প্রতিটি document একটাই function-এ। প্রতিটির জন্য test: balanced, party account সঠিক দিকে, VAT সঠিক account ও দিকে, TDS (থাকলে)। Direction-এর বাইরে কোন document-এ if লাগে — সেটাই নকশার ফাঁক; তালিকা করুন।

৩. Advance — is_advance, 2160/1140 party subledger, applyAdvance() (JV + allocation), refundAdvance(), আংশিক সমন্বয় (advance 1,00,000, invoice 60,000 → বাকি 40,000 পরের invoice-এ), advance aging, project বাতিলে কাটা রাখা (exercise ২)।

৪. Unapplied note — credit balance, statement-এ বার্তা, ফেরত বা পরের invoice-এ allocate (GL ছাড়া), ৩০ দিনে সতর্কতা। A/R-এর credit balance আর A/P-এর debit balance — Balance Sheet reclassification-এর query (অধ্যায় ২১-এর জন্য)।

৫. Cancel বনাম note — sent_at, canCancel(), UI-তে একটাই button যা ঠিক কাজটা করে; period বন্ধ থাকলে CN-এর posting_date; “duplicate invoice” reason_code যাতে return rate নষ্ট না হয় (exercise ৮)।

৬. Register ও VAT — CN/DN register মাস-ধরে, VAT return-এর adjustment line, দেশভেদে সময়সীমা config, মূল invoice-এর নম্বর/তারিখ note-এ ছাপা।

৭. Immutability — post হওয়া invoice/bill/note-এ UPDATE আটকান: database trigger? application layer? দুটোই? কোন column বদলানো যাবে (narration? attachment?) — তালিকা ও যুক্তি। অধ্যায় ৪৫-এর audit trail-এর জন্য এখন কী রাখবেন?

৮. রাতের যাচাই ৫০–৫৬। ৫১ ব্যর্থ হলে (GL 2160 ≠ Σ open advance): advance সমন্বয়ে JV হয়েছে কিন্তু applied_to_date বাড়েনি — নাকি উল্টো? কীভাবে আলাদা করবেন?

২ আর ৭ নম্বরটাই আসল পরীক্ষা — আর এটাই Part 2-র শেষ পরীক্ষা। অধ্যায় ১৩-এর Developer Challenge-এ বলেছিলাম posting rule এমন হোক যাতে purchase একই কাঠামোয় চলে; অধ্যায় ১৫-এ direction এল; এখন আটটা document একটা function-এ। যদি সত্যিই একটাই function হয়, Part 5-এর Posting Rule Engine (অধ্যায় ৩৮) আপনার লেখা হয়ে গেছে। আর immutability — “post-এর পরে edit নেই, শুধু নতুন document” — এই এক নিয়ম না মানলে Part 2-র বাকি সব নিয়ম কাগজে থাকে, software-এ নয়।


১০. Summary Card

তিন document, এক চরিত্র

advance টাকা document-এর আগে 2160 (L) / 1140 (A) party-ধরে; invoice/bill-এ সমন্বয় credit note invoice-এর পরে কমানো Dr 4180 (বা 2180), Dr 2140; Cr 1130 debit note bill-এর পরে কমানো Dr 2110; Cr মূল account, Cr 1160 কোনোটাই নিজে বিক্রি/ক্রয় নয় — আগের document-কে বদলায়

তিন cousin

advance invoice নেই, কাজ নেই, ইচ্ছাকৃত → invoice-এ সমন্বয় deferred invoice আছে, কাজ নেই → recognition unapplied invoice আছে, মেলে না, দুর্ঘটনা → allocate / ফেরত

Reversal না note

document ভুল + বেরোয়নি + period খোলা + allocation নেই → cancel নইলে → note, নিজের মাসে, মূল document-এর reference সহ post হওয়া document immutable; বদল = নতুন document

Note-এর নিয়ম

original_id বাধ্যতামূলক; line-ধরে; Σ ≤ original revenue/VAT note-এর মাসে (4180 contra); মূল মাস অপরিবর্তিত open invoice নেই → credit balance → ফেরত / পরের invoice (GL ছাড়া allocate) supplier-এর CN = আপনার DN-এর counterparty নম্বর — দ্বিতীয় entry নয়

Direction

SV +1 PB −1 CN(sales) −1 DN(purchase) +1 — একটাই buildDocumentEntry()

Developer checklist

□ notes + note_lines, (type, kind), gapless, original_id NOT NULL, সীমা □ directionOf() → buildDocumentEntry() — আট document এক rule □ payments.is_advance → 2160/1140, party subledger □ applyAdvance(): JV + allocation source 'advance'; refundAdvance() □ allocations.source_type: + refund; credit_note দুই দিকে; CHECK □ unapplied note: credit balance, statement, ৩০ দিন □ canCancel(): sent_at, period, allocation; UI একটাই button □ contract line CN → 2180, billed_to_date □ counterparty_note_no link — entry নয় □ proforma আলাদা table □ post হওয়া document immutable (trigger + app) □ report: CN/DN register (VAT adjustment), advance aging, credit balances, return rate □ রাতে: Σ note ≤ original, 2160/1140 == Σ open advance, JE link, বয়স, counterparty, 4180, party মিল

Part 2 শেষ

অধ্যায় ১১ থেকে ১৯ — নয়টি অধ্যায়, একটা software company-র আগস্ট ২০২৫ থেকে ফেব্রুয়ারি ২০২৬। Cash Book থেকে শুরু, তারপর ব্যাংকের সাথে মেলানো, বিক্রি, পাওনা, ক্রয়, দেনা, আয়-খরচের মাস, মাসের শেষের সমন্বয়, আর শেষে যা কিছু আগের document-কে বদলায়। প্রতিটি অধ্যায়ে একটাই GL, একটাই allocation table, একটাই posting rule — শুধু direction বদলেছে।

এখন যা আছে: প্রতিটি মাসের শেষে একটা Trial Balance যার প্রতিটি সংখ্যার নিচে একটা তালিকা — কোন invoice, কোন bill, কোন prepaid, কোন accrual, কোন contract। Part 3 — Financial Statements সেই Trial Balance থেকে শুরু: অধ্যায় ২০-এ Income Statement — এই কয়েক মাসের 4xxx আর 5xxx দিয়ে, “ব্যবসা কেমন চলল” এক পাতায়।

Part 2-র project ও exit criteria — Projects ও Exit Criteria পাতায়।