mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-06 21:59:13 +00:00
feat: Stock value and account balance sync. (#19233)
* feat: Allow user to sync stock_value and account_balance jv if perpetual inventory is checked * fix(test): Sales Invoice * fix(test): Purchase Invoice * fix(test): Delivery Note * fix: more test_case * fix(test): Stock Entry * fix(test): Purchase Receipt * fix(more-test): Stock Entries * fix(more-test): Sales Invoice and Delivery Note * fix: tests for delivery note * fix: tests for stock reconciliation * refactor: stock and account balance function * fix(more-test): Warehouse * fix(test): Landed Cost Voucher * fix: changes requested
This commit is contained in:
committed by
Nabin Hait
parent
7e9b90ad06
commit
a11e738801
@@ -3,8 +3,9 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe, erpnext
|
||||
from frappe.utils import flt, cstr, cint
|
||||
from frappe.utils import flt, cstr, cint, comma_and
|
||||
from frappe import _
|
||||
from erpnext.accounts.utils import get_stock_and_account_balance
|
||||
from frappe.model.meta import get_field_precision
|
||||
from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget
|
||||
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
||||
@@ -12,6 +13,7 @@ from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import g
|
||||
|
||||
class ClosedAccountingPeriod(frappe.ValidationError): pass
|
||||
class StockAccountInvalidTransaction(frappe.ValidationError): pass
|
||||
class StockValueAndAccountBalanceOutOfSync(frappe.ValidationError): pass
|
||||
|
||||
def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True, update_outstanding='Yes', from_repost=False):
|
||||
if gl_map:
|
||||
@@ -115,11 +117,9 @@ def check_if_in_list(gle, gl_map, dimensions=None):
|
||||
|
||||
def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
|
||||
if not from_repost:
|
||||
validate_account_for_perpetual_inventory(gl_map)
|
||||
validate_cwip_accounts(gl_map)
|
||||
|
||||
round_off_debit_credit(gl_map)
|
||||
|
||||
for entry in gl_map:
|
||||
make_entry(entry, adv_adj, update_outstanding, from_repost)
|
||||
|
||||
@@ -127,6 +127,10 @@ def save_entries(gl_map, adv_adj, update_outstanding, from_repost=False):
|
||||
if not from_repost:
|
||||
validate_expense_against_budget(entry)
|
||||
|
||||
if not from_repost:
|
||||
validate_account_for_perpetual_inventory(gl_map)
|
||||
|
||||
|
||||
def make_entry(args, adv_adj, update_outstanding, from_repost=False):
|
||||
args.update({"doctype": "GL Entry"})
|
||||
gle = frappe.get_doc(args)
|
||||
@@ -137,15 +141,31 @@ def make_entry(args, adv_adj, update_outstanding, from_repost=False):
|
||||
gle.submit()
|
||||
|
||||
def validate_account_for_perpetual_inventory(gl_map):
|
||||
if cint(erpnext.is_perpetual_inventory_enabled(gl_map[0].company)) \
|
||||
and gl_map[0].voucher_type=="Journal Entry":
|
||||
aii_accounts = [d[0] for d in frappe.db.sql("""select name from tabAccount
|
||||
where account_type = 'Stock' and is_group=0""")]
|
||||
if cint(erpnext.is_perpetual_inventory_enabled(gl_map[0].company)):
|
||||
account_list = [gl_entries.account for gl_entries in gl_map]
|
||||
|
||||
for entry in gl_map:
|
||||
if entry.account in aii_accounts:
|
||||
aii_accounts = [d.name for d in frappe.get_all("Account",
|
||||
filters={'account_type': 'Stock', 'is_group': 0, 'company': gl_map[0].company})]
|
||||
|
||||
for account in account_list:
|
||||
if account not in aii_accounts:
|
||||
continue
|
||||
|
||||
account_bal, stock_bal, warehouse_list = get_stock_and_account_balance(account,
|
||||
gl_map[0].posting_date, gl_map[0].company)
|
||||
|
||||
if gl_map[0].voucher_type=="Journal Entry":
|
||||
# In case of Journal Entry, there are no corresponding SL entries,
|
||||
# hence deducting currency amount
|
||||
account_bal -= flt(gl_map[0].debit) - flt(gl_map[0].credit)
|
||||
if account_bal == stock_bal:
|
||||
frappe.throw(_("Account: {0} can only be updated via Stock Transactions")
|
||||
.format(entry.account), StockAccountInvalidTransaction)
|
||||
.format(account), StockAccountInvalidTransaction)
|
||||
|
||||
elif account_bal != stock_bal:
|
||||
frappe.throw(_("Account Balance ({0}) and Stock Value ({1}) is out of sync for account {2} and linked warehouse ({3}). Please create adjustment Journal Entry for amount {4}.")
|
||||
.format(account_bal, stock_bal, account, comma_and(warehouse_list), stock_bal - account_bal),
|
||||
StockValueAndAccountBalanceOutOfSync)
|
||||
|
||||
def validate_cwip_accounts(gl_map):
|
||||
if not cint(frappe.db.get_value("Asset Settings", None, "disable_cwip_accounting")) \
|
||||
|
||||
Reference in New Issue
Block a user