diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index 913656ad020..00d27ef232b 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -27,7 +27,6 @@ class IncorrectValuationRateError(frappe.ValidationError): pass class DuplicateEntryForWorkOrderError(frappe.ValidationError): pass class OperationsNotCompleteError(frappe.ValidationError): pass class MaxSampleAlreadyRetainedError(frappe.ValidationError): pass -class TotalBasicAmountZeroError(frappe.ValidationError): pass from erpnext.controllers.stock_controller import StockController @@ -650,11 +649,11 @@ class StockEntry(StockController): gl_entries = super(StockEntry, self).get_gl_entries(warehouse_account) total_basic_amount = sum([flt(t.basic_amount) for t in self.get("items") if t.t_warehouse]) + divide_based_on = total_basic_amount if self.get("additional_costs") and not total_basic_amount: - #If additional costs table is populated and total basic amount is - #somehow 0, interrupt transaction. - frappe.throw(_("Total Basic Amount in Items Table cannot be 0"), TotalBasicAmountZeroError) + # if total_basic_amount is 0, distribute additional charges based on qty + divide_based_on = sum(item.qty for item in list(self.get("items"))) item_account_wise_additional_cost = {} @@ -663,8 +662,11 @@ class StockEntry(StockController): if d.t_warehouse: item_account_wise_additional_cost.setdefault((d.item_code, d.name), {}) item_account_wise_additional_cost[(d.item_code, d.name)].setdefault(t.expense_account, 0.0) + + multiply_based_on = d.basic_amount if total_basic_amount else d.qty + item_account_wise_additional_cost[(d.item_code, d.name)][t.expense_account] += \ - (t.amount * d.basic_amount) / total_basic_amount + (t.amount * multiply_based_on) / divide_based_on if item_account_wise_additional_cost: for d in self.get("items"): diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index c5e67092d3d..ee5f2370987 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -16,7 +16,6 @@ from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry from erpnext.accounts.doctype.account.test_account import get_inventory_account from erpnext.stock.doctype.stock_entry.stock_entry import move_sample_to_retention_warehouse, make_stock_in_entry from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import OpeningEntryAccountError -from erpnext.stock.doctype.stock_entry.stock_entry import TotalBasicAmountZeroError from six import iteritems def get_sle(**args): @@ -798,14 +797,26 @@ class TestStockEntry(unittest.TestCase): "posting_date": nowdate(), "company":"_Test Company with perpetual inventory", "items":[ - {"item_code":"Basil Leaves", - "description":"Basil Leaves", - "qty": 1, - "basic_rate": 0, - "uom":"Nos", - "t_warehouse": "Stores - TCP1", - "allow_zero_valuation_rate": 1, - "cost_center": "Main - TCP1"} + { + "item_code":"Basil Leaves", + "description":"Basil Leaves", + "qty": 1, + "basic_rate": 0, + "uom":"Nos", + "t_warehouse": "Stores - TCP1", + "allow_zero_valuation_rate": 1, + "cost_center": "Main - TCP1" + }, + { + "item_code":"Basil Leaves", + "description":"Basil Leaves", + "qty": 2, + "basic_rate": 0, + "uom":"Nos", + "t_warehouse": "Stores - TCP1", + "allow_zero_valuation_rate": 1, + "cost_center": "Main - TCP1" + }, ], "additional_costs":[ {"expense_account":"Miscellaneous Expenses - TCP1", @@ -813,9 +824,15 @@ class TestStockEntry(unittest.TestCase): "description": "miscellanous"} ] }) - se.insert() - self.assertRaises(TotalBasicAmountZeroError, se.submit) + se.submit() + + self.check_gl_entries("Stock Entry", se.name, + sorted([ + ["Stock Adjustment - TCP1", 100.0, 0.0], + ["Miscellaneous Expenses - TCP1", 0.0, 100.0] + ]) + ) def make_serialized_item(item_code=None, serial_no=None, target_warehouse=None): se = frappe.copy_doc(test_records[0])