{"record":{"id":"d7da1185eecabe83","repo":"odoo/odoo","slug":"you-cannot-add-modify-entries-prior-to-and-inclusi","errorCode":null,"errorMessage":"You cannot add/modify entries prior to and inclusive of: %(lock_date_info)s.","messagePattern":"You cannot add/modify entries prior to and inclusive of: (.+?)\\.","errorType":"exception","errorClass":"UserError","httpStatus":null,"severity":"error","filePath":"addons/account/models/account_move.py","lineNumber":2824,"sourceCode":"        ''', tuple(moves.ids)))\n\n    def _check_fiscal_lock_dates(self):\n        if self.env.context.get('bypass_lock_check') is BYPASS_LOCK_CHECK:\n            return\n        for move in self:\n            journal = move.journal_id\n            violated_lock_dates = move.company_id._get_lock_date_violations(\n                move.date,\n                fiscalyear=True,\n                sale=journal and journal.type == 'sale',\n                purchase=journal and journal.type == 'purchase',\n                tax=False,\n                hard=True,\n            )\n            if violated_lock_dates:\n                message = _(\"You cannot add/modify entries prior to and inclusive of: %(lock_date_info)s.\",\n                            lock_date_info=self.env['res.company']._format_lock_dates(violated_lock_dates))\n                raise UserError(message)\n        return True\n\n    @api.constrains('auto_post', 'invoice_date')\n    def _require_bill_date_for_autopost(self):\n        \"\"\"Vendor bills must have an invoice date set to be posted. Require it for auto-posted bills.\"\"\"\n        for record in self:\n            if record.auto_post != 'no' and record.is_purchase_document() and not record.invoice_date:\n                raise ValidationError(_(\"For this entry to be automatically posted, it required a bill date.\"))\n\n    @api.constrains('journal_id', 'move_type')\n    def _check_journal_move_type(self):\n        for move in self:\n            if move.is_purchase_document(include_receipts=True) and move.journal_id.type != 'purchase':\n                raise ValidationError(_(\"Cannot create a purchase document in a non purchase journal\"))\n            if move.is_sale_document(include_receipts=True) and move.journal_id.type != 'sale':\n                raise ValidationError(_(\"Cannot create a sale document in a non sale journal\"))\n\n    @api.constrains('line_ids', 'fiscal_position_id', 'company_id')","sourceCodeStart":2806,"sourceCodeEnd":2842,"githubUrl":"https://github.com/odoo/odoo/blob/1e661df964b1b264c9cef3ab28430d4785be3fda/addons/account/models/account_move.py#L2806-L2842","documentation":"UserError from _check_fiscal_lock_dates when a move's date falls on or before an active lock date of its company (fiscal year lock, plus hard sale/purchase locks depending on journal type, fiscalyear=True, hard=True). Lock dates freeze the ledger so reported periods cannot change; the message enumerates which locks are violated via _format_lock_dates.","triggerScenarios":"Creating/editing/posting a move whose date <= company hard lock date: write({'date': ...}) backdating an entry; posting an old invoice; creating entries dated in a closed fiscal year; the write() path also calls this when changing name/date of posted moves or unposting.","commonSituations":"Backdating invoices after year-end closing; users in a period already locked by the accountant; imports with historical dates after locks were set; trying to reset a posted move to draft across the lock.","solutions":["Set the move's date to a date after all violated lock dates","Ask an advisor/admin to adjust or clear the lock dates: Settings > Accounting > Lock Dates (or write on res.company lock fields) and retry","If the entry genuinely belongs in the locked period, temporarily lift the hard lock, make the change, restore it — with auditor awareness","Use context keys only if the code path legitimately bypasses checks (e.g. closing operations), never to silently edit locked periods"],"exampleFix":"// before\nmove.write({'date': '2023-12-15'})  # company fiscal year locked at 2023-12-31\n\n// after\nlock = move.company_id.fiscalyear_lock_date\nsafe_date = lock + timedelta(days=1) if lock and fields.Date.to_date('2023-12-15') <= lock else '2023-12-15'\nmove.write({'date': safe_date})","handlingStrategy":"validation","validationCode":"def lock_violations(move, date):\n    return move.company_id._get_lock_date_violations(date, fiscalyear=True, sale=move.journal_id.type=='sale', purchase=move.journal_id.type=='purchase', tax=False, hard=True)","typeGuard":null,"tryCatchPattern":"try:\n    move.write({'date': new_date})\nexcept UserError as e:\n    if 'lock' in str(e).lower():\n        move.write({'date': safe_after_lock(move.company_id)})","preventionTips":["Before writing dates, compare them against company_id.fiscalyear_lock_date / tax_lock_date / hard lock fields","Clamp imported historical dates to the open period unless an advisor authorizes unlocking","Surface lock dates in the UI/automation so users pick valid dates in the first place"],"tags":["odoo","accounting","lock-date","fiscal-year","audit"],"backgroundTag":null,"analyzedSha":"1e661df964b1b264c9cef3ab28430d4785be3fda","analyzedAt":"2026-08-15T05:22:16.142Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}