Post Dated Cheques (PDC)
Track issued and received post dated cheques as real records with a guarded lifecycle and balanced journal entries on present, clear and bounce.
Why this module
Post Dated Cheques (PDC)
Real records, real entries
Every cheque is a queryable, exportable, audit-ready record. Present, clear and bounce each post a balanced double-entry journal through a suspense account, not a status flag with no accounting behind it.
The book is the source of truth
Serial allocation takes a Postgres row lock so concurrent registrations queue rather than race, rejects out-of-order serials, and exhausts the book automatically. A unique constraint on book and number is the backstop.
Yours to keep
LGPL-3 source on disk. No activation key, no phone-home, no recurring licence. Bounce reasons are configurable data, not hard-coded enum literals. Read it, extend it, fork it if you need to.
Day in the life
An accounts clerk handles a bounced foreign-currency cheque.
A customer's USD cheque was deposited last week and the bank now returns it. The clerk opens the cheque, runs the bounce wizard, picks insufficient funds as the reason and enters the bank charge. The module reverses the original present entry (which had converted the USD amount into company currency while carrying the signed USD in amount_currency, so the reversal stays balanced) and records the charge amount on the cheque. The customer agrees to re-bank. The replace wizard chains a fresh cheque with a new value date and stamps the original as replaced, so the trail from the first cheque to its replacement is intact. Tomorrow the daily cron will auto-present the replacement once its value date arrives, each row in its own savepoint so a single bad record cannot abort the run.
Edge cases
The cases most modules quietly ignore.
In the shipped code today, each one a place where a cheaper module silently does the wrong thing.
A foreign-currency cheque posts the present, clear and bounce entries by converting the cheque amount into company currency for debit and credit while carrying the signed foreign amount in amount_currency, so FX cheques post balanced and stay reconcilable.
A post dated cheque cannot be presented before its value date, because real banks refuse it. An explicit eh_pdc_force_early context key exists for opening-balance and data-import backfill.
Registration takes a SELECT FOR UPDATE row lock on the cheque book so two simultaneous registrations queue instead of racing the next-serial pointer, with a unique constraint on book and cheque number as the safety net.
Registering a serial that is not the book's next number is rejected with a remediation message, preventing out-of-order or skipped cheque numbers.
The bounce only posts a reversal when the present move actually exists and is posted, so it never double-reverses and never reverses an unposted entry.
When the last serial in a book is consumed the book flips to exhausted automatically, and only one in-use book is allowed per journal and company.
Posting raises an explicit error naming the missing suspense, default, receivable or payable account rather than writing a one-sided or broken journal entry.
What is inside
Built to do the job, end to end.
- Cheque register. One model for issued (payable) and received (receivable) cheques with a direction flag, counterparty, bank journal, issue and value dates, amount and currency. Guarded lifecycle: draft, registered, presented, cleared, bounced, replaced, cancelled, each transition stamping user and timestamp.
- Cheque books. Per bank journal with start and end serials, a next-serial pointer and remaining count. Concurrency-safe allocation by row lock, serial-gap rejection, automatic exhaustion when the last serial is consumed, and one in-use book per journal and company.
- Posting engine. Present, clear and bounce post balanced double-entry journals through a suspense account, with multi-currency conversion and amount_currency. A hard-fail resolver names any missing account rather than posting a broken move. Cleared-cheque bank lines are available to standard bank reconciliation.
- Bounce and replace. Bounce wizard with a configurable reason lookup (insufficient funds, signature, stop payment, account closed, post dated, technical, amount mismatch, other) and a bank-charge amount captured on the cheque. Replace wizard re-banks via a new cheque carrying a new value date and chains it to the original.
- Auto-present cron. A daily cron auto-presents every registered cheque, issued or received, once its value date arrives. Each cheque runs in its own savepoint so a single failing row never aborts the batch.
- Smart buttons and register report. Smart-button counters on the partner, invoice and payment forms show linked or open cheques, plus a kanban grouped by state. A printable PDF cheque register prints any filtered selection with status and lifecycle dates; the list groups interactively by journal or direction.
Honest about the edges
What this does not do, so nothing surprises you.
- There is no write-off transition. A bounced cheque can be replaced or left bounced; the bank-charge amount is stored on the cheque as data and is not posted to any account, and there is no FX gain or loss posting.
- The cron auto-presents both issued and received cheques on their value date. There is no per-direction or per-bank-policy switch.
- The payment link is an informational read-only field. Clearance posts a bank journal entry but does not stamp the linked payment as reconciled.
- There is no aged or aging report and no dashboard. The only report is a flat PDF cheque register; outstanding cheques are surfaced through the built-in Overdue filter, smart buttons and a state kanban.
- There is no cheque-to-journal-entry drill in the form, no partner-ledger integration and no close-checklist integration.
post dated cheque management odoo, PDC odoo 19 community, cheque register odoo, cheque book serial tracking odoo, issued and received cheque tracking, cheque bounce and replace workflow, post dated cheque accounting, cheque clearing suspense account odoo, cheque lifecycle state machine odoo
Languages
Available in 19 languages
The interface ships translated out of the box. Switch language in Odoo and the fields, menus, and messages follow.
Please log in to comment on this module