Merge branch 'master' of github.com:webnotes/erpnext into sales_purchase_return

Conflicts:
	patches/patch_list.py
diff --git a/accounts/doctype/pos_setting/test_pos_setting.py b/accounts/doctype/pos_setting/test_pos_setting.py
new file mode 100644
index 0000000..2c45c4d
--- /dev/null
+++ b/accounts/doctype/pos_setting/test_pos_setting.py
@@ -0,0 +1,14 @@
+test_records = [
+	[{
+		"doctype": "POS Setting",
+		"name": "_Test POS Setting",
+		"currency": "INR",
+		"conversion_rate": 1.0,
+		"price_list_name": "_Test Price List",
+		"company": "_Test Company",
+		"warehouse": "_Test Warehouse",
+		"cash_bank_account": "_Test Account Bank Account - _TC",
+		"income_account": "Sales - _TC",
+		"cost_center": "_Test Cost Center - _TC",
+	}]
+]
\ No newline at end of file
diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py
index de3ee95..0271a58 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/accounts/doctype/sales_invoice/sales_invoice.py
@@ -47,6 +47,7 @@
 	def validate(self):
 		super(DocType, self).validate()
 		
+		self.validate_posting_time()
 		self.so_dn_required()
 		self.validate_proj_cust()
 		sales_com_obj = get_obj('Sales Common')
@@ -636,10 +637,9 @@
 
 				# Reduce actual qty from warehouse
 				self.make_sl_entry( d, d['warehouse'], - flt(d['qty']) , 0, update_stock)
-				
+		
 		get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values)
-	
-
+		
 	def get_actual_qty(self,args):
 		args = eval(args)
 		actual_qty = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1)
diff --git a/accounts/doctype/sales_invoice/sales_invoice.txt b/accounts/doctype/sales_invoice/sales_invoice.txt
index c7c8fba..35710b4 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.txt
+++ b/accounts/doctype/sales_invoice/sales_invoice.txt
@@ -1,8 +1,8 @@
 [
  {
-  "creation": "2013-01-29 17:54:09", 
+  "creation": "2013-03-12 11:56:25", 
   "docstatus": 0, 
-  "modified": "2013-01-29 18:22:52", 
+  "modified": "2013-03-12 14:31:24", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -77,7 +77,6 @@
   "print_hide": 1
  }, 
  {
-  "default": "1", 
   "depends_on": "eval:doc.is_pos==1", 
   "doctype": "DocField", 
   "fieldname": "update_stock", 
diff --git a/accounts/doctype/sales_invoice/test_sales_invoice.py b/accounts/doctype/sales_invoice/test_sales_invoice.py
index 84eddea..91c0622 100644
--- a/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -297,7 +297,7 @@
 		])
 		ps.insert()
 		
