অধ্যায় ১৬ — Accounts Payable
Volume 1 · Part 2 — Core Business Accounting · Chapter 16
পূর্বশর্ত: অধ্যায় ১৫ (Purchase), অধ্যায় ১৪ (Accounts Receivable — allocation ও aging), অধ্যায় ১১ (Cash ও Bank — payments, cheque, PDC)
১. Learning Objective
এই অধ্যায় শেষে আপনি পারবেন:
A/P-এর তিন স্তর — GL, supplier subledger, open bill — A/R-এর আয়নায় ব্যাখ্যা করতে
Payment allocation নকশা করতে, আর A/R-এর allocation table-এর সাথে একটাই table-এ আনতে
এক payment-এ বহু bill, আংশিক payment, বেশি payment — তিনটিই সামলাতে
Settlement discount received-এর entry লিখতে, আর discount নেওয়া লাভজনক কি না — তা হিসাব করতে
Payment run নকশা করতে: কাকে, কবে, কত — নগদের সীমার ভিতরে
Supplier aging-কে cash forecast হিসেবে পড়তে
Supplier-এর পাঠানো statement আপনার খাতার সাথে reconcile করতে
PDC issue করলে A/P-এ কী হয়, আর কী হয় না — তা বলতে
Supplier-এর bank account বদল — payment fraud-এর সবচেয়ে সাধারণ পথ — আটকাতে
তিন-মুখী reconciliation: GL 2110 == subledger == open bill − unapplied — চালাতেসময়: পড়া ৫০ মিনিট + অনুশীলন ৬০ মিনিট।
২. Concept Explanation
অপেক্ষা বনাম সিদ্ধান্ত
অধ্যায় ১৪-এ টাকা আসে — কবে আসবে, কত আসবে, আপনার হাতে নেই; আপনি তাগাদা দেন আর অপেক্ষা করেন। অধ্যায় ১৬-এ টাকা যায় — আর কবে, কত, কাকে আগে — প্রতিটি সিদ্ধান্ত আপনার।
A/R (অধ্যায় ১৪) A/P (অধ্যায় ১৬)
──────────────── ────────────────
receipt এলে allocate payment-এর আগে বাছাই, পরে allocate
গ্রাহক কখন দেবেন — অনিশ্চিত আপনি কখন দেবেন — পরিকল্পনা
aging: কে দিচ্ছে না aging: কাকে দিতে দেরি হচ্ছে, নগদ কত লাগবে
discount allowed (আয় কমে) discount received (নেওয়া লাভজনক?)
credit limit: গ্রাহককে কত দেবেন cash limit: নিজের কত আছে
statement আপনি পাঠান statement supplier পাঠান, আপনি মেলান
fraud: টাকা নিয়ে write-off fraud: ভুয়া supplier, বদলানো bank accountতাই এই অধ্যায়ের কাঠামো অধ্যায় ১৪-এরই — তিন স্তর, allocation, aging, statement — কিন্তু মাঝখানে একটা নতুন জিনিস: payment run। আর শেষে একটা নতুন ভয়: A/P হলো প্রতিষ্ঠান থেকে টাকা বেরোনোর সবচেয়ে বড় দরজা।
তিন স্তর — আয়না
স্তর ১ GL 2110 Accounts Payable 3,46,950 Cr
│
স্তর ২ Subledger supplier-ধরে ব্যালেন্স
বাড়িওয়ালা 61,750
ISP 9,200
টেক সাপ্লাই 2,76,000
│
স্তর ৩ Open items bill-ধরে বকেয়া
PB-10-0001 বাড়িওয়ালা 61,750 (due 31-10)
PB-10-0002 ISP 9,200 (due 28-10)
PB-10-0003 টেক সাপ্লাই 2,76,000 (due 09-11)
(4,14,000 − DN 1,38,000)সূত্র একই, দিক উল্টো:
GL 2110 == Σ subledger (supplier) == Σ open bill − Σ unapplied paymentUnapplied payment — supplier-কে যা দিয়েছেন কিন্তু কোনো bill-এর সাথে বাঁধা নেই — এবার আপনার পাওনা (supplier আপনাকে ফেরত দেবেন বা পরের bill-এ কাটবেন)। A/R-এ unapplied receipt ছিল লুকানো liability; A/P-এ unapplied payment লুকানো asset। Balance Sheet-এ reclassify-এর নিয়ম একই।
Allocation — একটাই table, দুই দিক
অধ্যায় ১৪-এর receipt_allocations sales invoice-কে receipt-এর সাথে বাঁধত। এখন purchase bill-কে payment-এর সাথে বাঁধতে হবে। দুটো table নয় — অধ্যায় ১৫-এ posting rule-কে যেভাবে direction দিয়ে এক করেছি, allocation-ও তাই:
allocations
document_type sales_invoice | purchase_invoice
document_id
source_type receipt | payment | discount | credit_note | debit_note
| write_off | advance
amountএকটা bill-এর open হিসাব A/R-এরই আয়না:
open = payable_total − Σ payment − Σ discount received
− Σ debit note − Σ advance adjustedতিনটি রূপও একই — আংশিক (৯-১১-এ ২,৭৬,০০০-এর বিপরীতে ১,৫০,০০০), এক payment বহু bill (এক supplier-কে তিনটা bill-এর টাকা এক transfer-এ), বেশি payment (ভুলে TDS না কেটে পুরো ৬৫,০০০ পাঠানো)। আর অধ্যায় ১৪-এর সবচেয়ে গুরুত্বপূর্ণ কথাটা এখানেও: allocation GL বদলায় না — Dr A/P [supplier], Cr Bank payment post-এর সময়েই হয়ে গেছে।
Settlement discount received — নেবেন কি?
Supplier-এর শর্ত “২/১০ net ৩০”। ৯২,০০০-এর bill ১০ দিনে দিলে ৯০,১৬০:
Dr 2110 A/P [অফিস মার্ট] 92,000 ← bill পুরো বন্ধ
Cr 1120 Bank 90,160
Cr 4540 Discount Received 1,840 ← আয় (4190-এর আয়না)খরচ (বা asset) যা ছিল তাই — ৮০,০০০ furniture ৮০,০০০-ই। ছাড়টা bill-এর ঘটনা নয়, payment-এর ঘটনা, তাই আলাদা account। নীতিভেদে কেউ খরচ কমান (contra-expense); এই বইয়ে 4540, আয়।
A/R-এ প্রশ্ন ছিল “গ্রাহক ছাড় কেটেছেন কি ঠিকমতো”। A/P-এ প্রশ্ন “ছাড়টা নেওয়া উচিত কি” — আর উত্তরটা অঙ্কে:
২% ছাড়, ২০ দিন আগে দিলে (১০ দিনে, ৩০-এর বদলে)
বার্ষিক হার = 2 / 98 × 365 / 20 ≈ 37%২০ দিন আগে টাকা দিয়ে ২% বাঁচানো মানে বছরে ৩৭% return — ব্যাংক overdraft-এর সুদের (১২–১৫%) অনেক উপরে। নগদ থাকলে, বা overdraft নিলেও, ছাড় নেওয়া লাভজনক। সূত্রটা payment run-এ বসবে — system নিজেই বলবে কোন bill আগে দেওয়া বুদ্ধিমানের।
Payment run — কাকে, কবে, কত
A/R-এ receipt একটা একটা করে আসে। A/P-এ payment ব্যাচে হয় — সপ্তাহে একবার বা দুবার বসে সিদ্ধান্ত:
১. কী কী bill open — due কবে, ছাড় আছে কি, overdue কি
২. নগদ কত আছে — আর কত রাখতে হবে (বেতন, VAT, ভাড়া)
৩. বাছাই: ছাড়ের সময়সীমা আজ/কাল → প্রথমে (৩৭%)
overdue → তারপর (সম্পর্ক, জরিমানা)
due এই সপ্তাহে → তারপর
due পরে → পরের run-এ
৪. মানুষ দেখেন, বদলান, অনুমোদন দেন
৫. execute: supplier-ধরে একটা payment, তার নিচে bill-ধরে allocationধাপ ৩ system-এর প্রস্তাব, ধাপ ৪ মানুষের সিদ্ধান্ত। আর ধাপ ৪-এ যিনি প্রস্তাব করেন তিনি অনুমোদন দেন না — অধ্যায় ১৫-এর bill approval-এর মতো, এখানে আরও কড়া: এটা আসল টাকা বেরোনোর মুহূর্ত।
Payment run-এর একটা গুরুত্বপূর্ণ ফল: supplier-ধরে একটা payment, bill-ধরে নয়। তিনটা bill-এর জন্য তিনটা transfer নয় — একটা transfer, তিনটা allocation। Supplier-এর remittance advice-এ তিনটা bill নম্বর — যাতে তার A/R-এ allocation ঠিক হয়।
Supplier aging — cash forecast
Bucket, due date থেকে বয়স, as-of — সব অধ্যায় ১৪-এর মতো। কিন্তু পড়ার ভঙ্গি আলাদা:
A/R aging "90+-এ কত আটকে আছে" → আদায়ের চাপ, bad debt
A/P aging "আগামী ৩০ দিনে কত দিতে হবে" → নগদ লাগবে কততাই A/P aging-এ প্রায়ই bucket উল্টো দিকেও থাকে — due in 0–7, 8–30, 31–60 — সামনের দিকে। এটা cash flow forecast-এর কাঁচামাল (অধ্যায় ২২): সামনের মাসের A/P due + বেতন + VAT − প্রত্যাশিত receipt = নগদ ঘাটতি বা উদ্বৃত্ত।
Overdue bucket-এ টাকা থাকা A/P-তে সবসময় খারাপ নয় — কখনো ইচ্ছাকৃত (নগদ নেই, supplier-কে জানানো আছে)। কিন্তু অজান্তে overdue মানে bill অনুমোদনে আটকে আছে বা কেউ ভুলে গেছে — দুটোই রাতের যাচাইয়ে ধরা পড়া উচিত।
Supplier statement reconciliation
অধ্যায় ১৪-এ আপনি গ্রাহককে statement পাঠিয়েছেন। এবার supplier আপনাকে পাঠান — “আমার খাতায় আপনি ২,৬৪,০০০ দেবেন।” আপনার খাতায় ১,২৬,০০০। পার্থক্য ১,৩৮,০০০ — কে ঠিক?
এটা অধ্যায় ১২-এর bank reconciliation-এর হুবহু কাঠামো — দুই পাশের খাতা, line ধরে match, পার্থক্যের প্রকার:
১ timing আপনার খাতায় আছে, তার নেই অপেক্ষা / জানান
→ আপনার debit note, transit-এ payment
২ তার-only তার খাতায় আছে, আপনার নেই bill চান / entry
→ bill এখনো আসেনি, তার interest charge
৩ ভুল যেকোনো পাশে সংশোধনী / বিতর্ক
→ দর ভুল, দুবার bill, ভুল supplierReconciliation ছাড়া statement-এর সংখ্যা মেনে নেওয়া — সবচেয়ে সাধারণ overpayment-এর কারণ: supplier-এর statement-এ আপনার debit note নেই, আপনি “statement অনুযায়ী” দিয়ে দিলেন। আপনার খাতাই সত্য; statement যাচাইয়ের উপকরণ।
PDC issue — দেনা থাকে, cheque ঘোরে
Supplier-কে ৫ ডিসেম্বরের তারিখ লেখা cheque আজ (২৫ নভেম্বর) দিলেন। অধ্যায় ১১-এর নিয়ম উল্টো দিকে:
২৫-১১ payment তৈরি, status = 'draft', instrument_date = 05-12
journal entry নেই → A/P-এ 1,26,000 এখনো open, Bank কমেনি
allocation নেই — কারণ payment post হয়নি
০৫-১২ scheduled কাজ post করে: Dr 2110 [টেক], Cr 1120
তারপর allocationকিন্তু ৩০ নভেম্বরের aging-এ এই bill “overdue” দেখাবে — যদিও cheque দেওয়া আছে। তাই aging-এ একটা memo column: PDC issued। আর supplier-এর হাতে আপনার cheque আছে — তার খাতায় সে টাকা পেয়েছে ধরতেও পারে; statement reconciliation-এ এটা timing পার্থক্য।
আরেকটা সূক্ষ্মতা: আজকের তারিখের cheque দিলে A/P তখনই বন্ধ, Bank তখনই কমে — কিন্তু cheque clear হয় ৩–৭ দিন পরে। সেই ফাঁকটা bank reconciliation-এর কাজ (unpresented cheque, অধ্যায় ১২), A/P-এর নয়।
Supplier bank account — সবচেয়ে বড় দরজা
A/P-এ টাকা যায় supplier-এর bank account-এ। সেই account নম্বর কোথা থেকে আসে? Supplier master থেকে। কে বদলাতে পারেন? এই প্রশ্নটাই payment fraud-এর কেন্দ্র:
email আসে supplier-এর নামে: "আমাদের bank account বদলেছে, নতুন নম্বর…"
কেউ master-এ বদলে দেন
পরের payment run-এ 2,76,000 চলে যায় — অন্য কারো account-এ
supplier দুই সপ্তাহ পরে ফোন করেন: "টাকা পাইনি"এটা accounting-এর bug নয় — entry নিখুঁত, allocation নিখুঁত, তিন স্তর মিলে যায়। শুধু টাকা ভুল জায়গায়। প্রতিরোধ software-এ:
১. bank account বদল = আলাদা অনুমতি, আলাদা অনুমোদন (দুজন)
২. বদলের পরে N দিন (৭–১৪) নতুন account-এ payment আটকে থাকে —
অথবা ফোনে যাচাই (email-এ নয়, master-এর পুরনো নম্বরে)
৩. payment file-এ account নম্বর master থেকে — user input থেকে কখনো নয়
৪. বদলের log: কে, কখন, আগে কী ছিল
৫. payment run-এর অনুমোদনে দেখানো: "এই supplier-এর bank account
গত ৩০ দিনে বদলেছে"অধ্যায় ৪৮-এ পুরো ছবি; এখানে schema-তে জায়গা রাখা — supplier_bank_accounts, আলাদা table, verified পতাকা সহ।
Bill-এর জীবনচক্র — শেষ অংশ
অধ্যায় ১৫-এ posted পর্যন্ত এসেছিল। এবার বাকিটা:
POSTED
│
├──▶ payment run-এ নির্বাচিত ──▶ PARTIALLY PAID ──▶ PAID
│
├──▶ PDC issued (memo; status বদলায় না)
│
├──▶ on hold (বিতর্ক — statement-এ মেলেনি, মাল ফেরত) → payment run বাদ দেয়
│
└──▶ debit note (অধ্যায় ১৯) → open কমেon_hold একটা পতাকা, status নয় — bill posted-ই থাকে (দেনা আছে), শুধু payment run তাকে প্রস্তাবে তোলে না। কারণ লেখা থাকে, আর ৩০ দিনের বেশি hold-এ থাকলে সতর্কতা।
৩. Accounting Rule
Entry
| ঘটনা | Debit | Credit |
|---|---|---|
| Payment (পুরো / আংশিক / unapplied) | A/P [supplier] | Bank |
| Settlement discount সহ payment | A/P [supplier] (পুরো) | Bank (নিট), Discount Received |
| Advance-এর সমন্বয় | A/P [supplier] | Advance to Supplier |
| Debit note (অধ্যায় ১৯) | A/P [supplier] | Expense/Asset, VAT Receivable |
| Unapplied ফেরত পাওয়া | Bank | A/P [supplier] |
| TDS সরকারকে (অধ্যায় ৫৬) | TDS Payable | Bank |
| PDC issue | — (কিছু না, তারিখ পর্যন্ত) | — |
Journal entry-তে যা কখনো হয় না
Payment-এ Expense (খরচ bill-এ, একবার)
Discount-এ Expense কমানো (আলাদা account — নীতি হিসেবে ঠিক করা)
PDC-র তারিখের আগে Bank (cheque টাকা নয়, প্রতিশ্রুতি)Allocation
প্রতিটি open bill-এর জন্য:
open = payable_total − Σ payment − Σ discount received
− Σ debit note − Σ advance adjusted
allocation-এর যোগফল ≤ payment-এর অঙ্ক
payment − allocated = unapplied (supplier-এর কাছে আপনার পাওনা)তিন-মুখী সূত্র
GL 2110 == Σ subledger (supplier) == Σ open bill − Σ unapplied paymentDiscount নেওয়া হবে কি
বার্ষিক হার = pct / (1 − pct) × 365 / (net_days − discount_days)
হার > overdraft/ঋণের সুদ → নেওয়া লাভজনক (নগদ থাকলে বা ধার করেও)অলঙ্ঘনীয়
Payment run: প্রস্তাবকারী ≠ অনুমোদনকারী
Bank account: master থেকে, বদলে দুজনের অনুমোদন + অপেক্ষা৪. Real Business Example
নভেম্বর ২০২৫ — দেওয়ার মাস
১ নভেম্বরে open bills — অধ্যায় ১৫-এর অক্টোবর থেকে:
Bill Supplier bill due payable open
──── ──────── ──── ─── ─────── ────
PB-10-0001 বাড়িওয়ালা 01-10 31-10 61,750 61,750 ← ১ দিন overdue
PB-10-0002 ISP 28-09 28-10 9,200 9,200 ← ৪ দিন overdue
PB-10-0003 টেক সাপ্লাই 10-10 09-11 4,14,000 2,76,000 ← DN 1,38,000 বাদে
────────
GL 2110 3,46,950 ✓
আর: 1140 Advance to Supplier — contractor রফিক 40,000
2150 TDS Payable — অক্টোবরের ভাড়া 3,250
1120 Bank — Prime 4,60,000০১-১১ — নভেম্বরের ভাড়ার bill, ৬৫,০০০, TDS ৫%, due ০১-১২
PB-11-0001
Dr 5220 Office Rent 65,000
Cr 2150 TDS Payable 3,250
Cr 2110 A/P [বাড়িওয়ালা] 61,750০৩-১১ — অক্টোবরের ভাড়া transfer: ৬৫,০০০ — ভুল
নতুন accountant bill-এর ৬৫,০০০ দেখে পুরোটাই পাঠিয়ে দিলেন; payable ছিল ৬১,৭৫০।
PV-11-0001
Dr 2110 A/P [বাড়িওয়ালা] 65,000
Cr 1120 Bank — Prime 65,000
allocation: PB-10-0001 61,750 → open 0 → paid
unapplied 3,250 ← বাড়িওয়ালার কাছে আপনার পাওনাভুলটা ধরা পড়ল allocation-এ — ৬৫,০০০ কোনো bill-এর সাথে পুরো মেলে না। Allocation না থাকলে এই ৩,২৫০ কখনো ধরা পড়ত না — subledger-এ বাড়িওয়ালা ৫৮,৫০০ দেখাত, আর সবাই ভাবত ঠিকই আছে।
০৫-১১ — ৩,২৫০ নভেম্বরের bill-এ allocate; ISP-কে ৯,২০০
allocation (GL entry নেই):
unapplied PV-11-0001 3,250 → PB-11-0001 → open 58,500
PV-11-0002
Dr 2110 A/P [ISP] 9,200
Cr 1120 Bank — Prime 9,200
allocation: PB-10-0002 9,200 → paidবাড়িওয়ালাকে জানানো হলো: “নভেম্বরে ৫৮,৫০০ পাবেন।” Journal entry একটাও নয় — শুধু allocation table-এ একটা সারি সরল।
০৭-১১ — অক্টোবরের TDS সরকারকে
PV-11-0003
Dr 2150 TDS Payable 3,250
Cr 1120 Bank — Prime 3,250TDS-এর challan, certificate — অধ্যায় ৫৬। এখানে শুধু: এটা supplier-কে payment নয়, তাই A/P স্পর্শ হয় না, allocation নেই।
১০-১১ — টেক সাপ্লাই due ০৯-১১, ২,৭৬,০০০; নগদ টানাটানি — আংশিক
মাসের শেষে বেতন ২,৪০,০০০ যাবে। পুরোটা এখন দিলে বেতনে টান পড়বে। Supplier-কে ফোন: ১,৫০,০০০ এখন, বাকিটা ৫ ডিসেম্বরে — মেনে নিলেন।
PV-11-0004
Dr 2110 A/P [টেক সাপ্লাই] 1,50,000
Cr 1120 Bank — Prime 1,50,000
allocation: PB-10-0003 1,50,000 → open 1,26,000 → partially_paid
bill note: "বাকি 05-12, ফোনে সম্মত — [নাম], 10-11"১২-১১ — অফিস মার্ট থেকে আসবাব ৮০,০০০ + VAT ১২,০০০; শর্ত ২/১০ net ৩০
Dr কোথায়? আসবাব, threshold-এর উপরে → Asset
PB-11-0002 (supplier bill: "OM-7731", bill 12-11, due 12-12, ছাড় ২২-১১ পর্যন্ত)
Dr 1520 Furniture & Fixtures 80,000
Dr 1160 VAT Receivable 12,000
Cr 2110 A/P [অফিস মার্ট] 92,000১৫-১১ — contractor রফিকের bill ৫০,০০০, TDS ১০%; advance ৪০,০০০ সমন্বয়
PB-11-0003
Dr 5270 Professional Fee 50,000
Cr 2150 TDS Payable 5,000
Cr 2110 A/P [রফিক] 45,000
JV-11-0005 advance adjustment
Dr 2110 A/P [রফিক] 40,000
Cr 1140 Advance to Supplier 40,000
allocation: PB-11-0003 45,000 − advance 40,000 = open 5,000অধ্যায় ১৪-এর সালমার advance-এর আয়না: advance asset থেকে সরে A/P কমাল; allocation-এ source_type = 'advance'।
২০-১১ — Payment run
Open bills, নগদ, প্রস্তাব:
PAYMENT RUN PR-11-0002 — প্রস্তাব, 20-11-2025
Bill Supplier due open ছাড় বার্ষিক overdue
──── ──────── ─── ──── ─── ────── ───────
PB-11-0002 অফিস মার্ট 12-12 92,000 1,840 37% —
PB-10-0003 টেক সাপ্লাই 09-11 1,26,000 — — 11 দিন
PB-11-0001 বাড়িওয়ালা 01-12 58,500 — — —
PB-11-0003 রফিক 15-12 5,000 — — —
প্রস্তাব
✓ PB-11-0002 90,160 ছাড় 22-11 পর্যন্ত — আগে
✗ PB-10-0003 — PDC 05-12, ফোনে সম্মত
✓ PB-11-0001 58,500
✓ PB-11-0003 5,000
────────
মোট 1,53,660
Bank — Prime আজ 2,32,550
সংরক্ষিত: বেতন 30-11 (2,40,000) ← !
প্রত্যাশিত receipt এ মাসে 3,14,000
(করিম 38,000 + নদী গ্রুপ 2,76,000 — অধ্যায় ১৭)
ব্যবহারযোগ্য 3,06,550
প্রস্তাবের পরে 1,52,890 ✓তিনটি সিদ্ধান্ত পড়ুন: অফিস মার্ট প্রথমে — দুই দিন পরে ছাড় হারাবে, ৩৭%। টেক সাপ্লাই overdue, কিন্তু সম্মতি আছে — PDC। বাড়িওয়ালা due ০১-১২, পরের run ২৮-১১-এ দিলেও হতো — কিন্তু নগদ আছে, সম্পর্ক ভালো থাকুক। প্রস্তাব করলেন accountant; অনুমোদন দিলেন finance manager — আলাদা মানুষ।
Execute:
PV-11-0006 অফিস মার্ট
Dr 2110 A/P [অফিস মার্ট] 92,000
Cr 1120 Bank — Prime 90,160
Cr 4540 Discount Received 1,840
allocation: PB-11-0002 payment 90,160 + discount 1,840 → paid
PV-11-0007 বাড়িওয়ালা
Dr 2110 A/P [বাড়িওয়ালা] 58,500
Cr 1120 Bank — Prime 58,500
allocation: PB-11-0001 58,500 → paid
(3,250 unapplied + 58,500 = 61,750 ✓)
PV-11-0008 রফিক
Dr 2110 A/P [রফিক] 5,000
Cr 1120 Bank — Prime 5,000
allocation: PB-11-0003 5,000 → paid
(advance 40,000 + 5,000 = 45,000 ✓)তিনটা payment, একটা run — payment_run_id তিনটাতেই।
২৫-১১ — টেক সাপ্লাইকে PDC ১,২৬,০০০, তারিখ ০৫-১২
payment PV-11-0009: status = 'draft', method = cheque,
instrument_date = 05-12, amount 1,26,000
journal entry: নেই
A/P [টেক]: 1,26,000 open — অপরিবর্তিত
bill memo: PDC issued 05-12, cheque #001187২৬-১১ — টেক সাপ্লাইয়ের statement এল: “বকেয়া ২,৬৪,০০০”
তার খাতা (আপনি তার গ্রাহক) আপনার খাতা
─────────────────────── ──────────
Invoice TS/2025/1190 4,14,000 PB-10-0003 4,14,000
Receipt 10-11 (1,50,000) PV-11-0004 (1,50,000)
DN-10-0006 (1,38,000) ← তার খাতায় নেই
───────────────────────────── ──────────────────────
ব্যালেন্স 2,64,000 ব্যালেন্স 1,26,000
পার্থক্য 1,38,000 = ঠিক DN-10-0006প্রকার ১ — timing: আপনার debit note তার খাতায় credit note হিসেবে বসেনি (ফেরত laptop-এর জন্য এখনো credit note দেয়নি)। কাজ: supplier-কে credit note চাওয়া, bill-এ statement_reconciled_at = 26-11, difference = DN-10-0006 pending। PDC ইতিমধ্যে ১,২৬,০০০-এর — statement-এর ২,৬৪,০০০ দেখে দ্বিতীয় cheque নয়।
৩০ নভেম্বর — তিন স্তর মেলান
স্তর ১ — GL 2110:
opening 3,46,950
+ PB-11-0001 61,750
− PV-11-0001 65,000
− PV-11-0002 9,200
− PV-11-0004 1,50,000
+ PB-11-0002 92,000
+ PB-11-0003 45,000
− JV-11-0005 (advance) 40,000
− PV-11-0006 92,000
− PV-11-0007 58,500
− PV-11-0008 5,000
─────────
closing 1,26,000 Crস্তর ২ — subledger:
টেক সাপ্লাই 1,26,000 Cr
বাড়িওয়ালা 0 (61,750 + 61,750 − 65,000 − 58,500)
ISP 0
অফিস মার্ট 0
রফিক 0
────────
1,26,000 Cr ✓স্তর ৩ — open items:
PB-10-0003 টেক সাপ্লাই open 1,26,000 (PDC issued 05-12)
unapplied 0
────────
1,26,000 ✓Supplier aging — ৩০ নভেম্বর
A/P AGING — as of 30-11-2025
Supplier Current 1–30 31–60 61–90 90+ মোট memo
──────── ─────── ──── ───── ───── ─── ─── ────
টেক সাপ্লাই 1,26,000 1,26,000 PDC 05-12
(PB-10-0003, due 09-11, 21 দিন)
────────
1,26,000 1,26,000 ✓ == GL
সামনের দিকে (cash forecast):
0–7 দিনে due 1,26,000 (PDC — cheque clear হবে)
8–30 দিনে due 0
+ বেতন 30-11 2,40,000
+ VAT net (অধ্যায় ৫৫) ~50,000তুলনার জন্য ১ নভেম্বরের aging: ৭১,০০০ overdue (দুই bill), ২,৭৬,০০০ current। এক মাসে সব বন্ধ, একটা বাকি — যেটা সম্মতিতে। A/P aging-এ “overdue শূন্য” লক্ষ্য নয়; “অজানা overdue শূন্য” লক্ষ্য।
মাসের নগদ
payment 3,81,110 (65,000 + 9,200 + 3,250 + 1,50,000
+ 90,160 + 58,500 + 5,000)
ছাড় পেয়ে বাঁচল 1,840
bill হলো (payable) 1,98,750 (61,750 + 92,000 + 45,000)
A/P কমল 2,20,950 (3,46,950 → 1,26,000)“কত bill এল” আর “কত টাকা গেল” আলাদা — অধ্যায় ১৫-এর “কত কিনলাম বনাম কত খরচ”-এর পরের ধাপ। তিনটি সংখ্যা, তিনটি report: purchase register, cash book, A/P movement।
৫. Implementation — Software ও Database
Allocation — একটা table, দুই দিক
অধ্যায় ১৪-এর receipt_allocations কে সাধারণ করুন:
allocations
id BIGINT PK
company_id BIGINT FK
document_type VARCHAR(20) -- sales_invoice | purchase_invoice
document_id BIGINT -- invoice বা bill
source_type VARCHAR(20) -- receipt | payment | discount | credit_note
-- | debit_note | write_off | advance
source_id BIGINT -- payments.id, notes.id, JV id
amount DECIMAL(18,4) -- document-এর open কমায়
allocation_date DATE -- as-of aging
allocated_at, allocated_by
CHECK (amount > 0)
CHECK ((document_type = 'sales_invoice'
AND source_type IN ('receipt','discount','credit_note','write_off','advance'))
OR (document_type = 'purchase_invoice'
AND source_type IN ('payment','discount','debit_note','advance')))
INDEX (document_type, document_id)
INDEX (source_type, source_id)CHECK-টা গুরুত্বপূর্ণ — sales invoice-এ payment allocate হওয়া, বা bill-এ write_off — দুটোই bug, database-ই আটকাক। (Supplier-এর দেনা “write-off” করা — অর্থাৎ না দিয়ে মুছে ফেলা — হয়, কিন্তু সেটা অন্য জিনিস: Cr Other Income, আর তার নিজের অনুমোদন। অধ্যায় ১৯।)
purchase_invoices-এও একই দুটো সংরক্ষিত column:
purchase_invoices (+)
amount_settled DECIMAL(18,4) NOT NULL DEFAULT 0
open_amount DECIMAL(18,4) NOT NULL -- payable_total − amount_settled
on_hold BOOLEAN NOT NULL DEFAULT false
hold_reason TEXT NULL
pdc_payment_id BIGINT FK NULL -- memo: PDC দেওয়া আছে
statement_reconciled_at DATE NULLallocate() — direction সহ
অধ্যায় ১৪-এর allocate()-এর সাথে পার্থক্য শুধু party-র প্রকার আর document table:
allocate(source, [(doc, amount)...], by):
lock source, lock প্রতিটি doc (FOR UPDATE)
যাচাই:
source.status == 'posted' -- PDC (draft) allocate হয় না
প্রতিটি doc.party_id == source.party_id
doc.document_type মেলে source.kind-এর সাথে -- payment ↔ purchase_invoice
SUM(amount) ≤ unapplied(source)
প্রতিটি: amount ≤ doc.open_amount
doc.on_hold == false (নইলে override অনুমতি + log)
প্রতিটি (doc, amount):
INSERT allocations (doc.type, doc.id, source.type, source.id, amount,
allocation_date = source.doc_date)
doc.amount_settled += amount; doc.open_amount −= amount
doc.status = open_amount == 0 ? 'paid' : 'partially_paid'
-- journal entry নেইReallocation (০৫-১১-এর ৩,২৫০): পুরনো সারি নেই (unapplied-এর কোনো সারি ছিল না), শুধু নতুন সারি — allocations (purchase_invoice, PB-11-0001, payment, PV-11-0001, 3,250)। GL অপরিবর্তিত। ভুল bill-এ বাঁধা থাকলে: সারি মুছে নতুন সারি, দুটোই audit log-এ (অধ্যায় ৪৫)।
Payment run
payment_runs
id, company_id
run_no VARCHAR(40) -- PR-11-0002
run_date DATE
cash_bank_account_id BIGINT FK
cash_available DECIMAL(18,4) -- সেদিনের ব্যালেন্স (snapshot)
cash_reserve DECIMAL(18,4) -- বেতন, VAT — বাদ রাখা
status VARCHAR(20) -- proposed | approved | executed | cancelled
proposed_by, approved_by, executed_at
CHECK (proposed_by <> approved_by) -- segregation, database-এই
payment_run_lines
id, run_id
bill_id BIGINT FK
supplier_id BIGINT FK
open_amount DECIMAL(18,4) -- প্রস্তাবের সময়
discount_available DECIMAL(18,4) -- এই run-এর তারিখে দিলে
annualized_rate DECIMAL(8,4) NULL
pay_amount DECIMAL(18,4) -- ব্যবহারকারী বদলাতে পারেন
selected BOOLEAN
skip_reason TEXT NULL -- "PDC 05-12", "on hold"
payment_id BIGINT FK NULL -- execute-এর পরেপ্রস্তাব:
proposePaymentRun(as_of, horizon_days, cash, reserve):
budget = cash − reserve + expected_receipts(as_of, horizon_days) -- A/R aging থেকে
bills = open purchase_invoices
WHERE status IN ('posted','partially_paid')
AND on_hold = false
AND pdc_payment_id IS NULL
AND (due_date ≤ as_of + horizon
OR discount_deadline BETWEEN as_of AND as_of + horizon)
প্রতিটি bill:
disc = discountIf(bill, paid_on = as_of) -- 0 হতে পারে
rate = disc > 0 ? annualized(bill.terms) : null
priority = disc > 0 ? (1, −rate) -- ছাড় আগে, বড় হার আগে
: due_date < as_of ? (2, due_date) -- overdue, পুরনো আগে
: (3, due_date)
lines = sort by priority
running = 0
প্রতিটি line:
pay = line.open − line.disc
selected = running + pay ≤ budget
যদি selected: running += pay
নইলে skip_reason = "budget"
INSERT payment_runs (status = proposed), lines
return run -- মানুষ দেখেন, বদলানannualized():
annualized(terms): -- "2/10 net 30"
return terms.pct / (1 − terms.pct) × 365 / (terms.net_days − terms.discount_days)Execute — supplier-ধরে একটা payment:
executePaymentRun(run, by):
যাচাই: run.status == 'approved', by ≠ run.proposed_by
প্রতিটি supplier in run.lines WHERE selected, GROUP BY supplier:
bank = supplier.verified_bank_account() -- নিচে
pmt = createPayment(kind = 'payment', party = supplier,
amount = Σ pay_amount, method = transfer,
bank_account = bank, payment_run_id = run.id)
disc = Σ discount_available WHERE selected
entry: Dr 2110 [supplier] Σ(pay + disc)
Cr Bank Σ pay
Cr 4540 disc (থাকলে)
post(pmt)
allocate(pmt, [(bill, pay) ...])
প্রতিটি bill যার disc > 0:
INSERT allocations (bill, 'discount', entry.id, disc)
line.payment_id = pmt.id
run.status = 'executed'
generate remittance advice per supplier (bill নম্বর সহ)
generate bank payment file (থাকলে — অধ্যায় ৫০)একই supplier-এর তিনটা bill → একটা payments সারি, তিনটা allocations সারি, একটা journal entry। Remittance advice-এ তিনটা bill নম্বর — supplier-এর অধ্যায় ১৪ যাতে সহজ হয়।
Discount received-এর যুক্তি
A/R-এ system সনাক্ত করত গ্রাহক ছাড় কেটেছেন কি না। A/P-এ system প্রস্তাব করে:
discountIf(bill, paid_on):
যদি bill.terms.pct > 0
এবং paid_on ≤ bill.bill_date + bill.terms.discount_days
এবং bill.open_amount == bill.payable_total: -- আংশিক-এ ছাড় নয় (নীতি)
return bill.open_amount × bill.terms.pct
return 0শেষ শর্তটা নীতির — কিছু supplier আংশিক payment-এও আনুপাতিক ছাড় দেন; config। আর ছাড়টা VAT-সহ মোটের উপর না net-এর উপর — supplier-এর শর্ত অনুযায়ী, দেশভেদে ভিন্ন (অধ্যায় ৫৫)। উদাহরণে মোটের উপর।
Supplier bank account
supplier_bank_accounts
id, supplier_id
bank_name, branch, account_no, account_name, routing
is_primary BOOLEAN
verified BOOLEAN NOT NULL DEFAULT false
verified_by, verified_at, verification_method -- phone | document | test_payment
effective_from DATE -- বদলের পরে অপেক্ষা
created_by, created_at
replaced_id BIGINT FK NULL -- আগেরটা কোনটা ছিল
supplier.verified_bank_account():
a = primary WHERE verified AND effective_from ≤ today
যদি a নেই: reject("supplier-এর verified bank account নেই")
যদি a.created_at > today − 30: flag("bank account সম্প্রতি বদলেছে") -- run-এর অনুমোদনে দেখান
return aAccount নম্বর কখনো payment screen-এ type করা হয় না; payment file master থেকেই। verified set করা আলাদা অনুমতি, যিনি create করেছেন তিনি নন।
PDC issued
অধ্যায় ১১-এর একই কাঠামো, দিক উল্টো — kind = 'payment', status = 'draft', instrument_date ভবিষ্যৎ, journal entry নেই। বাড়তি:
issuePDC(bill, cheque_no, instrument_date, by):
pmt = createPayment(kind = payment, party = bill.supplier, method = cheque,
instrument_no = cheque_no, instrument_date, status = draft)
bill.pdc_payment_id = pmt.id -- memo: aging-এ দেখাবে, run-এ বাদ
scheduled (প্রতিদিন):
প্রতিটি payments WHERE kind = payment, method = cheque, status = draft,
instrument_date ≤ today:
postPayment(pmt, doc_date = instrument_date)
allocate(pmt, [(bill, amount)]) -- bill pdc_payment_id থেকে
bill.pdc_payment_id = NULLPDC বাতিল (supplier cheque ফেরত দিলেন): payment cancelled, pdc_payment_id = NULL, bill আবার run-এ আসবে। কোনো reversal নেই — কারণ কোনো entry ছিল না।
Supplier statement reconciliation
অধ্যায় ১২-এর matching engine পুনর্ব্যবহার — শুধু দুই পাশ বদলে:
supplier_statements
id, supplier_id, statement_date, closing_balance, file_url
supplier_statement_lines
id, statement_id, line_date, ref, description, debit, credit
matched_type / matched_id -- purchase_invoice | payment | debit_note
match_status -- matched | unmatched | disputed
reconcileSupplierStatement(stmt):
ours = subledger lines (supplier, ≤ statement_date)
auto-match: ref == supplier_bill_no | amount + date ± 3
unmatched তার পাশে → "bill আসেনি?" / "তার charge"
unmatched আমাদের পাশে → "আমাদের DN তার খাতায় নেই" / "payment transit-এ" / PDC
summary:
তার closing − Σ(তার-only) + Σ(আমাদের-only) == আমাদের subledger ✓২৬-১১-এর উদাহরণে: তার ২,৬৪,০০০ − ০ + (−১,৩৮,০০০ DN) = ১,২৬,০০০ ✓। Statement reconcile হলে purchase_invoices.statement_reconciled_at update — auditor-এর প্রথম প্রশ্ন “বড় supplier-দের statement মেলানো হয়েছে?”
Aging — একটাই query, direction parameter
অধ্যায় ১৪-এর query-তে sales_invoices → purchase_invoices, receipt → payment, customer → supplier — আর কিছু নয়। allocations এক table হওয়ায় সত্যিই একটা query, document_type parameter:
WITH open_items AS (
SELECT d.id, d.party_id, d.due_date, d.pdc_payment_id,
d.payable_total
− COALESCE((SELECT SUM(a.amount) FROM allocations a
WHERE a.document_type = :doc_type
AND a.document_id = d.id
AND a.allocation_date <= :as_of), 0) AS open_amt
FROM :document_table d
WHERE d.company_id = :c
AND d.status NOT IN ('draft','received','cancelled')
AND d.posting_date <= :as_of
),
unapplied AS (
SELECT p.party_id,
SUM(p.amount) − COALESCE(SUM(a.amount), 0) AS unapplied_amt
FROM payments p
LEFT JOIN allocations a
ON a.source_type = :source_type AND a.source_id = p.id
AND a.allocation_date <= :as_of
WHERE p.kind = :payment_kind AND p.party_type = :party_type
AND p.status = 'posted' AND p.doc_date <= :as_of
GROUP BY p.party_id
)
SELECT s.name,
SUM(CASE WHEN :as_of <= o.due_date THEN open_amt END) AS current,
SUM(CASE WHEN :as_of − o.due_date BETWEEN 1 AND 30 THEN open_amt END) AS d1_30,
SUM(CASE WHEN :as_of − o.due_date BETWEEN 31 AND 60 THEN open_amt END) AS d31_60,
SUM(CASE WHEN :as_of − o.due_date BETWEEN 61 AND 90 THEN open_amt END) AS d61_90,
SUM(CASE WHEN :as_of − o.due_date > 90 THEN open_amt END) AS d90plus,
−COALESCE(u.unapplied_amt, 0) AS unapplied,
SUM(CASE WHEN o.pdc_payment_id IS NOT NULL THEN open_amt END) AS pdc_memo
FROM open_items o
JOIN suppliers s ON s.id = o.party_id
LEFT JOIN unapplied u ON u.party_id = o.party_id
WHERE o.open_amt > 0
GROUP BY s.name, u.unapplied_amt;Cash forecast-এর জন্য একই open_items, শুধু bucket সামনের দিকে: due_date − :as_of BETWEEN 0 AND 7, 8 AND 30, …
রাতের যাচাই
২৯. GL 2110 (posted_lines)
== SUM(subledger balance by supplier)
== SUM(purchase_invoices.open_amount WHERE open)
− SUM(unapplied payments)
৩০. প্রতিটি bill:
open_amount == payable_total − SUM(allocations)
৩১. status সামঞ্জস্য:
open_amount == 0 ⟺ status IN ('paid','cancelled')
0 < open < total ⟺ status == 'partially_paid'
৩২. unapplied payment ৩০ দিনের বেশি পুরনো → সতর্কতা (আপনার টাকা supplier-এর কাছে)
৩৩. overdue bill যার note নেই, hold নেই, PDC নেই → সতর্কতা ("অজানা overdue")
৩৪. on_hold ৩০ দিনের বেশি → সতর্কতা
৩৫. গত ৩০ দিনে bank account বদলানো supplier-কে payment হয়েছে
যেখানে verified_by == created_by → ০ সারি
৩৬. allocation-এর supplier ≠ payment-এর supplier → ০ সারি৩৫ নম্বরটা accounting নয় — কিন্তু এটাই সবচেয়ে বেশি টাকা বাঁচায়।
Test হিসেবে
test "allocation GL বদলায় না":
pay(বাড়িওয়ালা, 65,000)
g1 = balance(2110)
allocate(payment, [(PB-10-0001, 61,750)])
assert balance(2110) == g1
assert unapplied(payment) == 3,250
test "discount received: A/P পুরো, Bank নিট, খরচ অপরিবর্তিত":
bill = post(draft(অফিস মার্ট, line(1520, 80,000, VAT15), terms 2/10 net 30))
run = propose(as_of = bill_date + 8); approve(run, অন্য user); execute(run)
assert bill.status == 'paid'
assert Δ 1120 == −90,160
assert Δ 4540 == +1,840
assert Δ 1520 == +80,000 (অপরিবর্তিত)
test "payment run: ছাড় আগে, budget-এর বাইরে বাদ":
bills: A (ছাড় 37%, 90,000), B (overdue, 1,00,000), C (due +20, 50,000)
run = propose(budget = 1,50,000)
-- priority A, B, C; A 90,000 ✓; B: 1,90,000 > budget ✗; C: 1,40,000 ✓
assert selected == [A, C]
assert run.lines[B].skip_reason == 'budget'
test "প্রস্তাবকারী অনুমোদন দিতে পারেন না":
run = propose(by = X)
assert rejects approve(run, by = X)
test "PDC: A/P open থাকে, তারিখে বন্ধ হয়":
issuePDC(PB-10-0003, date = 05-12)
assert PB-10-0003.open_amount == 1,26,000
assert Δ 1120 == 0
clock → 05-12; runScheduled()
assert PB-10-0003.status == 'paid'
assert Δ 1120 == −1,26,000
test "verified bank account ছাড়া payment নয়":
supplier.add_bank_account(verified = false)
assert rejects execute(run with supplier)
test "একই aging query দুই দিক":
a = aging(doc_type = sales_invoice, as_of)
p = aging(doc_type = purchase_invoice, as_of)
assert Σ a == gl(1130) + unapplied_receipts
assert Σ p == gl(2110) + unapplied_payments৬. Financial Statement Impact
INCOME STATEMENT (নভেম্বর)
5220 Office Rent 65,000
5270 Professional Fee 50,000
4540 Discount Received (1,840) ← আয় (বা contra-expense, নীতিভেদে)
(payment কোনো খরচ তৈরি করেনি — খরচ bill-এ ছিল)
BALANCE SHEET (৩০ নভেম্বর, নড়াচড়া)
2110 Accounts Payable −2,20,950 (3,46,950 → 1,26,000)
2150 TDS Payable +5,000 (→ 8,250)
1140 Advance to Supplier −40,000 (→ 0)
1520 Furniture & Fixtures +80,000
1160 VAT Receivable +12,000
1120 Bank −3,81,110 (A/P ও TDS-এর payment; বাকি Cash Book-এ)
CASH FLOW (নভেম্বর)
operating: supplier-দের payment −2,90,950 (3,81,110 − 90,160 furniture)
investing: furniture −90,160 ← asset-এর paymentদুটো বিষয়। প্রথম, PDC-র ১,২৬,০০০ কোথাও নেই — Bank কমেনি, A/P কমেনি; Balance Sheet-এর note-এ “cheques issued, not yet due” — পাঠক জানুক। দ্বিতীয়, Cash Flow-এ furniture-এর payment investing-এ — অধ্যায় ১৫-এর Dr-সিদ্ধান্ত এখানে payment-কেও শ্রেণিবদ্ধ করল; payment নিজে জানে না সে কিসের, allocation তাকে bill-এর সাথে বেঁধে বলে দেয়। Allocation ছাড়া Cash Flow Statement-এর operating/investing ভাগ সম্ভব নয় (অধ্যায় ২২)।
৭. Common Developer Mistakes
| ভুল | কী ঘটে | সঠিক পথ |
|---|---|---|
| A/P-এর জন্য দ্বিতীয় allocation table | দুটো কোড, দুটো bug, aging দুবার লেখা | allocations + document_type, CHECK |
| Payment-এ bill ছাড়াই “supplier-কে ৬৫,০০০” | overpayment কখনো ধরা পড়ে না | allocation বাধ্যতামূলক বা unapplied সতর্কতা |
| Unapplied payment খরচে | আপনার টাকা supplier-এর কাছে, খাতায় নেই | subledger-এ debit, ৩০ দিনে সতর্কতা, statement-এ চান |
| Discount received-এ খরচ কমানো, bill-এর মাসে | bill-এর মাসের খরচ পরের মাসে বদলায় | 4540, payment-এর মাসে |
| Payment run ছাড়া — যে bill যখন | ছাড় হারায়, নগদ পরিকল্পনা নেই, বেতনে টান | run: প্রস্তাব → অনুমোদন → execute |
| প্রস্তাব ও অনুমোদন একই user | একজনই টাকা বের করতে পারেন | CHECK (proposed_by <> approved_by) |
| Bill-ধরে আলাদা payment | ১০টা bill, ১০টা transfer, ১০টা bank charge | supplier-ধরে এক payment, বহু allocation |
| PDC issue-তে Bank credit | Bank ব্যালেন্স এমন টাকা কমায় যা যায়নি | draft, instrument_date-এ post |
| PDC থাকা bill payment run-এ | দুবার payment | pdc_payment_id থাকলে বাদ |
| Statement-এর ব্যালেন্স মেনে payment | supplier-এর ভুলে আপনার টাকা | reconcile, আপনার খাতাই সত্য |
| Bank account screen-এ type করা | ভুল account, বা ইচ্ছাকৃত | master থেকে, verified, অপেক্ষা |
| Bank account বদল একজনের হাতে | BEC fraud — সবচেয়ে সাধারণ payment fraud | দুজন, log, ৩০ দিনের পতাকা |
| Aging-এ PDC memo নেই | ”overdue” দেখে দ্বিতীয় cheque | memo column |
on_hold = status | দেনা “হারিয়ে” যায় report থেকে | পতাকা, status posted-ই |
| Aging দুই দিকে দুই query | একটায় as-of ঠিক, অন্যটায় নয় | parameter দিয়ে এক query |
শেষের আগেরটা আর bank account-এর দুটো — এই অধ্যায়ের বিশেষ। A/R-এ ভুলের দাম “টাকা দেরিতে আসে”; A/P-এ ভুলের দাম “টাকা ভুল জায়গায় চলে যায়” — আর ফেরত আসে না।
৮. Exercises
সেট ক — allocation ও entry
১। Supplier-এর তিনটা open bill: A 40,000 (due 01-11), B 25,000
(due 15-11), C 60,000 (due 01-12)। ১০-১১-এ 90,000 transfer।
Allocation লিখুন (FIFO)। entry কয়টা? allocation কয়টা সারি?
remittance advice-এ কী লেখা থাকবে?
২। Bill 1,15,000 (VAT সহ), শর্ত ২/১০ net ৩০, bill 05-11। ১২-১১-এ
দিলে কত? entry ও allocation। বার্ষিক হার কত?
৩। ২ নম্বরের bill ১৮-১১-এ দিলেন। ছাড় নেই। ব্যবহারকারী তবু 1,12,700
দিলেন — কী হবে? bill open কত? supplier কী বলবেন?
৪। ভুলে supplier-কে 20,000 বেশি দিয়েছেন। তিনি পরের bill-এ কাটবেন
বললেন। এখন entry? allocation? পরের bill 50,000 এলে?
৫। ৪ নম্বরে supplier ফেরত পাঠালেন। entry। allocation table-এ কী হবে?
৬। Contractor-কে advance 30,000; bill এল 50,000, TDS 10%। entry গুলো,
allocation, open কত, run-এ কত দেবেন?সেট খ — payment run ও aging
৭। ৩০-১১-এ open bills:
P due 25-11 1,00,000 ছাড় নেই
Q due 15-12 80,000 2/10, bill 25-11 (ছাড় 05-12 পর্যন্ত)
R due 10-12 45,000 PDC issued 10-12
S due 20-11 30,000 on hold (মাল ফেরত, DN হয়নি)
T due 05-12 60,000
নগদ 2,50,000, সংরক্ষিত 1,20,000। প্রস্তাব লিখুন — ক্রম, কোনটা বাদ,
কেন। মোট কত?
৮। ৭ নম্বরের aging (৩০-১১) bucket-ধরে লিখুন — R আর S কোথায়?
memo column-এ কী? GL 2110 কত?
৯। ৭ নম্বরে অনুমোদনকারী Q-এর ছাড় না নিয়ে P আগে দিতে বললেন
("পুরনো supplier, রেগে আছে")। System কি আটকাবে? উচিত?
১০। Supplier-এর statement: ব্যালেন্স 3,20,000। আপনার subledger:
2,05,000। পার্থক্য 1,15,000। আপনার হাতে: DN 65,000 (গত সপ্তাহে),
PDC 50,000 (তারিখ পরের মাস)। reconcile করুন — কোনটা কোন
প্রকার? দ্বিতীয় cheque দেবেন?সেট গ — কোনটা ভুল
১১। PDC issue-তে: Dr 2110 / Cr 1120, "cheque তো দিয়ে দিয়েছি"
১২। Discount received: Dr 2110 92,000 / Cr 1120 90,160 / Cr 1520 1,840
১৩। allocations table-এ sales_invoice + source_type 'payment' একটা সারি
১৪। payment_runs: approved_by = proposed_by, "ছোট team"
১৫। Payment screen-এ bank account নম্বর একটা text field
১৬। Supplier statement-এ 2,64,000 → "statement অনুযায়ী পরিশোধ" button
১৭। Aging query: `CURRENT_DATE − bill_date`সেট ঘ — নকশা
১৮। allocations-এ document_type দুটো, source_type সাতটা। কোন জোড়া
বৈধ, কোনটা নয় — table আকারে। CHECK constraint লিখুন। ভবিষ্যতে
'employee_advance' (অধ্যায় ২৯) এলে কী বদলাবে?
১৯। Payment run-এর budget-এ "প্রত্যাশিত receipt" ধরা কতটা নিরাপদ?
গ্রাহক না দিলে? দুটো নীতি লিখুন — আশাবাদী ও রক্ষণশীল — আর
কোনটা কখন।
২০। একই supplier-এর দুটো bill, একটা on_hold। Run তাকে একটা payment
দেবে (hold বাদে)। Remittance advice-এ hold-এর bill-টার কথা
লেখা উচিত? supplier-এর দিক থেকে ভাবুন।
২১। Bank account বদলের ৭ দিনের অপেক্ষা — জরুরি payment হলে? override
কে দেবেন, কী log হবে, পরে কে দেখবেন? একটা "নিরাপদ override"
নকশা করুন।
২২। বহু-currency supplier (অধ্যায় ৫৪-এর আগাম): USD bill, BDT payment।
allocation কোন currency-তে? bill-এর দিনের rate আর payment-এর
দিনের rate আলাদা — পার্থক্য কোথায়?উত্তর আছে Workbook-এর Answer Key, অধ্যায় ১৬-এ।
৯. Developer Challenge
একটি PayablesService নকশা করুন — payment allocation থেকে payment run, PDC, statement reconciliation, bank account নিয়ন্ত্রণ পর্যন্ত — আর অধ্যায় ১৪-এর ReceivablesService-এর সাথে যতটা সম্ভব একই কোড ভাগ করে।
যা যা নকশা করবেন:
১.
allocations— একটা table,document_type+source_type,CHECKদিয়ে বৈধ জোড়া। অধ্যায় ১৪-এরreceipt_allocationsথেকে migration: কী বদলাবে, পুরনো data কীভাবে আসবে, downtime লাগবে কি?২.
allocate()— একটাই function দুই দিকে। কোথায়if directionলাগবেই, আর কোথায় লাগা মানে নকশা ভুল? দুজন একই payment একসাথে allocate করলে? একই bill-এ payment আর debit note একসাথে?৩. Payment run —
propose(),approve(),execute(); priority-র যুক্তি config-এ (ছাড়ের হারের সীমা, horizon, reserve-এর নিয়ম); মানুষের বদল সংরক্ষণ (কে কোন line বদলালেন, কেন); execute অর্ধেক হয়ে ব্যর্থ হলে (দুটো payment হলো, তৃতীয়টায় bank file ব্যর্থ) — কী অবস্থায় থাকবে, কীভাবে আবার চালাবেন (idempotency — অধ্যায় ৪৬)?৪. Discount received —
discountIf(), আংশিক payment-এ আনুপাতিক ছাড়ের config, VAT-সহ/ছাড়া base, আর ছাড় হাতছাড়া হলে report: “এ মাসে কত ছাড় হারালাম, কেন” — নগদের অভাবে, না অনুমোদনের দেরিতে?৫. PDC issued — draft payment, scheduled post,
pdc_payment_idmemo, aging column, বাতিল। Supplier যদি cheque তারিখের আগেই deposit করেন (bank ফেরত দেয়, charge কাটে)? এটা কোন অধ্যায়ের ঘটনা — ১১, ১২, না ১৬?৬. Supplier statement reconciliation — অধ্যায় ১২-এর matching engine কতটা পুনর্ব্যবহার করা যায়? দুই পাশের প্রকার তিনটি; প্রতিটি পার্থক্যের জন্য “পরের কাজ” (credit note চাওয়া, bill খোঁজা, বিতর্ক)।
statement_reconciled_atদিয়ে report: “কোন supplier-এর statement ৯০ দিনে মেলানো হয়নি”।৭.
supplier_bank_accounts— create/verify আলাদা অনুমতি,effective_fromঅপেক্ষা,replaced_idchain, ৩০ দিনের পতাকা run-এর অনুমোদনে, log। একটা test: “একজন user নিজে account যোগ করে নিজে verify করে সেদিনই payment পাঠাতে পারেন না” — তিনটি স্তরে আটকান (অনুমতি,CHECK, রাতের যাচাই ৩৫)।৮. রাতের যাচাই ২৯–৩৬। ২৯ ব্যর্থ হলে তিন স্তরের কোনটা ভুল — অধ্যায় ১৪-এর পদ্ধতিই কি চলবে? PDC কোন স্তরে সমস্যা করতে পারে?
৩ আর ৭ নম্বরটাই আসল পরীক্ষা। Payment run হলো এই বইয়ের প্রথম batch process যা টাকা বের করে — অর্ধেক হয়ে থামলে কী হয়, সেই প্রশ্নটা অধ্যায় ৪৬ ও ৪৭-এর পুরো বিষয়। আর bank account নিয়ন্ত্রণ — এটা accounting-এর কোনো নিয়ম নয়, কিন্তু accounting software-এর সবচেয়ে ব্যয়বহুল ছিদ্র। যে system-এ তিন স্তর নিখুঁত মেলে আর টাকা ভুল account-এ যায়, সেটা ব্যর্থ system।
১০. Summary Card
আয়না
A/R (অধ্যায় ১৪) A/P (অধ্যায় ১৬)
control 1130 2110
source receipt payment
discount 4190 Allowed (Dr) 4540 Received (Cr)
unapplied লুকানো liability লুকানো asset
advance 2160 (liab.) 1140 (asset)
statement আপনি পাঠান আপনি মেলান
নিয়ন্ত্রণ credit limit payment run + bank accountতিন স্তর
GL 2110 == Σ subledger (supplier) == Σ open bill − Σ unapplied payment
প্রতিদিন যাচাই; একটাই allocations table, document_type দিয়েEntry
payment Dr 2110 [supplier] Cr Bank
discount সহ Dr 2110 (পুরো) Cr Bank (নিট) Cr 4540
advance সমন্বয় Dr 2110 [supplier] Cr 1140
PDC issue — (instrument_date পর্যন্ত কিছু না)Discount নেবেন?
বার্ষিক হার = pct/(1−pct) × 365/(net − disc দিন) 2/10 net 30 → 37%
হার > ঋণের সুদ → নিনPayment run
প্রস্তাব (ছাড় → overdue → due) → মানুষ বদলান → অনুমোদন (অন্য কেউ) → execute
supplier-ধরে এক payment, bill-ধরে allocation, remittance advice
budget = নগদ − সংরক্ষিত (+ প্রত্যাশিত receipt, নীতিভেদে)Developer checklist
□ allocations: document_type + source_type + CHECK
□ allocate() এক function, দুই দিক; GL স্পর্শ করে না
□ unapplied payment: subledger debit, ৩০ দিনে সতর্কতা
□ discount: payment-এর মাসে, 4540, annualized হার run-এ
□ payment_runs: proposed_by ≠ approved_by (CHECK)
□ supplier-ধরে এক payment, remittance advice
□ PDC: draft, scheduled post, pdc_payment_id memo, run-এ বাদ
□ on_hold পতাকা, status নয়; ৩০ দিনে সতর্কতা
□ supplier_bank_accounts: verified, দুজন, effective_from, ৩০ দিনের পতাকা
□ payment file-এ account master থেকে, কখনো input থেকে নয়
□ statement reconcile: অধ্যায় ১২-এর engine, আপনার খাতাই সত্য
□ aging: এক query, direction parameter, PDC memo, সামনের bucket
□ রাতে: তিন স্তর, open == গণিত, status, unapplied বয়স, অজানা overdue,
hold বয়স, bank account বদল, cross-supplierপরবর্তী অধ্যায়
অধ্যায় ১৭ — Revenue ও Expense Recognition: Part 2-র প্রথম ছয় অধ্যায়ে টাকা, invoice, bill, receipt, payment — সব ঘুরে এল। আর প্রতিটিতে একটা প্রশ্ন বারবার পিছিয়ে দিয়েছি: আয়টা কোন মাসের? খরচটা কোন মাসের? অধ্যায় ১৩-এ deferred revenue, অধ্যায় ১৫-এ “যে মাসের খরচ সেই মাস”, এই অধ্যায়ে “payment কোনো খরচ তৈরি করে না” — সবগুলো একই নিয়মের টুকরো। পরের অধ্যায়ে নিয়মটা পুরো: আয় হয় কাজ সম্পন্ন হলে, খরচ হয় সুবিধা ভোগ হলে — invoice, bill, টাকা কোনোটাই নয়। আর তার সাথে একটা তিন মাসের project, যার invoice, revenue আর cash — তিনটি একেবারে আলাদা মাসে পড়ে।