mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-28 01:14:46 +00:00
fix: sort stock vouchers before reposting GLE
This commit is contained in:
@@ -1,10 +1,17 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
import frappe
|
||||||
from frappe.test_runner import make_test_objects
|
from frappe.test_runner import make_test_objects
|
||||||
|
|
||||||
from erpnext.accounts.party import get_party_shipping_address
|
from erpnext.accounts.party import get_party_shipping_address
|
||||||
from erpnext.accounts.utils import get_future_stock_vouchers, get_voucherwise_gl_entries
|
from erpnext.accounts.utils import (
|
||||||
|
get_future_stock_vouchers,
|
||||||
|
get_voucherwise_gl_entries,
|
||||||
|
sort_stock_vouchers_by_posting_date,
|
||||||
|
)
|
||||||
|
from erpnext.stock.doctype.item.test_item import make_item
|
||||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
|
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
|
||||||
|
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
|
||||||
|
|
||||||
|
|
||||||
class TestUtils(unittest.TestCase):
|
class TestUtils(unittest.TestCase):
|
||||||
@@ -47,6 +54,25 @@ class TestUtils(unittest.TestCase):
|
|||||||
msg="get_voucherwise_gl_entries not returning expected GLes",
|
msg="get_voucherwise_gl_entries not returning expected GLes",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_stock_voucher_sorting(self):
|
||||||
|
vouchers = []
|
||||||
|
|
||||||
|
item = make_item().name
|
||||||
|
|
||||||
|
stock_entry = {"item": item, "to_warehouse": "_Test Warehouse - _TC", "qty": 1, "rate": 10}
|
||||||
|
|
||||||
|
se1 = make_stock_entry(posting_date="2022-01-01", **stock_entry)
|
||||||
|
se2 = make_stock_entry(posting_date="2022-02-01", **stock_entry)
|
||||||
|
se3 = make_stock_entry(posting_date="2022-03-01", **stock_entry)
|
||||||
|
|
||||||
|
for doc in (se1, se2, se3):
|
||||||
|
vouchers.append((doc.doctype, doc.name))
|
||||||
|
|
||||||
|
vouchers.append(("Stock Entry", "Wat"))
|
||||||
|
|
||||||
|
sorted_vouchers = sort_stock_vouchers_by_posting_date(list(reversed(vouchers)))
|
||||||
|
self.assertEqual(sorted_vouchers, vouchers)
|
||||||
|
|
||||||
|
|
||||||
ADDRESS_RECORDS = [
|
ADDRESS_RECORDS = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
|
|
||||||
from json import loads
|
from json import loads
|
||||||
|
from typing import List, Tuple
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
@@ -1122,6 +1123,9 @@ def update_gl_entries_after(
|
|||||||
def repost_gle_for_stock_vouchers(
|
def repost_gle_for_stock_vouchers(
|
||||||
stock_vouchers, posting_date, company=None, warehouse_account=None
|
stock_vouchers, posting_date, company=None, warehouse_account=None
|
||||||
):
|
):
|
||||||
|
if not stock_vouchers:
|
||||||
|
return
|
||||||
|
|
||||||
def _delete_gl_entries(voucher_type, voucher_no):
|
def _delete_gl_entries(voucher_type, voucher_no):
|
||||||
frappe.db.sql(
|
frappe.db.sql(
|
||||||
"""delete from `tabGL Entry`
|
"""delete from `tabGL Entry`
|
||||||
@@ -1129,6 +1133,8 @@ def repost_gle_for_stock_vouchers(
|
|||||||
(voucher_type, voucher_no),
|
(voucher_type, voucher_no),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
stock_vouchers = sort_stock_vouchers_by_posting_date(stock_vouchers)
|
||||||
|
|
||||||
if not warehouse_account:
|
if not warehouse_account:
|
||||||
warehouse_account = get_warehouse_account_map(company)
|
warehouse_account = get_warehouse_account_map(company)
|
||||||
|
|
||||||
@@ -1149,6 +1155,27 @@ def repost_gle_for_stock_vouchers(
|
|||||||
_delete_gl_entries(voucher_type, voucher_no)
|
_delete_gl_entries(voucher_type, voucher_no)
|
||||||
|
|
||||||
|
|
||||||
|
def sort_stock_vouchers_by_posting_date(
|
||||||
|
stock_vouchers: List[Tuple[str, str]]
|
||||||
|
) -> List[Tuple[str, str]]:
|
||||||
|
sle = frappe.qb.DocType("Stock Ledger Entry")
|
||||||
|
voucher_nos = [v[1] for v in stock_vouchers]
|
||||||
|
|
||||||
|
sles = (
|
||||||
|
frappe.qb.from_(sle)
|
||||||
|
.select(sle.voucher_type, sle.voucher_no, sle.posting_date, sle.posting_time, sle.creation)
|
||||||
|
.where((sle.is_cancelled == 0) & (sle.voucher_no.isin(voucher_nos)))
|
||||||
|
.groupby(sle.voucher_type, sle.voucher_no)
|
||||||
|
).run(as_dict=True)
|
||||||
|
sorted_vouchers = [(sle.voucher_type, sle.voucher_no) for sle in sles]
|
||||||
|
|
||||||
|
unknown_vouchers = set(stock_vouchers) - set(sorted_vouchers)
|
||||||
|
if unknown_vouchers:
|
||||||
|
sorted_vouchers.extend(unknown_vouchers)
|
||||||
|
|
||||||
|
return sorted_vouchers
|
||||||
|
|
||||||
|
|
||||||
def get_future_stock_vouchers(
|
def get_future_stock_vouchers(
|
||||||
posting_date, posting_time, for_warehouses=None, for_items=None, company=None
|
posting_date, posting_time, for_warehouses=None, for_items=None, company=None
|
||||||
):
|
):
|
||||||
|
|||||||
Reference in New Issue
Block a user