-test_dependencies = ["Journal Voucher"]
+test_dependencies = ["Journal Voucher", "POS Setting"]
 
 test_records = [
 	[
diff --git a/patches/march_2013/p04_pos_update_stock_check.py b/patches/march_2013/p04_pos_update_stock_check.py
new file mode 100644
index 0000000..da48efe
--- /dev/null
+++ b/patches/march_2013/p04_pos_update_stock_check.py
@@ -0,0 +1,18 @@
+import webnotes
+
+def execute():
+	from webnotes.utils import cint
+	webnotes.reload_doc("setup", "doctype", "global_defaults")
+	
+	doctype_list = webnotes.get_doctype("Sales Invoice")
+	update_stock_df = doctype_list.get_field("update_stock")
+	
+	global_defaults = webnotes.bean("Global Defaults", "Global Defaults")
+	global_defaults.doc.update_stock = cint(update_stock_df.default)
+	global_defaults.save()
+
+	webnotes.conn.sql("""delete from `tabProperty Setter`
+		where doc_type='Sales Invoice' and doctype_or_field='DocField'
+		and field_name='update_stock' and property='default'""")
+		
+	webnotes.reload_doc("accounts", "doctype", "sales_invoice")
\ No newline at end of file
diff --git a/patches/patch_list.py b/patches/patch_list.py
index f5e3f40..1120848 100644
--- a/patches/patch_list.py
+++ b/patches/patch_list.py
@@ -211,5 +211,6 @@
 	"patches.march_2013.p02_get_global_default",
 	"patches.march_2013.p03_rename_blog_to_blog_post",
 	"execute:webnotes.reload_doc('hr', 'search_criteria', 'monthly_attendance_details')",
+	"patches.march_2013.p04_pos_update_stock_check",
 	"patches.march_2013.p05_payment_reconciliation",
 ]
\ No newline at end of file
diff --git a/setup/doctype/global_defaults/global_defaults.txt b/setup/doctype/global_defaults/global_defaults.txt
index 960da7e..a55c6c0 100644
--- a/setup/doctype/global_defaults/global_defaults.txt
+++ b/setup/doctype/global_defaults/global_defaults.txt
@@ -1,8 +1,8 @@
 [
  {
-  "creation": "2013-02-19 12:28:27", 
+  "creation": "2013-03-08 15:37:09", 
   "docstatus": 0, 
-  "modified": "2013-02-20 14:09:00", 
+  "modified": "2013-03-12 18:48:53", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -250,6 +250,13 @@
   "fieldtype": "Column Break"
  }, 
  {
+  "description": "If checked, then in POS Sales Invoice, Update Stock gets checked by default", 
+  "doctype": "DocField", 
+  "fieldname": "update_stock", 
+  "fieldtype": "Check", 
+  "label": "Update Stock when using POS Sales Invoice"
+ }, 
+ {
   "doctype": "DocField", 
   "fieldname": "account_info", 
   "fieldtype": "HTML", 
diff --git a/stock/doctype/bin/bin.py b/stock/doctype/bin/bin.py
index 37ecf85..e1bc6bd 100644
--- a/stock/doctype/bin/bin.py
+++ b/stock/doctype/bin/bin.py
@@ -70,7 +70,7 @@
 				"posting_date": args.get("posting_date"),
 				"posting_time": args.get("posting_time")
 			})
-					
+			
 	def update_qty(self, args):
 		# update the stock values (for current quantities)
 		self.doc.actual_qty = flt(self.doc.actual_qty) + flt(args.get("actual_qty"))
@@ -83,11 +83,11 @@
 		 	flt(self.doc.indented_qty) + flt(self.doc.planned_qty) - flt(self.doc.reserved_qty)
 		
 		self.doc.save()
-				
+		
 		if (flt(args.get("actual_qty")) < 0 or flt(args.get("reserved_qty")) > 0) \
 				and args.get("is_cancelled") == 'No' and args.get("is_amended")=='No':
 			self.reorder_item(args.get("voucher_type"), args.get("voucher_no"))
-			
+		
 	def get_first_sle(self):
 		sle = sql("""
 			select * from `tabStock Ledger Entry`
diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py
index 229ec40..46c6ee4 100644
--- a/stock/doctype/delivery_note/delivery_note.py
+++ b/stock/doctype/delivery_note/delivery_note.py
@@ -133,7 +133,7 @@
 		super(DocType, self).validate()
 		
 		import utilities
-		utilities.validate_status(self.doc.status, ["Draft", "submitted", "Cancelled"])
+		utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Cancelled"])
 
 		self.so_required()
 		self.validate_fiscal_year()
diff --git a/stock/doctype/stock_entry/stock_entry.js b/stock/doctype/stock_entry/stock_entry.js
index ba1f648..0b27d99 100644
--- a/stock/doctype/stock_entry/stock_entry.js
+++ b/stock/doctype/stock_entry/stock_entry.js
@@ -18,6 +18,39 @@
 wn.provide("erpnext.stock");
 
 erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
+	setup: function() {
+		var me = this;
+		
+		this.frm.fields_dict.delivery_note_no.get_query = function() {
+			return { query: "stock.doctype.stock_entry.stock_entry.query_sales_return_doc" };
+		};
+		
+		this.frm.fields_dict.sales_invoice_no.get_query = 
+			this.frm.fields_dict.delivery_note_no.get_query;
+		
+		this.frm.fields_dict.purchase_receipt_no.get_query = function() {
+			return { query: "stock.doctype.stock_entry.stock_entry.query_purchase_return_doc" };
+		};
+		
+		this.frm.fields_dict.mtn_details.grid.get_field('item_code').get_query = function() {
+			if(in_list(["Sales Return", "Purchase Return"], me.frm.doc.purpose) && 
+				me.get_doctype_docname()) {
+					return {
+						query: "stock.doctype.stock_entry.stock_entry.query_return_item",
+						filters: {
+							purpose: me.frm.doc.purpose,
+							delivery_note_no: me.frm.doc.delivery_note_no,
+							sales_invoice_no: me.frm.doc.sales_invoice_no,
+							purchase_receipt_no: me.frm.doc.purchase_receipt_no
+						}
+					};
+			} else {
+				return erpnext.queries.item({is_stock_item: "Yes"});
+			}
+		};
+		
+	},
+	
 	onload_post_render: function() {
 		if(this.frm.doc.__islocal && (this.frm.doc.production_order || this.frm.doc.bom_no) 
 			&& !getchildren('Stock Entry Detail', this.frm.doc.name, 'mtn_details').length) {
@@ -27,12 +60,25 @@
 	},
 	
 	refresh: function() {
+		var me = this;
 		erpnext.hide_naming_series();
 		this.toggle_related_fields(this.frm.doc);
 		this.toggle_enable_bom();
 		if (this.frm.doc.docstatus==1) {
 			this.show_stock_ledger();
 		}
+		
+		if(this.frm.doc.docstatus === 1 && 
+				wn.boot.profile.can_create.indexOf("Journal Voucher")!==-1) {
+			if(this.frm.doc.purpose === "Sales Return") {
+				this.frm.add_custom_button("Make Credit Note", function() { me.make_return_jv(); });
+				this.add_excise_button();
+			} else if(this.frm.doc.purpose === "Purchase Return") {
+				this.frm.add_custom_button("Make Debit Note", function() { me.make_return_jv(); });
+				this.add_excise_button();
+			}
+		}
+		
 	},
 	
 	on_submit: function() {
@@ -80,6 +126,68 @@
 	toggle_enable_bom: function() {
 		this.frm.toggle_enable("bom_no", !this.frm.doc.production_order);
 	},
+	
+	get_doctype_docname: function() {
+		if(this.frm.doc.purpose === "Sales Return") {
+			if(this.frm.doc.delivery_note_no && this.frm.doc.sales_invoice_no) {
+				// both specified
+				msgprint(wn._("You can not enter both Delivery Note No and Sales Invoice No. \
+					Please enter any one."));
+				
+			} else if(!(this.frm.doc.delivery_note_no || this.frm.doc.sales_invoice_no)) {
+				// none specified
+				msgprint(wn._("Please enter Delivery Note No or Sales Invoice No to proceed"));
+				
+			} else if(this.frm.doc.delivery_note_no) {
+				return {doctype: "Delivery Note", docname: this.frm.doc.delivery_note_no};
+				
+			} else if(this.frm.doc.sales_invoice_no) {
+				return {doctype: "Sales Invoice", docname: this.frm.doc.sales_invoice_no};
+				
+			}
+		} else if(this.frm.doc.purpose === "Purchase Return") {
+			if(this.frm.doc.purchase_receipt_no) {
+				return {doctype: "Purchase Receipt", docname: this.frm.doc.purchase_receipt_no};
+				
+			} else {
+				// not specified
+				msgprint(wn._("Please enter Purchase Receipt No to proceed"));
+				
+			}
+		}
+	},
+	
+	add_excise_button: function() {
+		if(wn.boot.control_panel.country === "India")
+			this.frm.add_custom_button("Make Excise Invoice", function() {
+				var excise = wn.model.make_new_doc_and_get_name('Journal Voucher');
+				excise = locals['Journal Voucher'][excise];
+				excise.voucher_type = 'Excise Voucher';
+				loaddoc('Journal Voucher', excise.name);
+			});
+	},
+	
+	make_return_jv: function() {
+		this.frm.call({
+			method: "make_return_jv",
+			args: {
+				stock_entry: this.frm.doc.name
+			},
+			callback: function(r) {
+				if(!r.exc) {
+					var jv_name = wn.model.make_new_doc_and_get_name('Journal Voucher');
+					var jv = locals["Journal Voucher"][jv_name];
+					$.extend(jv, r.message[0]);
+					$.each(r.message.slice(1), function(i, jvd) {
+						var child = wn.model.add_child(jv, "Journal Voucher Detail", "entries");
+						$.extend(child, jvd);
+					});
+					loaddoc("Journal Voucher", jv_name);
+				}
+				
+			}
+		});
+	},
 
 });
 
@@ -140,15 +248,6 @@
 	cur_frm.cscript.toggle_related_fields(doc, cdt, cdn);
 }
 
-// item code - only if quantity present in source warehosue
-var fld = cur_frm.fields_dict['mtn_details'].grid.get_field('item_code');
-fld.query_description = "If Source Warehouse is selected, items with existing stock \
-	for that warehouse will be selected";
-
-fld.get_query = function() {
-	return erpnext.queries.item({is_stock_item: "Yes"});
-}
-
 // copy over source and target warehouses
 cur_frm.fields_dict['mtn_details'].grid.onrowadd = function(doc, cdt, cdn){
 	var d = locals[cdt][cdn];
diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py
index cd20266..131e9ff 100644
--- a/stock/doctype/stock_entry/stock_entry.py
+++ b/stock/doctype/stock_entry/stock_entry.py
@@ -26,8 +26,10 @@
 from stock.stock_ledger import get_previous_sle
 import json
 
-
 sql = webnotes.conn.sql
+
+class NotUpdateStockError(webnotes.ValidationError): pass
+class StockOverReturnError(webnotes.ValidationError): pass
 	
 from controllers.accounts_controller import AccountsController
 
@@ -38,6 +40,7 @@
 		self.fname = 'mtn_details' 
 		
 	def validate(self):
+		self.validate_posting_time()
 		self.validate_purpose()
 		self.validate_serial_nos()
 		pro_obj = self.doc.production_order and \
@@ -275,26 +278,55 @@
 						or update the Quantity manually."), raise_exception=1)
 						
 	def validate_return_reference_doc(self):
-		""" validate item with reference doc"""
-		ref_doctype = ref_docname = ""
-		if self.doc.purpose == "Sales Return" and \
-				(self.doc.delivery_note_no or self.doc.sales_invoice_no):
-			ref_doctype = self.doc.delivery_note_no and "Delivery Note" or "Sales Invoice"
-			ref_docname = self.doc.delivery_note_no or self.doc.sales_invoice_no
-		elif self.doc.purpose == "Purchase Return" and self.doc.purchase_receipt_no:
-			ref_doctype = "Purchase Receipt"
-			ref_docname = self.doc.purchase_receipt_no
+		"""validate item with reference doc"""
+		ref = get_return_reference_details(self.doc.fields)
+		
+		if ref.doclist:
+			# validate docstatus
+			if ref.doclist[0].docstatus != 1:
+				webnotes.msgprint(_(ref.doclist[0].doctype) + ' "' + ref.doclist[0].name + '": ' 
+					+ _("Status should be Submitted"), raise_exception=webnotes.InvalidStatusError)
 			
-		if ref_doctype and ref_docname:
+			# update stock check
+			if ref.doclist[0].doctype == "Sales Invoice" and (cint(ref.doclist[0].is_pos) != 1 \
+				or cint(ref.doclist[0].update_stock) != 1):
+					webnotes.msgprint(_(ref.doclist[0].doctype) + ' "' + ref.doclist[0].name + '": ' 
+						+ _("Is POS and Update Stock should be checked."), 
+						raise_exception=NotUpdateStockError)
+			
+			# posting date check
+			ref_posting_datetime = "%s %s" % (cstr(ref.doclist[0].posting_date), 
+				cstr(ref.doclist[0].posting_time) or "00:00:00")
+			this_posting_datetime = "%s %s" % (cstr(self.doc.posting_date), 
+				cstr(self.doc.posting_time))
+			if this_posting_datetime < ref_posting_datetime:
+				from webnotes.utils.dateutils import datetime_in_user_format
+				webnotes.msgprint(_("Posting Date Time cannot be before")
+					+ ": " + datetime_in_user_format(ref_posting_datetime),
+					raise_exception=True)
+			
+			stock_items = get_stock_items_for_return(ref.doclist, ref.parentfields)
+			already_returned_item_qty = self.get_already_returned_item_qty(ref.fieldname)
+			
 			for item in self.doclist.get({"parentfield": "mtn_details"}):
-				ref_exists = webnotes.conn.sql("""select name from `tab%s` 
-					where parent = %s and item_code = %s and docstatus=1""" % 
-					(ref_doctype + " Item", '%s', '%s'), (ref_docname, item.item_code))
-					
-				if not ref_exists:
-					msgprint(_("Item: '") + item.item_code + _("' does not exists in ") +
-						ref_doctype + ": " + ref_docname, raise_exception=1)
-			
+				# validate if item exists in the ref doclist and that it is a stock item
+				if item.item_code not in stock_items:
+					msgprint(_("Item") + ': "' + item.item_code + _("\" does not exist in ") +
+						ref.doclist[0].doctype + ": " + ref.doclist[0].name, 
+						raise_exception=webnotes.DoesNotExistError)
+				
+				# validate quantity <= ref item's qty - qty already returned
+				ref_item = ref.doclist.getone({"item_code": item.item_code})
+				returnable_qty = ref_item.qty - flt(already_returned_item_qty.get(item.item_code))
+				self.validate_value("transfer_qty", "<=", returnable_qty, item,
+					raise_exception=StockOverReturnError)
+				
+	def get_already_returned_item_qty(self, ref_fieldname):
+		return dict(webnotes.conn.sql("""select item_code, sum(transfer_qty) as qty
+			from `tabStock Entry Detail` where parent in (
+				select name from `tabStock Entry` where `%s`=%s and docstatus=1)
+			group by item_code""" % (ref_fieldname, "%s"), (self.doc.fields.get(ref_fieldname),)))
+		
 	def update_serial_no(self, is_submit):
 		"""Create / Update Serial No"""
 		from stock.utils import get_valid_serial_nos
@@ -326,6 +358,7 @@
 				self.add_to_values(d, cstr(d.s_warehouse), -flt(d.transfer_qty), is_cancelled)
 			if cstr(d.t_warehouse):
 				self.add_to_values(d, cstr(d.t_warehouse), flt(d.transfer_qty), is_cancelled)
+		
 		get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values, 
 			self.doc.amended_from and 'Yes' or 'No')
 
@@ -639,10 +672,306 @@
 						+ " " + _("Row #") + (" %d %s " % (mreq_item.idx, _("of")))
 						+ _("Material Request") + (" - %s" % item.material_request), 
 						raise_exception=webnotes.MappingMismatchError)
-
+	
 @webnotes.whitelist()
 def get_production_order_details(production_order):
 	result = webnotes.conn.sql("""select bom_no, 
 		ifnull(qty, 0) - ifnull(produced_qty, 0) as fg_completed_qty, use_multi_level_bom
 		from `tabProduction Order` where name = %s""", production_order, as_dict=1)
-	return result and result[0] or {}
\ No newline at end of file
+	return result and result[0] or {}
+	
+def query_sales_return_doc(doctype, txt, searchfield, start, page_len, filters):
+	conditions = ""
+	if doctype == "Sales Invoice":
+		conditions = "and is_pos=1 and update_stock=1"
+	
+	return webnotes.conn.sql("""select name, customer, customer_name
+		from `tab%s` where docstatus = 1
+		and (`%s` like %%(txt)s or `customer` like %%(txt)s) %s
+		order by name, customer, customer_name
+		limit %s""" % (doctype, searchfield, conditions, "%(start)s, %(page_len)s"),
+		{"txt": "%%%s%%" % txt, "start": start, "page_len": page_len}, as_list=True)
+	
+def query_purchase_return_doc(doctype, txt, searchfield, start, page_len, filters):
+	return webnotes.conn.sql("""select name, supplier, supplier_name
+		from `tab%s` where docstatus = 1
+		and (`%s` like %%(txt)s or `supplier` like %%(txt)s)
+		order by name, supplier, supplier_name
+		limit %s""" % (doctype, searchfield, "%(start)s, %(page_len)s"),
+		{"txt": "%%%s%%" % txt, "start": start, "page_len": page_len}, as_list=True)
+		
+def query_return_item(doctype, txt, searchfield, start, page_len, filters):
+	txt = txt.replace("%", "")
+
+	ref = get_return_reference_details(filters)
+			
+	stock_items = get_stock_items_for_return(ref.doclist, ref.parentfields)
+	
+	result = []
+	for item in ref.doclist.get({"parentfield": ["in", ref.parentfields]}):
+		if item.item_code in stock_items:
+			item.item_name = cstr(item.item_name)
+			item.description = cstr(item.description)
+			if (txt in item.item_code) or (txt in item.item_name) or (txt in item.description):
+				val = [
+					item.item_code, 
+					(len(item.item_name) > 40) and (item.item_name[:40] + "...") or item.item_name, 
+					(len(item.description) > 40) and (item.description[:40] + "...") or \
+						item.description
+				]
+				if val not in result:
+					result.append(val)
+
+	return result[start:start+page_len]
+
+def get_stock_items_for_return(ref_doclist, parentfields):
+	"""return item codes filtered from doclist, which are stock items"""
+	if isinstance(parentfields, basestring):
+		parentfields = [parentfields]
+	
+	all_items = list(set([d.item_code for d in 
+		ref_doclist.get({"parentfield": ["in", parentfields]})]))
+	stock_items = webnotes.conn.sql_list("""select name from `tabItem`
+		where is_stock_item='Yes' and name in (%s)""" % (", ".join(["%s"] * len(all_items))),
+		tuple(all_items))
+
+	return stock_items
+	
+def get_return_reference_details(args):
+	ref = webnotes._dict()
+	
+	# get ref_doclist
+	if args["purpose"] in return_map:
+		for fieldname, val in return_map[args["purpose"]].items():
+			if args.get(fieldname):
+				ref.fieldname = fieldname
+				ref.doclist = webnotes.get_doclist(val[0], args[fieldname])
+				ref.parentfields = val[1]
+				break
+				
+	return ref
+	
+return_map = {
+	"Sales Return": {
+		# [Ref DocType, [Item tables' parentfields]]
+		"delivery_note_no": ["Delivery Note", ["delivery_note_details", "packing_details"]],
+		"sales_invoice_no": ["Sales Invoice", ["entries", "packing_details"]]
+	},
+	"Purchase Return": {
+		"purchase_receipt_no": ["Purchase Receipt", ["purchase_receipt_details"]]
+	}
+}
+
+@webnotes.whitelist()
+def make_return_jv(stock_entry):
+	se = webnotes.bean("Stock Entry", stock_entry)
+	if not se.doc.purpose in ["Sales Return", "Purchase Return"]:
+		return
+	
+	ref = get_return_reference_details(se.doc.fields)
+	
+	if ref.doclist[0].doctype == "Delivery Note":
+		result = make_return_jv_from_delivery_note(se, ref)
+	elif ref.doclist[0].doctype == "Sales Invoice":
+		result = make_return_jv_from_sales_invoice(se, ref)
+	elif ref.doclist[0].doctype == "Purchase Receipt":
+		result = make_return_jv_from_purchase_receipt(se, ref)
+	
+	# create jv doclist and fetch balance for each unique row item
+	jv_list = [{
+		"__islocal": 1,
+		"doctype": "Journal Voucher",
+		"posting_date": se.doc.posting_date,
+		"voucher_type": se.doc.purpose == "Sales Return" and "Credit Note" or "Debit Note",
+		"fiscal_year": se.doc.fiscal_year,
+		"company": se.doc.company
+	}]
+	
+	from accounts.utils import get_balance_on
+	for r in result:
+		jv_list.append({
+			"__islocal": 1,
+			"doctype": "Journal Voucher Detail",
+			"parentfield": "entries",
+			"account": r.get("account"),
+			"debit": r.get("debit"),
+			"credit": r.get("credit"),
+			"against_invoice": r.get("against_invoice"),
+			"against_voucher": r.get("against_voucher"),
+			"balance": get_balance_on(r.get("account"), se.doc.posting_date)
+		})
+		
+	return jv_list
+	
+def make_return_jv_from_sales_invoice(se, ref):
+	# customer account entry
+	parent = {
+		"account": ref.doclist[0].debit_to,
+		"credit": 0.0,
+		"against_invoice": ref.doclist[0].name,
+	}
+	
+	# income account entries
+	children = {}
+	for se_item in se.doclist.get({"parentfield": "mtn_details"}):
+		# find item in ref.doclist
+		ref_item = ref.doclist.getone({"item_code": se_item.item_code})
+		
+		account, debit = get_sales_account_and_amount_from_item(ref.doclist, ref_item,
+			se_item.transfer_qty)
+		
+		if account not in children:
+			children[account] = 0
+		children[account] += debit
+		parent["credit"] += debit
+			
+	# find tax account and value and add corresponding rows
+	
+	return [parent] + [{"account": account, "debit": debit} for account, debit in children.items()]
+	
+def get_sales_account_and_amount_from_item(doclist, ref_item, transfer_qty):
+	account = debit = None
+	if not ref_item.income_account:
+		if ref_item.parent_item:
+			parent_item = doclist.getone({"item_code": ref_item.parent_item})
+			packing_ratio = parent_item.qty / ref_item.qty
+
+			debit = parent_item.basic_rate * transfer_qty * packing_ratio
+			account = parent_item.income_account
+	else:
+		debit = ref_item.basic_rate * transfer_qty
+		account = ref_item.income_account
+	
+	return account, debit	
+	
+def make_return_jv_from_delivery_note(se, ref):
+	invoices_against_delivery = get_invoice_list("Sales Invoice Item", "delivery_note",
+		ref.doclist[0].name)
+	
+	if not invoices_against_delivery:
+		sales_orders_against_delivery = [d.prevdoc_docname for d in 
+			ref.doclist.get({"prevdoc_doctype": "Sales Order"}) if d.prevdoc_docname]
+		
+		invoices_against_delivery = get_invoice_list("Sales Invoice Item", "sales_order",
+			sales_orders_against_delivery)
+	
+	against_invoice = {}
+	
+	for se_item in se.doclist.get({"parentfield": "mtn_details"}):
+		pending = se_item.transfer_qty
+		for sales_invoice in invoices_against_delivery:
+			si = webnotes.bean("Sales Invoice", sales_invoice)
+			si.run_method("make_packing_list")
+			ref_item = si.doclist.get({"item_code": se_item.item_code})
+			
+			if not ref_item:
+				continue
+			
+			ref_item = ref_item[0]
+			
+			if ref_item.qty < pending:
+				transfer_qty = ref_item.qty
+				pending -= ref_item.qty
+			else:
+				transfer_qty = pending
+				pending = 0
+			
+			account, debit = get_sales_account_and_amount_from_item(si.doclist, ref_item,
+				transfer_qty)
+				
+			if si.doclist[0].name not in against_invoice:
+				against_invoice[sales_invoice] = {
+					"parent": {"account": si.doclist[0].debit_to, "credit": 0},
+					"children": {}
+				}
+				
+			against_invoice[sales_invoice]["parent"]["credit"] += debit
+			
+			if account not in against_invoice[sales_invoice]["children"]:
+				against_invoice[sales_invoice]["children"][account] = 0
+			
+			against_invoice[sales_invoice]["children"][account] += debit
+			
+			# find tax account and value and add corresponding rows
+			
+			if pending <= 0:
+				break
+	
+	result = []
+	for sales_invoice, opts in against_invoice.items():
+		parent = opts["parent"]
+		parent.update({"against_invoice": sales_invoice})
+		children = [{"account": account, "debit": debit} 
+			for account, debit in opts["children"].items()]
+		result += [parent] + children
+	return result
+	
+def get_invoice_list(doctype, link_field, value):
+	if isinstance(value, basestring):
+		value = [value]
+	
+	return webnotes.conn.sql_list("""select distinct parent from `tab%s`
+		where docstatus = 1 and `%s` in (%s)""" % (doctype, link_field,
+			", ".join(["%s"]*len(value))), tuple(value))
+			
+def make_return_jv_from_purchase_receipt(se, ref):
+	invoice_against_receipt = get_invoice_list("Purchase Invoice Item", "purchase_receipt",
+		ref.doclist[0].name)
+	
+	if not invoice_against_receipt:
+		purchase_orders_against_receipt = [d.prevdoc_docname for d in 
+			ref.doclist.get({"prevdoc_doctype": "Purchase Order"}) if d.prevdoc_docname]
+		
+		invoice_against_receipt = get_invoice_list("Purchase Invoice Item", "purchase_order",
+			purchase_orders_against_receipt)
+			
+	against_voucher = {}
+	
+	for se_item in se.doclist.get({"parentfield": "mtn_details"}):
+		pending = se_item.transfer_qty
+		for purchase_invoice in invoice_against_receipt:
+			pi = webnotes.bean("Purchase Invoice", purchase_invoice)
+			ref_item = pi.doclist.get({"item_code": se_item.item_code})
+			
+			if not ref_item:
+				continue
+			
+			ref_item = ref_item[0]
+			
+			if ref_item.qty < pending:
+				transfer_qty = ref_item.qty
+				pending -= ref_item.qty
+			else:
+				transfer_qty = pending
+				pending = 0
+			
+			credit = ref_item.rate * transfer_qty
+			account = ref_item.expense_head
+			
+			if pi.doclist[0].name not in against_voucher:
+				against_voucher[purchase_invoice] = {
+					"parent": {"account": pi.doclist[0].credit_to, "debit": 0},
+					"children": {}
+				}
+			
+			against_voucher[purchase_invoice]["parent"]["debit"] += credit
+
+			if account not in against_voucher[purchase_invoice]["children"]:
+				against_voucher[purchase_invoice]["children"][account] = 0
+				
+			against_voucher[purchase_invoice]["children"][account] += credit
+			
+			# find tax account and value and add corresponding rows
+			
+			if pending <= 0:
+				break
+	
+	result = []
+	for purchase_invoice, opts in against_voucher.items():
+		parent = opts["parent"]
+		parent.update({"against_voucher": purchase_invoice})
+		children = [{"account": account, "credit": credit} 
+			for account, credit in opts["children"].items()]
+		result += [parent] + children
+	return result
+		
\ No newline at end of file
diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py
index a4103c3..049b0e6 100644
--- a/stock/doctype/stock_entry/test_stock_entry.py
+++ b/stock/doctype/stock_entry/test_stock_entry.py
@@ -3,11 +3,15 @@
 
 from __future__ import unicode_literals
 import webnotes, unittest
+from webnotes.utils import flt
 
 class TestStockEntry(unittest.TestCase):
 	def test_auto_material_request(self):
 		webnotes.conn.sql("""delete from `tabMaterial Request Item`""")
 		webnotes.conn.sql("""delete from `tabMaterial Request`""")
+		self._clear_stock()
+		
+		webnotes.conn.set_value("Global Defaults", None, "auto_indent", True)
 
 		st1 = webnotes.bean(copy=test_records[0])
 		st1.insert()
@@ -22,7 +26,7 @@
 			
 		self.assertTrue(mr_name)
 		
-	def test_material_receipt_gl_entry(self):
+	def atest_material_receipt_gl_entry(self):
 		webnotes.conn.sql("delete from `tabStock Ledger Entry`")
 		webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
 		
@@ -59,7 +63,7 @@
 		
 		webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
 
-	def test_material_issue_gl_entry(self):
+	def atest_material_issue_gl_entry(self):
 		webnotes.conn.sql("delete from `tabStock Ledger Entry`")
 		webnotes.defaults.set_global_default("auto_inventory_accounting", 1)
 		
@@ -147,7 +151,7 @@
 			self.assertEquals(expected_sle[i][1], sle.warehouse)
 			self.assertEquals(expected_sle[i][2], sle.actual_qty)
 		
-	def check_gl_entries(self, voucher_type, voucher_no, expected_gl_entries):
+	def acheck_gl_entries(self, voucher_type, voucher_no, expected_gl_entries):
 		# check gl entries
 		
 		gl_entries = webnotes.conn.sql("""select account, debit, credit
@@ -158,7 +162,411 @@
 			self.assertEquals(expected_gl_entries[i][0], gle.account)
 			self.assertEquals(expected_gl_entries[i][1], gle.debit)
 			self.assertEquals(expected_gl_entries[i][2], gle.credit)
+	
+	def _clear_stock(self):
+		webnotes.conn.sql("delete from `tabStock Ledger Entry`")
+		webnotes.conn.sql("""delete from `tabBin`""")
+	
+	def _insert_material_receipt(self):
+		self._clear_stock()
+		se1 = webnotes.bean(copy=test_records[0])
+		se1.insert()
+		se1.submit()
+		
+		se2 = webnotes.bean(copy=test_records[0])
+		se2.doclist[1].item_code = "_Test Item Home Desktop 100"
+		se2.insert()
+		se2.submit()
+		
+	def _get_actual_qty(self):
+		return flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", 
+			"warehouse": "_Test Warehouse"}, "actual_qty"))
+			
+	def _test_sales_invoice_return(self, item_code, delivered_qty, returned_qty):
+		from stock.doctype.stock_entry.stock_entry import NotUpdateStockError
+		
+		from accounts.doctype.sales_invoice.test_sales_invoice \
+			import test_records as sales_invoice_test_records
+		
+		# invalid sales invoice as update stock not checked
+		si = webnotes.bean(copy=sales_invoice_test_records[1])
+		si.insert()
+		si.submit()
+		
+		se = webnotes.bean(copy=test_records[0])
+		se.doc.purpose = "Sales Return"
+		se.doc.sales_invoice_no = si.doc.name
+		se.doclist[1].qty = returned_qty
+		se.doclist[1].transfer_qty = returned_qty
+		self.assertRaises(NotUpdateStockError, se.insert)
+		
+		self._insert_material_receipt()
+		
+		# check currency available qty in bin
+		actual_qty_0 = self._get_actual_qty()
+		
+		# insert a pos invoice with update stock
+		si = webnotes.bean(copy=sales_invoice_test_records[1])
+		si.doc.is_pos = si.doc.update_stock = 1
+		si.doclist[1].warehouse = "_Test Warehouse"
+		si.doclist[1].item_code = item_code
+		si.insert()
+		si.submit()
+		
+		# check available bin qty after invoice submission
+		actual_qty_1 = self._get_actual_qty()
+		
+		self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1)
+		
+		# check if item is validated
+		se = webnotes.bean(copy=test_records[0])
+		se.doc.purpose = "Sales Return"
+		se.doc.sales_invoice_no = si.doc.name
+		se.doc.posting_date = "2013-03-10"
+		se.doclist[1].item_code = "_Test Item Home Desktop 200"
+		se.doclist[1].qty = returned_qty
+		se.doclist[1].transfer_qty = returned_qty
+		
+		# check if stock entry gets submitted
+		self.assertRaises(webnotes.DoesNotExistError, se.insert)
+		
+		# try again
+		se = webnotes.bean(copy=test_records[0])
+		se.doc.purpose = "Sales Return"
+		se.doc.posting_date = "2013-03-10"
+		se.doc.sales_invoice_no = si.doc.name
+		se.doclist[1].qty = returned_qty
+		se.doclist[1].transfer_qty = returned_qty
+		# in both cases item code remains _Test Item when returning
+		se.insert()
+		
+		se.submit()
+		
+		# check if available qty is increased
+		actual_qty_2 = self._get_actual_qty()
+		
+		self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2)
+		
+		return se
+	
+	def test_sales_invoice_return_of_non_packing_item(self):
+		self._test_sales_invoice_return("_Test Item", 5, 2)
+			
+	def test_sales_invoice_return_of_packing_item(self):
+		self._test_sales_invoice_return("_Test Sales BOM Item", 25, 20)
+		
+	def _test_delivery_note_return(self, item_code, delivered_qty, returned_qty):
+		self._insert_material_receipt()
+		
+		from stock.doctype.delivery_note.test_delivery_note \
+			import test_records as delivery_note_test_records
+		
+		actual_qty_0 = self._get_actual_qty()
+		
+		# make a delivery note based on this invoice
+		dn = webnotes.bean(copy=delivery_note_test_records[0])
+		dn.doclist[1].item_code = item_code
+		dn.insert()
+		dn.submit()
+		
+		actual_qty_1 = self._get_actual_qty()
+		
+		self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1)
+		
+		si_doclist = webnotes.map_doclist([
+			["Delivery Note", "Sales Invoice"],
+			["Delivery Note Item", "Sales Invoice Item"],
+			["Sales Taxes and Charges", "Sales Taxes and Charges"],
+			["Sales Team", "Sales Team"]], dn.doc.name)
+			
+		si = webnotes.bean(si_doclist)
+		si.doc.posting_date = dn.doc.posting_date
+		si.doc.debit_to = "_Test Customer - _TC"
+		for d in si.doclist.get({"parentfield": "entries"}):
+			d.income_account = "Sales - _TC"
+			d.cost_center = "_Test Cost Center - _TC"
+		si.insert()
+		si.submit()
+		
+		# insert and submit stock entry for sales return
+		se = webnotes.bean(copy=test_records[0])
+		se.doc.purpose = "Sales Return"
+		se.doc.delivery_note_no = dn.doc.name
+		se.doc.posting_date = "2013-03-10"
+		se.doclist[1].qty = se.doclist[1].transfer_qty = returned_qty
+		
+		se.insert()
+		se.submit()
+		
+		actual_qty_2 = self._get_actual_qty()
+		self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2)
+		
+		return se
+		
+	def test_delivery_note_return_of_non_packing_item(self):
+		self._test_delivery_note_return("_Test Item", 5, 2)
+		
+	def test_delivery_note_return_of_packing_item(self):
+		self._test_delivery_note_return("_Test Sales BOM Item", 25, 20)
+		
+	def _test_sales_return_jv(self, se, returned_value):
+		from stock.doctype.stock_entry.stock_entry import make_return_jv
+		jv_list = make_return_jv(se.doc.name)
+		
+		self.assertEqual(len(jv_list), 3)
+		self.assertEqual(jv_list[0].get("voucher_type"), "Credit Note")
+		self.assertEqual(jv_list[0].get("posting_date"), se.doc.posting_date)
+		self.assertEqual(jv_list[1].get("account"), "_Test Customer - _TC")
+		self.assertEqual(jv_list[2].get("account"), "Sales - _TC")
+		self.assertTrue(jv_list[1].get("against_invoice"))
+		
+		# debit == credit
+		debit = sum([flt(d.get("debit")) for d in jv_list])
+		credit = sum([flt(d.get("credit")) for d in jv_list])
+		self.assertEqual(debit, credit)
+		
+		# validate value of debit
+		self.assertEqual(debit, returned_value)
+		
+	def test_make_return_jv_for_sales_invoice_non_packing_item(self):
+		se = self._test_sales_invoice_return("_Test Item", 5, 2)
+		self._test_sales_return_jv(se, 1000)
+		
+	def test_make_return_jv_for_sales_invoice_packing_item(self):
+		se = self._test_sales_invoice_return("_Test Sales BOM Item", 25, 20)
+		self._test_sales_return_jv(se, 2000)
+		
+	def test_make_return_jv_for_delivery_note_non_packing_item(self):
+		se = self._test_delivery_note_return("_Test Item", 5, 2)
+		self._test_sales_return_jv(se, 200)
+		
+		se = self._test_delivery_note_return_against_sales_order("_Test Item", 5, 2)
+		self._test_sales_return_jv(se, 200)
+		
+	def test_make_return_jv_for_delivery_note_packing_item(self):
+		se = self._test_delivery_note_return("_Test Sales BOM Item", 25, 20)
+		self._test_sales_return_jv(se, 400)
+		
+		se = self._test_delivery_note_return_against_sales_order("_Test Sales BOM Item", 25, 20)
+		self._test_sales_return_jv(se, 400)
+		
+	def _test_delivery_note_return_against_sales_order(self, item_code, delivered_qty, returned_qty):
+		self._insert_material_receipt()
 
