mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-02 19:59:12 +00:00
refactor: simpler batching for GLE reposting (#31374)
* refactor: simpler batching for GLE reposting * test: add "actual" test for chunked GLE reposting
This commit is contained in:
@@ -2,7 +2,6 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
|
||||||
import itertools
|
|
||||||
from json import loads
|
from json import loads
|
||||||
from typing import TYPE_CHECKING, List, Optional, Tuple
|
from typing import TYPE_CHECKING, List, Optional, Tuple
|
||||||
|
|
||||||
@@ -11,7 +10,17 @@ import frappe.defaults
|
|||||||
from frappe import _, qb, throw
|
from frappe import _, qb, throw
|
||||||
from frappe.model.meta import get_field_precision
|
from frappe.model.meta import get_field_precision
|
||||||
from frappe.query_builder.utils import DocType
|
from frappe.query_builder.utils import DocType
|
||||||
from frappe.utils import cint, cstr, flt, formatdate, get_number_format_info, getdate, now, nowdate
|
from frappe.utils import (
|
||||||
|
cint,
|
||||||
|
create_batch,
|
||||||
|
cstr,
|
||||||
|
flt,
|
||||||
|
formatdate,
|
||||||
|
get_number_format_info,
|
||||||
|
getdate,
|
||||||
|
now,
|
||||||
|
nowdate,
|
||||||
|
)
|
||||||
from pypika import Order
|
from pypika import Order
|
||||||
from pypika.terms import ExistsCriterion
|
from pypika.terms import ExistsCriterion
|
||||||
|
|
||||||
@@ -1149,9 +1158,7 @@ def repost_gle_for_stock_vouchers(
|
|||||||
|
|
||||||
precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit")) or 2
|
precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit")) or 2
|
||||||
|
|
||||||
stock_vouchers_iterator = iter(stock_vouchers)
|
for stock_vouchers_chunk in create_batch(stock_vouchers, GL_REPOSTING_CHUNK):
|
||||||
|
|
||||||
while stock_vouchers_chunk := list(itertools.islice(stock_vouchers_iterator, GL_REPOSTING_CHUNK)):
|
|
||||||
gle = get_voucherwise_gl_entries(stock_vouchers_chunk, posting_date)
|
gle = get_voucherwise_gl_entries(stock_vouchers_chunk, posting_date)
|
||||||
|
|
||||||
for voucher_type, voucher_no in stock_vouchers_chunk:
|
for voucher_type, voucher_no in stock_vouchers_chunk:
|
||||||
@@ -1173,7 +1180,7 @@ def repost_gle_for_stock_vouchers(
|
|||||||
if repost_doc:
|
if repost_doc:
|
||||||
repost_doc.db_set(
|
repost_doc.db_set(
|
||||||
"gl_reposting_index",
|
"gl_reposting_index",
|
||||||
cint(repost_doc.gl_reposting_index) + GL_REPOSTING_CHUNK,
|
cint(repost_doc.gl_reposting_index) + len(stock_vouchers_chunk),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ class RepostItemValuation(Document):
|
|||||||
self.current_index = 0
|
self.current_index = 0
|
||||||
self.distinct_item_and_warehouse = None
|
self.distinct_item_and_warehouse = None
|
||||||
self.items_to_be_repost = None
|
self.items_to_be_repost = None
|
||||||
|
self.gl_reposting_index = 0
|
||||||
self.db_update()
|
self.db_update()
|
||||||
|
|
||||||
def deduplicate_similar_repost(self):
|
def deduplicate_similar_repost(self):
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from unittest.mock import MagicMock, call
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.tests.utils import FrappeTestCase
|
from frappe.tests.utils import FrappeTestCase
|
||||||
from frappe.utils import nowdate
|
from frappe.utils import nowdate
|
||||||
from frappe.utils.data import today
|
from frappe.utils.data import add_to_date, today
|
||||||
|
|
||||||
from erpnext.accounts.utils import repost_gle_for_stock_vouchers
|
from erpnext.accounts.utils import repost_gle_for_stock_vouchers
|
||||||
from erpnext.controllers.stock_controller import create_item_wise_repost_entries
|
from erpnext.controllers.stock_controller import create_item_wise_repost_entries
|
||||||
@@ -17,10 +17,11 @@ from erpnext.stock.doctype.repost_item_valuation.repost_item_valuation import (
|
|||||||
in_configured_timeslot,
|
in_configured_timeslot,
|
||||||
)
|
)
|
||||||
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||||
|
from erpnext.stock.tests.test_utils import StockTestMixin
|
||||||
from erpnext.stock.utils import PendingRepostingError
|
from erpnext.stock.utils import PendingRepostingError
|
||||||
|
|
||||||
|
|
||||||
class TestRepostItemValuation(FrappeTestCase):
|
class TestRepostItemValuation(FrappeTestCase, StockTestMixin):
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
frappe.flags.dont_execute_stock_reposts = False
|
frappe.flags.dont_execute_stock_reposts = False
|
||||||
|
|
||||||
@@ -225,3 +226,49 @@ class TestRepostItemValuation(FrappeTestCase):
|
|||||||
repost_gle_for_stock_vouchers(stock_vouchers=vouchers, posting_date=posting_date, repost_doc=doc)
|
repost_gle_for_stock_vouchers(stock_vouchers=vouchers, posting_date=posting_date, repost_doc=doc)
|
||||||
|
|
||||||
self.assertNotIn(call("gl_reposting_index", 1), doc.db_set.mock_calls)
|
self.assertNotIn(call("gl_reposting_index", 1), doc.db_set.mock_calls)
|
||||||
|
|
||||||
|
def test_gl_complete_gl_reposting(self):
|
||||||
|
from erpnext.accounts import utils
|
||||||
|
|
||||||
|
# lower numbers to simplify test
|
||||||
|
orig_chunk_size = utils.GL_REPOSTING_CHUNK
|
||||||
|
utils.GL_REPOSTING_CHUNK = 2
|
||||||
|
self.addCleanup(setattr, utils, "GL_REPOSTING_CHUNK", orig_chunk_size)
|
||||||
|
|
||||||
|
item = self.make_item().name
|
||||||
|
|
||||||
|
company = "_Test Company with perpetual inventory"
|
||||||
|
|
||||||
|
for _ in range(10):
|
||||||
|
make_stock_entry(item=item, company=company, qty=1, rate=10, target="Stores - TCP1")
|
||||||
|
|
||||||
|
# consume
|
||||||
|
consumption = make_stock_entry(item=item, company=company, qty=1, source="Stores - TCP1")
|
||||||
|
|
||||||
|
self.assertGLEs(
|
||||||
|
consumption,
|
||||||
|
[{"credit": 10, "debit": 0}],
|
||||||
|
gle_filters={"account": "Stock In Hand - TCP1"},
|
||||||
|
)
|
||||||
|
|
||||||
|
# backdated receipt
|
||||||
|
backdated_receipt = make_stock_entry(
|
||||||
|
item=item,
|
||||||
|
company=company,
|
||||||
|
qty=1,
|
||||||
|
rate=50,
|
||||||
|
target="Stores - TCP1",
|
||||||
|
posting_date=add_to_date(today(), days=-1),
|
||||||
|
)
|
||||||
|
self.assertGLEs(
|
||||||
|
backdated_receipt,
|
||||||
|
[{"credit": 0, "debit": 50}],
|
||||||
|
gle_filters={"account": "Stock In Hand - TCP1"},
|
||||||
|
)
|
||||||
|
|
||||||
|
# check that original consumption GLe is updated
|
||||||
|
self.assertGLEs(
|
||||||
|
consumption,
|
||||||
|
[{"credit": 50, "debit": 0}],
|
||||||
|
gle_filters={"account": "Stock In Hand - TCP1"},
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user