Skip to content

[FIX] product_replenishment_cost: process every pending batch on each cron run - #930

Open
les-adhoc wants to merge 1 commit into
ingadhoc:18.0from
adhoc-dev:18.0-h-123231-les
Open

les-adhoc wants to merge 1 commit into
ingadhoc:18.0from
adhoc-dev:18.0-h-123231-les

Conversation

@les-adhoc

@les-adhoc les-adhoc commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Problem

A full pass over the catalog used to depend on N chained runs: _cron_update_cost_from_replenishment_cost() processed 1000 products per run, stored a cursor in ir.config_parameter and enqueued the next batch with cron._trigger().

That chain is fragile:

  • If a batch fails (data error, contention, cron time limit) the remaining batches are not executed until the next scheduled run — monthly by default — and the catalog stays half updated.
  • There is no observable point where the pass is complete. A successful run only means that batch went through, not that the catalog was covered.
  • The continuation depends on the scheduler's trigger mechanism; anything that interrupts it leaves the work unfinished with no signal.

What changes

  • A run now walks every pending batch. The commit per batch is kept, so the transaction is no longer than before, and if MAX_BATCHES_PER_CRON_RUN (50) is exhausted the continuation is still enqueued with the trigger.
  • The cursor is carried in memory across batches instead of being re-read from the parameter on every batch. It is persisted with a direct UPDATE because set_param would clear the registry cache — which left the ORM cache of the record stale and made the loop reprocess the same batch over and over. The record is invalidated after the UPDATE so any later reader gets the fresh value.
  • The batch search uses limit=batch_size + 1 instead of loading the whole table to len() it.
  • _bom_find is resolved once per record in product_replenishment_cost_mrp, instead of up to three times through a ternary that repeated the whole expression. Same behaviour.
  • First tests for product_replenishment_cost_mrp, which had none.

No product cost changes value. Only which products a run reaches.

Test plan

0 failed, 0 error(s)
product_replenishment_cost:     30 tests
product_replenishment_cost_mrp:  5 tests

TestCronUpdateCostAllBatches.test_cron_processes_every_pending_batch runs the cron with batch_size=1 over four products and asserts that all of them end up updated and that the cursor is back to 0. Forcing MAX_BATCHES_PER_CRON_RUN = 1 (the previous behaviour) makes it fail, so it does measure the change.

Note

A run now takes proportionally longer — as many times as there are batches in the catalog. Worth keeping in mind if it is triggered from the UI on a large database.

@roboadhoc

Copy link
Copy Markdown
Contributor

Pull request status dashboard

@les-adhoc les-adhoc changed the title [FIX] product_replenishment_cost: accounting cost update on multi level BoM and full cron run [FIX] product_replenishment_cost: process every pending batch on each cron run Aug 4, 2026
… cron run

A full pass over the catalog used to depend on N chained runs: each run processed
1000 products and enqueued the next one with a cron trigger. That chain is
fragile. If a batch fails (data error, contention, cron time limit) the remaining
batches are not executed until the next scheduled run, monthly by default, and
the catalog stays half updated. There is also no observable point where the pass
is complete: a successful run only means that batch went through, not that the
catalog was covered.

A run now walks every pending batch. The commit per batch is kept, so the
transaction is no longer than before, and if MAX_BATCHES_PER_CRON_RUN is
exhausted the continuation is still enqueued with the trigger.

The cursor is carried in memory across batches instead of being re-read from the
parameter on every batch. It is persisted with a direct UPDATE because set_param
would clear the registry cache, which left the ORM cache of the record stale and
made the loop reprocess the same batch over and over. The record is invalidated
after the UPDATE so any later reader gets the fresh value, and the batch search
uses a limit instead of loading the whole table to count it.

Also resolves _bom_find once per record in product_replenishment_cost_mrp, which
was called up to three times through a ternary that repeated the whole
expression, and adds the first tests of that module.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants