diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py index b393c2bba45..dec591d7961 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py @@ -22,6 +22,7 @@ from erpnext.stock.stock_ledger import ( get_items_to_be_repost, repost_future_sle, ) +from erpnext.stock.utils import get_combine_datetime RecoverableErrors = (JobTimeoutException, QueryDeadlockError, QueryTimeoutError) @@ -321,28 +322,26 @@ class RepostItemValuation(Document): if self.based_on != "Item and Warehouse": return - filters = { - "item_code": self.item_code, - "warehouse": self.warehouse, - "name": self.name, - "posting_date": self.posting_date, - "posting_time": self.posting_time, - } - - frappe.db.sql( - """ - update `tabRepost Item Valuation` - set status = 'Skipped' - WHERE item_code = %(item_code)s - and warehouse = %(warehouse)s - and name != %(name)s - and TIMESTAMP(posting_date, posting_time) > TIMESTAMP(%(posting_date)s, %(posting_time)s) - and docstatus = 1 - and status = 'Queued' - and based_on = 'Item and Warehouse' - """, - filters, - ) + riv = frappe.qb.DocType("Repost Item Valuation") + ( + frappe.qb.update(riv) + .set(riv.status, "Skipped") + .where( + (riv.item_code == self.item_code) + & (riv.warehouse == self.warehouse) + & (riv.name != self.name) + # CombineDatetime on the column is portable (TIMESTAMP() is MySQL-only) and keeps the + # original NULL semantics (rows with NULL posting_time stay excluded); the RHS is this + # doc's own (always-set) posting datetime, computed in Python. + & ( + CombineDatetime(riv.posting_date, riv.posting_time) + > get_combine_datetime(self.posting_date, self.posting_time) + ) + & (riv.docstatus == 1) + & (riv.status == "Queued") + & (riv.based_on == "Item and Warehouse") + ) + ).run() def _recalculate_valuation_rate(self): doc = frappe.get_doc(self.voucher_type, self.voucher_no)