diff --git a/accounts/doctype/gl_entry/gl_entry.py b/accounts/doctype/gl_entry/gl_entry.py index 27199260f3..2a84211695 100644 --- a/accounts/doctype/gl_entry/gl_entry.py +++ b/accounts/doctype/gl_entry/gl_entry.py @@ -18,10 +18,10 @@ class DocType: self.validate_posting_date() self.check_credit_limit() self.check_pl_account() - - def on_update(self, adv_adj, update_outstanding = 'Yes'): - self.validate_account_details(adv_adj) self.validate_cost_center() + + def on_update_with_args(self, adv_adj, update_outstanding = 'Yes'): + self.validate_account_details(adv_adj) validate_freezed_account(self.doc.account, adv_adj) check_freezing_date(self.doc.posting_date, adv_adj) check_negative_balance(self.doc.account, adv_adj) diff --git a/accounts/doctype/journal_voucher/journal_voucher.py b/accounts/doctype/journal_voucher/journal_voucher.py index 24b6bf3390..e438b7ddb3 100644 --- a/accounts/doctype/journal_voucher/journal_voucher.py +++ b/accounts/doctype/journal_voucher/journal_voucher.py @@ -49,7 +49,7 @@ class DocType(AccountsController): from accounts.utils import remove_against_link_from_jv remove_against_link_from_jv(self.doc.doctype, self.doc.name, "against_jv") - self.make_gl_entries() + self.make_gl_entries(1) def on_trash(self): pass @@ -258,7 +258,7 @@ class DocType(AccountsController): }) ) if gl_map: - make_gl_entries(gl_map, cancel=self.doc.docstatus==2, adv_adj=adv_adj) + make_gl_entries(gl_map, cancel=cancel, adv_adj=adv_adj) def get_outstanding(self, args): args = eval(args) diff --git a/accounts/general_ledger.py b/accounts/general_ledger.py index c415e2d230..99518d2fc2 100644 --- a/accounts/general_ledger.py +++ b/accounts/general_ledger.py @@ -66,20 +66,24 @@ def save_entries(gl_map, adv_adj, update_outstanding): if flt(entry["debit"]) < 0 or flt(entry["credit"]) < 0: _swap(entry) - gle = Document('GL Entry', fielddata=entry) - gle_obj = webnotes.get_obj(doc=gle) - gle_obj.validate() - gle.save(1) - gle_obj.on_update(adv_adj, update_outstanding) + make_entry(entry, adv_adj, update_outstanding) validate_expense_against_budget(entry) # update total debit / credit - total_debit += flt(gle.debit) - total_credit += flt(gle.credit) - + total_debit += flt(entry["debit"]) + total_credit += flt(entry["credit"]) + validate_total_debit_credit(total_debit, total_credit) +def make_entry(args, adv_adj, update_outstanding): + args.update({"doctype": "GL Entry"}) + gle = webnotes.bean([args]) + gle.ignore_permissions = 1 + gle.insert() + gle.run_method("on_update_with_args", adv_adj, update_outstanding) + gle.submit() + def validate_total_debit_credit(total_debit, total_credit): if abs(total_debit - total_credit) > 0.005: webnotes.throw(_("Debit and Credit not equal for this voucher: Diff (Debit) is ") + @@ -102,4 +106,4 @@ def delete_gl_entries(gl_entries, adv_adj, update_outstanding): if entry.get("against_voucher") and entry.get("against_voucher_type") != "POS" \ and update_outstanding == 'Yes': update_outstanding_amt(entry["account"], entry.get("against_voucher_type"), - entry.get("against_voucher")) \ No newline at end of file + entry.get("against_voucher"), on_cancel=True) \ No newline at end of file diff --git a/patches/august_2013/p01_perpetual_accounting_patch.py b/patches/august_2013/p01_perpetual_accounting_patch.py index b3c993dd6e..2f08259e90 100644 --- a/patches/august_2013/p01_perpetual_accounting_patch.py +++ b/patches/august_2013/p01_perpetual_accounting_patch.py @@ -2,6 +2,9 @@ import webnotes from webnotes.utils import cint def execute(): + import patches.september_2012.repost_stock + patches.september_2012.repost_stock.execute() + import patches.march_2013.p08_create_aii_accounts patches.march_2013.p08_create_aii_accounts.execute() diff --git a/patches/august_2013/p06_deprecate_is_cancelled.py b/patches/august_2013/p06_deprecate_is_cancelled.py index 693a1ae159..ad196bd140 100644 --- a/patches/august_2013/p06_deprecate_is_cancelled.py +++ b/patches/august_2013/p06_deprecate_is_cancelled.py @@ -7,5 +7,5 @@ def execute(): webnotes.conn.sql("""delete from `tabStock Ledger Entry` where ifnull(is_cancelled, 'No') = 'Yes'""") - webnotes.reload_doc("stock", "doctype", "gl_entry") + webnotes.reload_doc("accounts", "doctype", "gl_entry") webnotes.conn.sql("""delete from `tabGL Entry` where ifnull(is_cancelled, 'No') = 'Yes'""") \ No newline at end of file diff --git a/stock/doctype/delivery_note/test_delivery_note.py b/stock/doctype/delivery_note/test_delivery_note.py index dbf6d4ff01..7c2ca43e25 100644 --- a/stock/doctype/delivery_note/test_delivery_note.py +++ b/stock/doctype/delivery_note/test_delivery_note.py @@ -49,6 +49,13 @@ class TestDeliveryNote(unittest.TestCase): dn.insert() dn.submit() + stock_value, stock_value_difference = webnotes.conn.get_value("Stock Ledger Entry", + {"voucher_type": "Delivery Note", "voucher_no": dn.doc.name, + "item_code": "_Test Item"}, ["stock_value", "stock_value_difference"]) + self.assertEqual(stock_value, 0) + self.assertEqual(stock_value_difference, -375) + + gl_entries = webnotes.conn.sql("""select account, debit, credit from `tabGL Entry` where voucher_type='Delivery Note' and voucher_no=%s order by account desc""", dn.doc.name, as_dict=1) diff --git a/stock/doctype/purchase_receipt/test_purchase_receipt.py b/stock/doctype/purchase_receipt/test_purchase_receipt.py index 3190fa37fa..0ba5470e6e 100644 --- a/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -39,6 +39,17 @@ class TestPurchaseReceipt(unittest.TestCase): pr.insert() pr.submit() + stock_value, stock_value_difference = webnotes.conn.get_value("Stock Ledger Entry", + {"voucher_type": "Purchase Receipt", "voucher_no": pr.doc.name, + "item_code": "_Test Item", "warehouse": "_Test Warehouse - _TC"}, + ["stock_value", "stock_value_difference"]) + self.assertEqual(stock_value, 375) + self.assertEqual(stock_value_difference, 375) + + bin_stock_value = webnotes.conn.get_value("Bin", {"item_code": "_Test Item", + "warehouse": "_Test Warehouse - _TC"}, "stock_value") + self.assertEqual(bin_stock_value, 375) + gl_entries = webnotes.conn.sql("""select account, debit, credit from `tabGL Entry` where voucher_type='Purchase Receipt' and voucher_no=%s order by account desc""", pr.doc.name, as_dict=1) diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index 71d426f48e..748cf693bf 100644 --- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -39,6 +39,9 @@ class DocType(DocListController): from accounts.utils import validate_fiscal_year validate_fiscal_year(self.doc.posting_date, self.doc.fiscal_year, self.meta.get_label("posting_date")) + def on_submit(self): + self.validate_serial_no() + #check for item quantity available in stock def actual_amt_check(self): if self.doc.batch_no: @@ -79,10 +82,7 @@ class DocType(DocListController): msgprint("Warehouse: '%s' does not exist in the system. Please check." % self.doc.fields.get(k), raise_exception = 1) def validate_item(self): - item_det = webnotes.conn.sql("""select name, has_batch_no, docstatus, - is_stock_item, has_serial_no, serial_no_series - from tabItem where name=%s""", - self.doc.item_code, as_dict=True)[0] + item_det = self.get_item_details() if item_det.is_stock_item != 'Yes': webnotes.throw("""Item: "%s" is not a Stock Item.""" % self.doc.item_code) @@ -96,10 +96,15 @@ class DocType(DocListController): if not webnotes.conn.sql("""select name from `tabBatch` where item='%s' and name ='%s' and docstatus != 2""" % (self.doc.item_code, self.doc.batch_no)): webnotes.throw("'%s' is not a valid Batch Number for Item '%s'" % (self.doc.batch_no, self.doc.item_code)) + + def get_item_details(self): + return webnotes.conn.sql("""select name, has_batch_no, docstatus, + is_stock_item, has_serial_no, serial_no_series + from tabItem where name=%s""", + self.doc.item_code, as_dict=True)[0] - self.validate_serial_no(item_det) - - def validate_serial_no(self, item_det): + def validate_serial_no(self): + item_det = self.get_item_details() if item_det.has_serial_no=="No": if self.doc.serial_no: webnotes.throw(_("Serial Number should be blank for Non Serialized Item" + ": " + self.doc.item), diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.txt b/stock/doctype/stock_ledger_entry/stock_ledger_entry.txt index 047f778462..a5ea161a73 100644 --- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.txt +++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-29 19:25:42", "docstatus": 0, - "modified": "2013-08-20 15:02:48", + "modified": "2013-08-23 12:23:18", "modified_by": "Administrator", "owner": "Administrator" }, @@ -224,6 +224,14 @@ "options": "Company:company:default_currency", "read_only": 1 }, + { + "doctype": "DocField", + "fieldname": "stock_value_difference", + "fieldtype": "Currency", + "label": "Stock Value Difference", + "options": "Company:company:default_currency", + "read_only": 1 + }, { "doctype": "DocField", "fieldname": "stock_queue", diff --git a/stock/stock_ledger.py b/stock/stock_ledger.py index 740120cf98..9a843ed549 100644 --- a/stock/stock_ledger.py +++ b/stock/stock_ledger.py @@ -46,7 +46,7 @@ def make_entry(args): sle = webnotes.bean([args]) sle.ignore_permissions = 1 sle.insert() - # sle.submit() + sle.submit() return sle.doc.name def delete_cancelled_entry(voucher_type, voucher_no): @@ -74,12 +74,13 @@ def update_entries_after(args, verbose=1): qty_after_transaction = flt(previous_sle.get("qty_after_transaction")) valuation_rate = flt(previous_sle.get("valuation_rate")) stock_queue = json.loads(previous_sle.get("stock_queue") or "[]") - stock_value = flt(previous_sle.get("stock_value")) + prev_stock_value = stock_value = flt(previous_sle.get("stock_value")) entries_to_fix = get_sle_after_datetime(previous_sle or \ {"item_code": args["item_code"], "warehouse": args["warehouse"]}, for_update=True) valuation_method = get_valuation_method(args["item_code"]) + stock_value_difference = 0.0 for sle in entries_to_fix: if sle.serial_no or not cint(webnotes.conn.get_default("allow_negative_stock")): @@ -107,12 +108,15 @@ def update_entries_after(args, verbose=1): else: stock_value = sum((flt(batch[0]) * flt(batch[1]) for batch in stock_queue)) + stock_value_difference = stock_value - prev_stock_value + prev_stock_value = stock_value + # update current sle webnotes.conn.sql("""update `tabStock Ledger Entry` set qty_after_transaction=%s, valuation_rate=%s, stock_queue=%s, - stock_value=%s where name=%s""", + stock_value=%s, stock_value_difference=%s where name=%s""", (qty_after_transaction, valuation_rate, - json.dumps(stock_queue), stock_value, sle.name)) + json.dumps(stock_queue), stock_value, stock_value_difference, sle.name)) if _exceptions: _raise_exceptions(args, verbose)