+		from selling.doctype.sales_order.test_sales_order \
+			import test_records as sales_order_test_records
+
+		actual_qty_0 = self._get_actual_qty()
+		
+		so = webnotes.bean(copy=sales_order_test_records[0])
+		so.doclist[1].item_code = item_code
+		so.doclist[1].qty = 5.0
+		so.insert()
+		so.submit()
+		
+		dn_doclist = webnotes.map_doclist([
+			["Sales Order", "Delivery Note"],
+			["Sales Order Item", "Delivery Note Item"],
+			["Sales Taxes and Charges", "Sales Taxes and Charges"],
+			["Sales Team", "Sales Team"]], so.doc.name)
+
+		dn = webnotes.bean(dn_doclist)
+		dn.doc.status = "Draft"
+		dn.doc.posting_date = so.doc.delivery_date
+		dn.insert()
+		dn.submit()
+		
+		actual_qty_1 = self._get_actual_qty()
+
+		self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1)
+
+		si_doclist = webnotes.map_doclist([
+			["Sales Order", "Sales Invoice"],
+			["Sales Order Item", "Sales Invoice Item"],
+			["Sales Taxes and Charges", "Sales Taxes and Charges"],
+			["Sales Team", "Sales Team"]], so.doc.name)
+
+		si = webnotes.bean(si_doclist)
+		si.doc.posting_date = dn.doc.posting_date
+		si.doc.debit_to = "_Test Customer - _TC"
+		for d in si.doclist.get({"parentfield": "entries"}):
+			d.income_account = "Sales - _TC"
+			d.cost_center = "_Test Cost Center - _TC"
+		si.insert()
+		si.submit()
+
+		# insert and submit stock entry for sales return
+		se = webnotes.bean(copy=test_records[0])
+		se.doc.purpose = "Sales Return"
+		se.doc.delivery_note_no = dn.doc.name
+		se.doc.posting_date = "2013-03-10"
+		se.doclist[1].qty = se.doclist[1].transfer_qty = returned_qty
+
+		se.insert()
+		se.submit()
+
+		actual_qty_2 = self._get_actual_qty()
+		self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2)
+
+		return se
+		
+	def test_purchase_receipt_return(self):
+		self._clear_stock()
+		
+		actual_qty_0 = self._get_actual_qty()
+		
+		from stock.doctype.purchase_receipt.test_purchase_receipt \
+			import test_records as purchase_receipt_test_records
+		
+		# submit purchase receipt
+		pr = webnotes.bean(copy=purchase_receipt_test_records[0])
+		pr.insert()
+		pr.submit()
+		
+		actual_qty_1 = self._get_actual_qty()
+		
+		self.assertEquals(actual_qty_0 + 10, actual_qty_1)
+		
+		pi_doclist = webnotes.map_doclist([
+			["Purchase Receipt", "Purchase Invoice"],
+			["Purchase Receipt Item", "Purchase Invoice Item"],
+			["Purchase Taxes and Charges", "Purchase Taxes and Charges"]], pr.doc.name)
+			
+		pi = webnotes.bean(pi_doclist)
+		pi.doc.posting_date = pr.doc.posting_date
+		pi.doc.credit_to = "_Test Supplier - _TC"
+		for d in pi.doclist.get({"parentfield": "entries"}):
+			d.expense_head = "_Test Account Cost for Goods Sold - _TC"
+			d.cost_center = "_Test Cost Center - _TC"
+		for d in pi.doclist.get({"parentfield": "purchase_tax_details"}):
+			d.cost_center = "_Test Cost Center - _TC"
+		
+		pi.run_method("calculate_taxes_and_totals")
+		pi.insert()
+		pi.submit()
+		
+		# submit purchase return
+		se = webnotes.bean(copy=test_records[0])
+		se.doc.purpose = "Purchase Return"
+		se.doc.purchase_receipt_no = pr.doc.name
+		se.doc.posting_date = "2013-03-01"
+		se.doclist[1].qty = se.doclist[1].transfer_qty = 5
+		se.doclist[1].s_warehouse = "_Test Warehouse"
+		se.insert()
+		se.submit()
+		
+		actual_qty_2 = self._get_actual_qty()
+		
+		self.assertEquals(actual_qty_1 - 5, actual_qty_2)
+		
+		return se, pr.doc.name
+		
+	def test_over_stock_return(self):
+		from stock.doctype.stock_entry.stock_entry import StockOverReturnError
+		
+		# out of 10, 5 gets returned
+		prev_se, pr_docname = self.test_purchase_receipt_return()
+		
+		# submit purchase return - return another 6 qtys so that exception is raised
+		se = webnotes.bean(copy=test_records[0])
+		se.doc.purpose = "Purchase Return"
+		se.doc.purchase_receipt_no = pr_docname
+		se.doc.posting_date = "2013-03-01"
+		se.doclist[1].qty = se.doclist[1].transfer_qty = 6
+		se.doclist[1].s_warehouse = "_Test Warehouse"
+		
+		self.assertRaises(StockOverReturnError, se.insert)
+		
+	def _test_purchase_return_jv(self, se, returned_value):
+		from stock.doctype.stock_entry.stock_entry import make_return_jv
+		jv_list = make_return_jv(se.doc.name)
+		
+		self.assertEqual(len(jv_list), 3)
+		self.assertEqual(jv_list[0].get("voucher_type"), "Debit Note")
+		self.assertEqual(jv_list[0].get("posting_date"), se.doc.posting_date)
+		self.assertEqual(jv_list[1].get("account"), "_Test Supplier - _TC")
+		self.assertEqual(jv_list[2].get("account"), "_Test Account Cost for Goods Sold - _TC")
+		self.assertTrue(jv_list[1].get("against_voucher"))
+		
+		# debit == credit
+		debit = sum([flt(d.get("debit")) for d in jv_list])
+		credit = sum([flt(d.get("credit")) for d in jv_list])
+		self.assertEqual(debit, credit)
+		
+		# validate value of credit
+		self.assertEqual(credit, returned_value)
+		
+	def test_make_return_jv_for_purchase_receipt(self):
+		se, pr_name = self.test_purchase_receipt_return()
+		self._test_purchase_return_jv(se, 250)
+		
+		se, pr_name = self._test_purchase_return_return_against_purchase_order()
+		self._test_purchase_return_jv(se, 250)
+		
+	def _test_purchase_return_return_against_purchase_order(self):
+		self._clear_stock()
+		
+		actual_qty_0 = self._get_actual_qty()
+		
+		from buying.doctype.purchase_order.test_purchase_order \
+			import test_records as purchase_order_test_records
+		
+		# submit purchase receipt
+		po = webnotes.bean(copy=purchase_order_test_records[0])
+		po.doc.is_subcontracted = None
+		po.doclist[1].item_code = "_Test Item"
+		po.doclist[1].import_rate = 50
+		po.insert()
+		po.submit()
+		
+		pr_doclist = webnotes.map_doclist([
+			["Purchase Order", "Purchase Receipt"],
+			["Purchase Order Item", "Purchase Receipt Item"],
+			["Purchase Taxes and Charges", "Purchase Taxes and Charges"]], po.doc.name)
+		
+		pr = webnotes.bean(pr_doclist)
+		pr.doc.posting_date = po.doc.transaction_date
+		pr.insert()
+		pr.submit()
+		
+		actual_qty_1 = self._get_actual_qty()
+		
+		self.assertEquals(actual_qty_0 + 10, actual_qty_1)
+		
+		pi_doclist = webnotes.map_doclist([
+			["Purchase Order", "Purchase Invoice"],
+			["Purchase Order Item", "Purchase Invoice Item"],
+			["Purchase Taxes and Charges", "Purchase Taxes and Charges"]], po.doc.name)
+			
+		pi = webnotes.bean(pi_doclist)
+		pi.doc.posting_date = pr.doc.posting_date
+		pi.doc.credit_to = "_Test Supplier - _TC"
+		for d in pi.doclist.get({"parentfield": "entries"}):
+			d.expense_head = "_Test Account Cost for Goods Sold - _TC"
+			d.cost_center = "_Test Cost Center - _TC"
+		for d in pi.doclist.get({"parentfield": "purchase_tax_details"}):
+			d.cost_center = "_Test Cost Center - _TC"
+		
+		pi.run_method("calculate_taxes_and_totals")
+		pi.insert()
+		pi.submit()
+		
+		# submit purchase return
+		se = webnotes.bean(copy=test_records[0])
+		se.doc.purpose = "Purchase Return"
+		se.doc.purchase_receipt_no = pr.doc.name
+		se.doc.posting_date = "2013-03-01"
+		se.doclist[1].qty = se.doclist[1].transfer_qty = 5
+		se.doclist[1].s_warehouse = "_Test Warehouse"
+		se.insert()
+		se.submit()
+		
+		actual_qty_2 = self._get_actual_qty()
+		
+		self.assertEquals(actual_qty_1 - 5, actual_qty_2)
+		
+		return se, pr.doc.name
+		
 test_records = [
 	[
 		{
diff --git a/stock/doctype/stock_ledger/stock_ledger.py b/stock/doctype/stock_ledger/stock_ledger.py
index 5dff992..fcb4a54 100644
--- a/stock/doctype/stock_ledger/stock_ledger.py
+++ b/stock/doctype/stock_ledger/stock_ledger.py
@@ -209,12 +209,13 @@
 
 			if v.get("actual_qty"):
 				sle_id = self.make_entry(v)
-
+				
 			args = v.copy()
 			args.update({
 				"sle_id": sle_id,
 				"is_amended": is_amended
 			})
+			
 			get_obj('Warehouse', v["warehouse"]).update_bin(args)
 
 
diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index d1fe3d9..3089a57 100644
--- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -39,7 +39,7 @@
 		self.check_stock_frozen_date()
 		self.scrub_posting_time()
 		self.doc.fiscal_year = get_fiscal_year(self.doc.posting_date)[0]
-	
+		
 	#check for item quantity available in stock
 	def actual_amt_check(self):
 		if self.doc.batch_no:
diff --git a/stock/stock_ledger.py b/stock/stock_ledger.py
index 883ced7..f15866d 100644
--- a/stock/stock_ledger.py
+++ b/stock/stock_ledger.py
@@ -36,6 +36,7 @@
 		}
 	"""
 	previous_sle = get_sle_before_datetime(args)
+	
 	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 "[]")
@@ -43,7 +44,7 @@
 
 	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"])
 	
 	for sle in entries_to_fix:
@@ -127,7 +128,7 @@
 	if not args.get("posting_date"):
 		args["posting_date"] = "1900-01-01"
 	if not args.get("posting_time"):
-		args["posting_time"] = "12:00"
+		args["posting_time"] = "00:00"
 	
 	return webnotes.conn.sql("""select * from `tabStock Ledger Entry`
 		where item_code = %%(item_code)s
diff --git a/utilities/transaction_base.py b/utilities/transaction_base.py
index 905e98f..2dc8c6a 100644
--- a/utilities/transaction_base.py
+++ b/utilities/transaction_base.py
@@ -16,7 +16,7 @@
 
 from __future__ import unicode_literals
 import webnotes
-from webnotes.utils import load_json, cstr, flt
+from webnotes.utils import load_json, cstr, flt, now_datetime
 from webnotes.model.doc import addchild
 
 from webnotes.model.controller import DocListController
@@ -246,4 +246,8 @@
 		[d.update({"doctype":"Communication"}) for d in comm_list]
 		
 		self.doclist.extend(webnotes.doclist([webnotes.doc(fielddata=d) \
-			for d in comm_list]))
\ No newline at end of file
+			for d in comm_list]))
+			
+	def validate_posting_time(self):
+		if not self.doc.posting_time:
+			self.doc.posting_time = now_datetime().strftime('%H:%M:%S')
\ No newline at end of file