diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py index 241620b419..6cb0bab4dc 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.py +++ b/accounts/doctype/sales_invoice/sales_invoice.py @@ -557,8 +557,10 @@ class DocType(SellingController): if gl_entries: make_gl_entries(gl_entries, cancel=(self.doc.docstatus == 2), update_outstanding=update_outstanding, merge_entries=False) - - self.update_gl_entries_after() + + if cint(webnotes.defaults.get_global_default("perpetual_accounting")) \ + and cint(self.doc.update_stock): + self.update_gl_entries_after() def make_customer_gl_entry(self, gl_entries): if self.doc.grand_total: diff --git a/accounts/general_ledger.py b/accounts/general_ledger.py index 2dcbe57b08..876a581955 100644 --- a/accounts/general_ledger.py +++ b/accounts/general_ledger.py @@ -9,11 +9,12 @@ from accounts.utils import validate_expense_against_budget def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True, update_outstanding='Yes'): - if not cancel: - gl_map = process_gl_map(gl_map, merge_entries) - save_entries(gl_map, adv_adj, update_outstanding) - else: - delete_gl_entries(gl_map, adv_adj, update_outstanding) + if gl_map: + if not cancel: + gl_map = process_gl_map(gl_map, merge_entries) + save_entries(gl_map, adv_adj, update_outstanding) + else: + delete_gl_entries(gl_map, adv_adj=adv_adj, update_outstanding=update_outstanding) def process_gl_map(gl_map, merge_entries=True): if merge_entries: @@ -21,12 +22,13 @@ def process_gl_map(gl_map, merge_entries=True): for entry in gl_map: # round off upto 2 decimal - entry["debit"] = flt(entry["debit"], 2) - entry["credit"] = flt(entry["credit"], 2) + entry.debit = flt(entry.debit, 2) + entry.credit = flt(entry.credit, 2) # toggle debit, credit if negative entry - if flt(entry["debit"]) < 0 or flt(entry["credit"]) < 0: - entry["debit"], entry["credit"] = abs(flt(entry["credit"])), abs(flt(entry["debit"])) + if flt(entry.debit) < 0 or flt(entry.credit) < 0: + entry.debit, entry.credit = abs(flt(entry.credit)), abs(flt(entry.debit)) + return gl_map def merge_similar_entries(gl_map): @@ -36,18 +38,18 @@ def merge_similar_entries(gl_map): # to that entry same_head = check_if_in_list(entry, merged_gl_map) if same_head: - same_head['debit'] = flt(same_head['debit']) + flt(entry['debit']) - same_head['credit'] = flt(same_head['credit']) + flt(entry['credit']) + same_head.debit = flt(same_head.debit) + flt(entry.debit) + same_head.credit = flt(same_head.credit) + flt(entry.credit) else: merged_gl_map.append(entry) # filter zero debit and credit entries - merged_gl_map = filter(lambda x: flt(x["debit"])!=0 or flt(x["credit"])!=0, merged_gl_map) + merged_gl_map = filter(lambda x: flt(x.debit)!=0 or flt(x.credit)!=0, merged_gl_map) return merged_gl_map def check_if_in_list(gle, gl_mqp): for e in gl_mqp: - if e['account'] == gle['account'] and \ + if e.account == gle.account and \ cstr(e.get('against_voucher'))==cstr(gle.get('against_voucher')) \ and cstr(e.get('against_voucher_type')) == \ cstr(gle.get('against_voucher_type')) \ @@ -62,8 +64,8 @@ def save_entries(gl_map, adv_adj, update_outstanding): validate_expense_against_budget(entry) # update total debit / credit - total_debit += flt(entry["debit"]) - total_credit += flt(entry["credit"]) + total_debit += flt(entry.debit) + total_credit += flt(entry.credit) validate_total_debit_credit(total_debit, total_credit) @@ -80,14 +82,20 @@ def validate_total_debit_credit(total_debit, total_credit): webnotes.throw(webnotes._("Debit and Credit not equal for this voucher: Diff (Debit) is ") + cstr(total_debit - total_credit)) -def delete_gl_entries(gl_entries=None, adv_adj=False, update_outstanding="Yes"): +def delete_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None, + adv_adj=False, update_outstanding="Yes"): + from accounts.doctype.gl_entry.gl_entry import check_negative_balance, \ check_freezing_date, update_outstanding_amt, validate_freezed_account + + if not gl_entries: + gl_entries = webnotes.conn.sql("""select * from `tabGL Entry` + where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no), as_dict=True) if gl_entries: check_freezing_date(gl_entries[0]["posting_date"], adv_adj) webnotes.conn.sql("""delete from `tabGL Entry` where voucher_type=%s and voucher_no=%s""", - (gl_entries[0]["voucher_type"], gl_entries[0]["voucher_no"])) + (voucher_type or gl_entries[0]["voucher_type"], voucher_no or gl_entries[0]["voucher_no"])) for entry in gl_entries: validate_freezed_account(entry["account"], adv_adj) diff --git a/accounts/utils.py b/accounts/utils.py index d20cb67c57..e88804abeb 100644 --- a/accounts/utils.py +++ b/accounts/utils.py @@ -360,7 +360,6 @@ def get_stock_and_account_difference(account_list=None, posting_date=None): for account, warehouse_list in account_warehouse_map.items(): account_balance = get_balance_on(account, posting_date) stock_value = get_stock_balance_on(warehouse_list, posting_date) - if abs(flt(stock_value) - flt(account_balance)) > 0.005: difference.setdefault(account, flt(stock_value) - flt(account_balance)) diff --git a/controllers/accounts_controller.py b/controllers/accounts_controller.py index 4b63f3f65e..6761092a99 100644 --- a/controllers/accounts_controller.py +++ b/controllers/accounts_controller.py @@ -332,7 +332,7 @@ class AccountsController(TransactionBase): def get_gl_dict(self, args): """this method populates the common properties of a gl entry record""" - gl_dict = { + gl_dict = webnotes._dict({ 'company': self.doc.company, 'posting_date': self.doc.posting_date, 'voucher_type': self.doc.doctype, @@ -343,7 +343,7 @@ class AccountsController(TransactionBase): 'debit': 0, 'credit': 0, 'is_opening': self.doc.fields.get("is_opening") or "No", - } + }) gl_dict.update(args) return gl_dict diff --git a/controllers/stock_controller.py b/controllers/stock_controller.py index deb687cf95..f3f61f9eea 100644 --- a/controllers/stock_controller.py +++ b/controllers/stock_controller.py @@ -8,130 +8,130 @@ from webnotes import msgprint, _ import webnotes.defaults from controllers.accounts_controller import AccountsController +from accounts.general_ledger import make_gl_entries, delete_gl_entries class StockController(AccountsController): def make_gl_entries(self): if not cint(webnotes.defaults.get_global_default("perpetual_accounting")): return - from accounts.general_ledger import make_gl_entries, delete_gl_entries - gl_entries = self.get_gl_entries_for_stock() - - if gl_entries and self.doc.docstatus==1: + if self.doc.docstatus==1: + gl_entries = self.get_gl_entries_for_stock() make_gl_entries(gl_entries) - elif self.doc.docstatus==2: - webnotes.conn.sql("""delete from `tabGL Entry` where voucher_type=%s - and voucher_no=%s""", (self.doc.doctype, self.doc.name)) - + else: + delete_gl_entries(voucher_type=self.doc.doctype, voucher_no=self.doc.name) + self.update_gl_entries_after() - - - def get_gl_entries_for_stock(self, item_acc_map=None, expense_account=None, cost_center=None): + + def get_gl_entries_for_stock(self, default_expense_account=None, default_cost_center=None): from accounts.general_ledger import process_gl_map + warehouse_account = self.get_warehouse_account() + stock_ledger = self.get_stock_ledger_details() + voucher_details = self.get_voucher_details(stock_ledger, default_expense_account, + default_cost_center) + + gl_list = [] + for detail in voucher_details: + sle_list = stock_ledger.get(detail.name) + if sle_list: + for sle in sle_list: + if warehouse_account.get(sle.warehouse): + + # from warehouse account + gl_list.append(self.get_gl_dict({ + "account": warehouse_account[sle.warehouse], + "against": detail.expense_account, + "cost_center": detail.cost_center, + "remarks": self.doc.remarks or "Accounting Entry for Stock", + "debit": sle.stock_value_difference + })) - if not (expense_account or cost_center or item_acc_map): - item_acc_map = {} - for item in self.doclist.get({"parentfield": self.fname}): - self.check_expense_account(item) - item_acc_map.setdefault(item.name, [item.expense_account, item.cost_center]) - - gl_entries = [] - stock_value_diff = self.get_stock_value_diff_from_sle(item_acc_map, expense_account, - cost_center) - for stock_in_hand_account, against_stock_account_dict in stock_value_diff.items(): - for against_stock_account, cost_center_dict in against_stock_account_dict.items(): - for cost_center, value_diff in cost_center_dict.items(): - gl_entries += [ - # stock in hand account - self.get_gl_dict({ - "account": stock_in_hand_account, - "against": against_stock_account, - "debit": value_diff, + # to target warehouse / expense account + gl_list.append(self.get_gl_dict({ + "account": detail.expense_account, + "against": warehouse_account[sle.warehouse], + "cost_center": detail.cost_center, "remarks": self.doc.remarks or "Accounting Entry for Stock", - }), - - # account against stock in hand - self.get_gl_dict({ - "account": against_stock_account, - "against": stock_in_hand_account, - "credit": value_diff, - "cost_center": cost_center != "No Cost Center" and cost_center or None, - "remarks": self.doc.remarks or "Accounting Entry for Stock", - }), - ] - gl_entries = process_gl_map(gl_entries) - return gl_entries + "credit": sle.stock_value_difference + })) + return process_gl_map(gl_list) - def get_stock_value_diff_from_sle(self, item_acc_map, expense_account, cost_center): - wh_acc_map = self.get_warehouse_account_map() - stock_value_diff = {} + def get_voucher_details(self, stock_ledger, default_expense_account, default_cost_center): + if not default_expense_account: + details = self.doclist.get({"parentfield": self.fname}) + for d in details: + self.check_expense_account(d) + else: + details = [webnotes._dict({ + "name":d, + "expense_account": default_expense_account, + "cost_center": default_cost_center + }) for d in stock_ledger.keys()] + + return details + + def get_stock_ledger_details(self): + stock_ledger = {} for sle in webnotes.conn.sql("""select warehouse, stock_value_difference, voucher_detail_no from `tabStock Ledger Entry` where voucher_type=%s and voucher_no=%s""", (self.doc.doctype, self.doc.name), as_dict=True): - account = wh_acc_map[sle.warehouse] - against_account = expense_account or item_acc_map[sle.voucher_detail_no][0] - cost_center = cost_center or item_acc_map[sle.voucher_detail_no][1] or \ - "No Cost Center" - - stock_value_diff.setdefault(account, {}).setdefault(against_account, {})\ - .setdefault(cost_center, 0) - stock_value_diff[account][against_account][cost_center] += \ - flt(sle.stock_value_difference) - - return stock_value_diff + stock_ledger.setdefault(sle.voucher_detail_no, []).append(sle) + return stock_ledger - def get_warehouse_account_map(self): - wh_acc_map = {} - warehouse_with_no_account = [] - for d in webnotes.conn.sql("""select name, account from `tabWarehouse`""", as_dict=True): - if not d.account: warehouse_with_no_account.append(d.name) - wh_acc_map.setdefault(d.name, d.account) - - if warehouse_with_no_account: - webnotes.throw(_("Please mention Perpetual Account in warehouse master for \ - following warehouses") + ": " + '\n'.join(warehouse_with_no_account)) + def get_warehouse_account(self): + warehouse_account = dict(webnotes.conn.sql("""select name, account from `tabWarehouse` + where ifnull(account, '') != ''""")) - return wh_acc_map + return warehouse_account def update_gl_entries_after(self): + from accounts.utils import get_stock_and_account_difference future_stock_vouchers = self.get_future_stock_vouchers() gle = self.get_voucherwise_gl_entries(future_stock_vouchers) for voucher_type, voucher_no in future_stock_vouchers: - existing_gle = gle.get((voucher_type, voucher_no), {}) - voucher_bean = webnotes.bean(voucher_type, voucher_no) - expected_gle = voucher_bean.run_method("get_gl_entries_for_stock") + existing_gle = gle.get((voucher_type, voucher_no), []) + voucher_obj = webnotes.get_obj(voucher_type, voucher_no) + expected_gle = voucher_obj.get_gl_entries_for_stock() + if expected_gle: + matched = True if existing_gle: - matched = True for entry in expected_gle: - entry_amount = existing_gle.get(entry.account, {}).get(entry.cost_center \ - or "No Cost Center", [0, 0]) - - if [entry.debit, entry.credit] != entry_amount: - matched = False - break - - if not matched: - # make updated entry - webnotes.conn.sql("""delete from `tabGL Entry` - where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no)) - - voucher_bean.run_method("make_gl_entries") + for e in existing_gle: + if entry.account==e.account \ + and entry.against_account==e.against_account\ + and entry.cost_center==e.cost_center: + if entry.debit != e.debit or entry.credit != e.credit: + matched = False + break else: - # make adjustment entry on that date - self.make_adjustment_entry(expected_gle, voucher_bean) + matched = False + + if not matched: + self.delete_gl_entries(voucher_type, voucher_no) + make_gl_entries(expected_gle) + else: + self.delete_gl_entries(voucher_type, voucher_no) + + # else: + # # make adjustment entry on that date + # self.make_adjustment_entry(expected_gle, voucher_obj) def get_future_stock_vouchers(self): future_stock_vouchers = [] - for d in webnotes.conn.sql("""select distinct voucher_type, voucher_no - from `tabStock Ledger Entry` - where timestamp(posting_date, posting_time) >= timestamp(%s, %s) - order by timestamp(posting_date, posting_time) asc, name asc""", + item_codes = webnotes.conn.sql_list("""select distinct item_code + from `tabStock Ledger Entry` + where voucher_type=%s and voucher_no=%s""", (self.doc.doctype, self.doc.name)) + + for d in webnotes.conn.sql("""select distinct sle.voucher_type, sle.voucher_no + from `tabStock Ledger Entry` sle + where timestamp(sle.posting_date, sle.posting_time) >= timestamp(%s, %s) + order by timestamp(sle.posting_date, sle.posting_time) asc, name asc""", (self.doc.posting_date, self.doc.posting_time), as_dict=True): future_stock_vouchers.append([d.voucher_type, d.voucher_no]) - + return future_stock_vouchers def get_voucherwise_gl_entries(self, future_stock_vouchers): @@ -141,13 +141,15 @@ class StockController(AccountsController): where posting_date >= %s and voucher_no in (%s)""" % ('%s', ', '.join(['%s']*len(future_stock_vouchers))), tuple([self.doc.posting_date] + [d[1] for d in future_stock_vouchers]), as_dict=1): - gl_entries.setdefault((d.voucher_type, d.voucher_no), {})\ - .setdefault(d.account, {})\ - .setdefault(d.cost_center, [d.debit, d.credit]) + gl_entries.setdefault((d.voucher_type, d.voucher_no), []).append(d) return gl_entries + + def delete_gl_entries(self, voucher_type, voucher_no): + webnotes.conn.sql("""delete from `tabGL Entry` + where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no)) - def make_adjustment_entry(self, expected_gle, voucher_bean): + def make_adjustment_entry(self, expected_gle, voucher_obj): from accounts.utils import get_stock_and_account_difference account_list = [d.account for d in expected_gle] acc_diff = get_stock_and_account_difference(account_list, expected_gle[0].posting_date) @@ -160,7 +162,7 @@ class StockController(AccountsController): if diff: gl_entries.append([ # stock in hand account - voucher_bean.get_gl_dict({ + voucher_obj.get_gl_dict({ "account": account, "against": stock_adjustment_account, "debit": diff, @@ -168,7 +170,7 @@ class StockController(AccountsController): }), # account against stock in hand - voucher_bean.get_gl_dict({ + voucher_obj.get_gl_dict({ "account": stock_adjustment_account, "against": account, "credit": diff, diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py index 8c0d5f962f..b07ba5a379 100644 --- a/stock/doctype/delivery_note/delivery_note.py +++ b/stock/doctype/delivery_note/delivery_note.py @@ -123,7 +123,6 @@ class DocType(SellingController): } }) - def validate_proj_cust(self): """check for does customer belong to same project as entered..""" if self.doc.project_name and self.doc.customer: diff --git a/stock/doctype/delivery_note/test_delivery_note.py b/stock/doctype/delivery_note/test_delivery_note.py index 31ea202027..43378a1654 100644 --- a/stock/doctype/delivery_note/test_delivery_note.py +++ b/stock/doctype/delivery_note/test_delivery_note.py @@ -7,13 +7,13 @@ import unittest import webnotes import webnotes.defaults from webnotes.utils import cint -from accounts.utils import get_stock_and_account_difference +from stock.doctype.purchase_receipt.test_purchase_receipt import get_gl_entries, test_records as pr_test_records class TestDeliveryNote(unittest.TestCase): - def _insert_purchase_receipt(self): - from stock.doctype.purchase_receipt.test_purchase_receipt import test_records as pr_test_records + def _insert_purchase_receipt(self, item_code=None): pr = webnotes.bean(copy=pr_test_records[0]) - pr.run_method("calculate_taxes_and_totals") + if item_code: + pr.doclist[1].item_code = item_code pr.insert() pr.submit() @@ -61,13 +61,14 @@ class TestDeliveryNote(unittest.TestCase): from `tabGL Entry` where voucher_type='Delivery Note' and voucher_no=%s order by account desc""", dn.doc.name, as_dict=1) - self.assertTrue(not gl_entries) + self.assertFalse(get_gl_entries("Delivery Note", dn.doc.name)) def test_delivery_note_gl_entry(self): self.clear_stock_account_balance() webnotes.defaults.set_global_default("perpetual_accounting", 1) self.assertEqual(cint(webnotes.defaults.get_global_default("perpetual_accounting")), 1) + webnotes.conn.set_value("Item", "_Test Item", "valuation_method", "FIFO") self._insert_purchase_receipt() @@ -84,25 +85,78 @@ class TestDeliveryNote(unittest.TestCase): dn.insert() dn.submit() - - gl_entries = webnotes.conn.sql("""select account, debit, credit - from `tabGL Entry` where voucher_type='Delivery Note' and voucher_no=%s - order by account asc""", dn.doc.name, as_dict=1) + gl_entries = get_gl_entries("Delivery Note", dn.doc.name) self.assertTrue(gl_entries) - - expected_values = sorted([ - [stock_in_hand_account, 0.0, 375.0], - ["Cost of Goods Sold - _TC", 375.0, 0.0] - ]) + expected_values = { + stock_in_hand_account: [0.0, 375.0], + "Cost of Goods Sold - _TC": [375.0, 0.0] + } for i, gle in enumerate(gl_entries): - self.assertEquals(expected_values[i][0], gle.account) - self.assertEquals(expected_values[i][1], gle.debit) - self.assertEquals(expected_values[i][2], gle.credit) - + self.assertEquals([gle.debit, gle.credit], expected_values.get(gle.account)) + # check stock in hand balance bal = get_balance_on(stock_in_hand_account, dn.doc.posting_date) self.assertEquals(bal, prev_bal - 375.0) - self.assertFalse(get_stock_and_account_difference([dn.doclist[1].warehouse])) + + # back dated purchase receipt + pr = webnotes.bean(copy=pr_test_records[0]) + pr.doc.posting_date = "2013-01-01" + pr.doclist[1].import_rate = 100 + pr.doclist[1].amount = 100 + + pr.insert() + pr.submit() + + gl_entries = get_gl_entries("Delivery Note", dn.doc.name) + self.assertTrue(gl_entries) + expected_values = { + stock_in_hand_account: [0.0, 666.65], + "Cost of Goods Sold - _TC": [666.65, 0.0] + } + for i, gle in enumerate(gl_entries): + self.assertEquals([gle.debit, gle.credit], expected_values.get(gle.account)) + + dn.cancel() + self.assertFalse(get_gl_entries("Delivery Note", dn.doc.name)) + + webnotes.defaults.set_global_default("perpetual_accounting", 0) + + def test_delivery_note_gl_entry_packing_item(self): + self.clear_stock_account_balance() + webnotes.defaults.set_global_default("perpetual_accounting", 1) + + self._insert_purchase_receipt() + self._insert_purchase_receipt("_Test Item Home Desktop 100") + + dn = webnotes.bean(copy=test_records[0]) + dn.doclist[1].item_code = "_Test Sales BOM Item" + dn.doclist[1].qty = 1 + + stock_in_hand_account = webnotes.conn.get_value("Warehouse", dn.doclist[1].warehouse, + "account") + + from accounts.utils import get_balance_on + prev_bal = get_balance_on(stock_in_hand_account, dn.doc.posting_date) + + dn.insert() + dn.submit() + + gl_entries = get_gl_entries("Delivery Note", dn.doc.name) + self.assertTrue(gl_entries) + + expected_values = { + stock_in_hand_account: [0.0, 525], + "Cost of Goods Sold - _TC": [525.0, 0.0] + } + for i, gle in enumerate(gl_entries): + self.assertEquals([gle.debit, gle.credit], expected_values.get(gle.account)) + + # check stock in hand balance + bal = get_balance_on(stock_in_hand_account, dn.doc.posting_date) + self.assertEquals(bal, prev_bal - 525.0) + + dn.cancel() + self.assertFalse(get_gl_entries("Delivery Note", dn.doc.name)) webnotes.defaults.set_global_default("perpetual_accounting", 0) @@ -163,6 +217,8 @@ class TestDeliveryNote(unittest.TestCase): webnotes.conn.sql("delete from `tabStock Ledger Entry`") webnotes.conn.sql("delete from `tabGL Entry`") +test_dependencies = ["Sales BOM"] + test_records = [ [ { @@ -196,8 +252,10 @@ test_records = [ "export_rate": 100.0, "amount": 500.0, "warehouse": "_Test Warehouse - _TC", - "stock_uom": "_Test UOM" + "stock_uom": "_Test UOM", + "expense_account": "Cost of Goods Sold - _TC", + "cost_center": "Main - _TC" } ] -] \ No newline at end of file +] diff --git a/stock/doctype/purchase_receipt/purchase_receipt.py b/stock/doctype/purchase_receipt/purchase_receipt.py index aaf40141d9..9f077994c7 100644 --- a/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/stock/doctype/purchase_receipt/purchase_receipt.py @@ -302,11 +302,8 @@ class DocType(BuyingController): def get_gl_entries_for_stock(self): against_stock_account = self.get_company_default("stock_received_but_not_billed") - item_acc_map = {} - for item in self.doclist.get({"parentfield": "purchase_receipt_details"}): - item_acc_map.setdefault(item.name, [against_stock_account, None]) - - gl_entries = super(DocType, self).get_gl_entries_for_stock(item_acc_map) + + gl_entries = super(DocType, self).get_gl_entries_for_stock(against_stock_account, None) return gl_entries diff --git a/stock/doctype/purchase_receipt/test_purchase_receipt.py b/stock/doctype/purchase_receipt/test_purchase_receipt.py index 0ba5470e6e..a0c72d985e 100644 --- a/stock/doctype/purchase_receipt/test_purchase_receipt.py +++ b/stock/doctype/purchase_receipt/test_purchase_receipt.py @@ -50,11 +50,7 @@ class TestPurchaseReceipt(unittest.TestCase): "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) - - self.assertTrue(not gl_entries) + self.assertFalse(get_gl_entries("Purchase Receipt", pr.doc.name)) def test_purchase_receipt_gl_entry(self): webnotes.defaults.set_global_default("perpetual_accounting", 1) @@ -66,14 +62,12 @@ class TestPurchaseReceipt(unittest.TestCase): pr.insert() pr.submit() - 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) + gl_entries = get_gl_entries("Purchase Receipt", pr.doc.name) + self.assertTrue(gl_entries) stock_in_hand_account = webnotes.conn.get_value("Warehouse", pr.doclist[1].warehouse, - "account") - + "account") fixed_asset_account = webnotes.conn.get_value("Warehouse", pr.doclist[2].warehouse, "account") @@ -87,9 +81,9 @@ class TestPurchaseReceipt(unittest.TestCase): self.assertEquals(expected_values[gle.account][0], gle.debit) self.assertEquals(expected_values[gle.account][1], gle.credit) - self.assertFalse(get_stock_and_account_difference([pr.doclist[1].warehouse, - pr.doclist[2].warehouse])) - + pr.cancel() + self.assertFalse(get_gl_entries("Purchase Receipt", pr.doc.name)) + webnotes.defaults.set_global_default("perpetual_accounting", 0) def _clear_stock_account_balance(self): @@ -126,6 +120,11 @@ class TestPurchaseReceipt(unittest.TestCase): self.assertEqual(webnotes.conn.get_value("Serial No", pr.doclist[1].serial_no, "status"), "Not Available") + +def get_gl_entries(voucher_type, voucher_no): + return webnotes.conn.sql("""select account, debit, credit + from `tabGL Entry` where voucher_type=%s and voucher_no=%s + order by account desc""", (voucher_type, voucher_no), as_dict=1) diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index c134951216..a692db5926 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -320,7 +320,7 @@ class DocType(StockController): sl_entries.append(self.get_sl_entries(d, { "warehouse": cstr(d.s_warehouse), "actual_qty": -flt(d.transfer_qty), - "incoming_rate": flt(d.incoming_rate) + "incoming_rate": 0 })) if cstr(d.t_warehouse): diff --git a/stock/doctype/stock_reconciliation/stock_reconciliation.py b/stock/doctype/stock_reconciliation/stock_reconciliation.py index f78b8e0754..6b2855a7c2 100644 --- a/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -298,8 +298,8 @@ class DocType(StockController): if not self.doc.cost_center: msgprint(_("Please enter Cost Center"), raise_exception=1) - super(DocType, self).get_gl_entries_for_stock(expense_account=self.doc.expense_account, - cost_center=self.doc.cost_center) + return super(DocType, self).get_gl_entries_for_stock(self.doc.expense_account, + self.doc.cost_center) def validate_expense_account(self): diff --git a/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/stock/doctype/stock_reconciliation/test_stock_reconciliation.py index 7de5c54346..df9e2291e8 100644 --- a/stock/doctype/stock_reconciliation/test_stock_reconciliation.py +++ b/stock/doctype/stock_reconciliation/test_stock_reconciliation.py @@ -12,7 +12,7 @@ from accounts.utils import get_fiscal_year, get_stock_and_account_difference, ge class TestStockReconciliation(unittest.TestCase): - def atest_reco_for_fifo(self): + def test_reco_for_fifo(self): webnotes.defaults.set_global_default("perpetual_accounting", 0) # [[qty, valuation_rate, posting_date, # posting_time, expected_stock_value, bin_qty, bin_valuation]] @@ -90,7 +90,6 @@ class TestStockReconciliation(unittest.TestCase): self.assertEqual(res and flt(res[0][0], 4) or 0, d[4]) # bin qty and stock value - print "bin" bin = webnotes.conn.sql("""select actual_qty, stock_value from `tabBin` where item_code = '_Test Item' and warehouse = '_Test Warehouse - _TC'""") @@ -103,7 +102,7 @@ class TestStockReconciliation(unittest.TestCase): stock_reco.doc.name) self.assertFalse(gl_entries) - def atest_reco_fifo_gl_entries(self): + def test_reco_fifo_gl_entries(self): webnotes.defaults.set_global_default("perpetual_accounting", 1) # [[qty, valuation_rate, posting_date, posting_time, stock_in_hand_debit]] @@ -120,23 +119,23 @@ class TestStockReconciliation(unittest.TestCase): [50, 1000, "2013-01-01", "12:00"], [5, 1000, "2013-01-01", "12:00"], [1, 1000, "2012-12-01", "00:00"], - ] for d in input_data: - # print d[0], d[1], d[2], d[3] self.cleanup_data() self.insert_existing_sle("FIFO") + self.assertFalse(get_stock_and_account_difference(["_Test Account Stock In Hand - _TC"])) stock_reco = self.submit_stock_reconciliation(d[0], d[1], d[2], d[3]) - self.assertFalse(get_stock_and_account_difference(["_Test Warehouse - _TC"])) - # cancel - stock_reco.cancel() - self.assertFalse(get_stock_and_account_difference(["_Test Warehouse - _TC"])) - - webnotes.defaults.set_global_default("perpetual_accounting", 0) - def atest_reco_moving_average_gl_entries(self): + self.assertFalse(get_stock_and_account_difference(["_Test Account Stock In Hand - _TC"])) + + stock_reco.cancel() + self.assertFalse(get_stock_and_account_difference(["_Test Account Stock In Hand - _TC"])) + + webnotes.defaults.set_global_default("perpetual_accounting", 0) + + def test_reco_moving_average_gl_entries(self): webnotes.defaults.set_global_default("perpetual_accounting", 1) # [[qty, valuation_rate, posting_date, @@ -259,6 +258,7 @@ class TestStockReconciliation(unittest.TestCase): pr3.insert() pr3.submit() + pr4 = webnotes.bean(copy=stock_entry) pr4.doc.posting_date = "2013-01-05" pr4.doc.fiscal_year = "_Test Fiscal Year 2013"