Discount in purchase cycle Merge branch 'master' of git://github.com/nijil/erpnext

Conflicts:
	erpnext/accounts/doctype/pv_detail/pv_detail.txt
	erpnext/buying/doctype/po_detail/po_detail.txt
	erpnext/stock/doctype/purchase_receipt_detail/purchase_receipt_detail.txt
diff --git a/.gitignore b/.gitignore
index 7f90378..0818a02 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@
 patch.log
 lib
 versions-local.db
+*.sql*
diff --git a/erpnext/accounts/doctype/gl_control/gl_control.py b/erpnext/accounts/doctype/gl_control/gl_control.py
index 44a9e8d..01f31eb 100644
--- a/erpnext/accounts/doctype/gl_control/gl_control.py
+++ b/erpnext/accounts/doctype/gl_control/gl_control.py
@@ -4,8 +4,8 @@
 from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
 from webnotes.model import db_exists
 from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
-from webnotes.model.doclist import getlist, copy_doclist
-from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
+from webnotes.model.doclist import getlist, copy_doclist, clone
+from webnotes.model.code import get_obj
 from webnotes import session, form, is_testing, msgprint, errprint
 
 sql = webnotes.conn.sql
@@ -24,14 +24,8 @@
 	# Get Company List
 	# ----------------
 	def get_companies(self,arg=''):
-		#d = get_defaults()
 		ret = sql("select name, abbr from tabCompany where docstatus != 2")
-		#pl = {}
-		#for r in ret:
-		#	inc = get_value('Account','Income - '+r[1], 'balance')
-		#	exp = get_value('Account','Expenses - '+r[1], 'balance')
-		#	pl[r[0]] = flt(flt(inc) - flt(exp))
-		return {'cl':[r[0] for r in ret]}#, 'pl':pl}
+		return {'cl':[r[0] for r in ret]}
 
 	def get_company_currency(self,arg=''):
 		dcc = TransactionBase().get_company_currency(arg)
@@ -506,3 +500,39 @@
 			for a in set(ac_list):
 				fy_obj.repost(a)
 
+
+def manage_recurring_invoices():
+	""" 
+		Create recurring invoices on specific date by copying the original one
+		and notify the concerned people
+	"""	
+	rv = sql("""select name, recurring_id from `tabReceivable Voucher` where ifnull(convert_into_recurring_invoice, 0) = 1 
+			and next_date = %s and next_date <= end_date order by next_date	desc""", nowdate())
+	for d in rv:
+		if not sql("""select name from `tabReceivable Voucher` where posting_date = %s and recurring_id = %s""", (nowdate(), d[1])):
+			prev_rv = get_obj('Receivable Voucher', d[0], with_children=1)
+			new_rv = create_new_invoice(prev_rv)
+
+			send_notification(new_rv)
+
+def create_new_invoice(prev_rv):
+	# clone rv
+	new_rv = clone(prev_rv)
+
+	# update new rv 
+
+	new_rv.doc.voucher_date = new_rv.doc.next_date
+	new_rv.doc.posting_date = new_rv.doc.next_date
+	new_rv.doc.aging_date = new_rv.doc.next_date
+	new_rv.doc.due_date = add_days(new_rv.doc.next_date, cint(date_diff(prev_rv.doc.due_date, prev_rv.doc.posting_date)))
+	new_rv.doc.save()
+
+	# submit and after submit
+	new_rv.submit()
+	new_rv.update_after_submit()
+
+	return new_rv
+
+def send_notification(new_rv):
+	"""Notify concerned persons about recurring invoice generation"""
+	pass
diff --git a/erpnext/accounts/doctype/gl_entry/gl_entry.txt b/erpnext/accounts/doctype/gl_entry/gl_entry.txt
index 776cbb3..1d84e1d 100644
--- a/erpnext/accounts/doctype/gl_entry/gl_entry.txt
+++ b/erpnext/accounts/doctype/gl_entry/gl_entry.txt
@@ -5,24 +5,26 @@
 	{
 		'creation': '2010-08-08 17:09:03',
 		'docstatus': 0,
-		'modified': '2010-12-29 12:59:45',
-		'modified_by': 'umair@iwebnotes.com',
+		'modified': '2011-11-24 15:03:45',
+		'modified_by': 'Administrator',
 		'owner': 'Administrator'
 	},
 
 	# These values are common for all DocType
 	{
-		'_last_update': '1309508838',
+		'_last_update': '1319016431',
 		'autoname': 'GL.#######',
 		'colour': 'White:FFF',
+		'default_print_format': 'Standard',
 		'doctype': 'DocType',
+		'in_create': 1,
 		'module': 'Accounts',
 		'name': '__common__',
 		'search_fields': 'voucher_no,account,posting_date,against_voucher',
 		'section_style': 'Simple',
 		'server_code_error': ' ',
 		'show_in_menu': 0,
-		'version': 101
+		'version': 103
 	},
 
 	# These values are common for all DocField
@@ -68,7 +70,6 @@
 		'cancel': 0,
 		'create': 0,
 		'doctype': 'DocPerm',
-		'idx': 1,
 		'permlevel': 0,
 		'role': 'Accounts Manager',
 		'submit': 0,
@@ -78,7 +79,6 @@
 	# DocPerm
 	{
 		'doctype': 'DocPerm',
-		'idx': 2,
 		'permlevel': 0,
 		'role': 'System Manager'
 	},
@@ -89,7 +89,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'posting_date',
 		'fieldtype': 'Date',
-		'idx': 1,
 		'in_filter': 1,
 		'label': 'Posting Date',
 		'oldfieldname': 'posting_date',
@@ -103,7 +102,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'transaction_date',
 		'fieldtype': 'Date',
-		'idx': 2,
 		'label': 'Transaction Date',
 		'oldfieldname': 'transaction_date',
 		'oldfieldtype': 'Date'
@@ -114,7 +112,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'aging_date',
 		'fieldtype': 'Date',
-		'idx': 3,
 		'in_filter': 1,
 		'label': 'Aging Date',
 		'oldfieldname': 'aging_date',
@@ -127,7 +124,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'account',
 		'fieldtype': 'Link',
-		'idx': 4,
 		'in_filter': 1,
 		'label': 'Account',
 		'oldfieldname': 'account',
@@ -141,7 +137,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'cost_center',
 		'fieldtype': 'Link',
-		'idx': 5,
 		'in_filter': 1,
 		'label': 'Cost Center',
 		'oldfieldname': 'cost_center',
@@ -155,7 +150,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'debit',
 		'fieldtype': 'Currency',
-		'idx': 6,
 		'label': 'Debit Amt',
 		'oldfieldname': 'debit',
 		'oldfieldtype': 'Currency'
@@ -166,7 +160,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'credit',
 		'fieldtype': 'Currency',
-		'idx': 7,
 		'label': 'Credit Amt',
 		'oldfieldname': 'credit',
 		'oldfieldtype': 'Currency'
@@ -177,7 +170,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'against',
 		'fieldtype': 'Text',
-		'idx': 8,
 		'in_filter': 1,
 		'label': 'Against',
 		'oldfieldname': 'against',
@@ -189,7 +181,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'against_voucher',
 		'fieldtype': 'Data',
-		'idx': 9,
 		'in_filter': 1,
 		'label': 'Against Voucher',
 		'oldfieldname': 'against_voucher',
@@ -202,7 +193,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'against_voucher_type',
 		'fieldtype': 'Data',
-		'idx': 10,
 		'in_filter': 0,
 		'label': 'Against Voucher Type',
 		'oldfieldname': 'against_voucher_type',
@@ -215,7 +205,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'voucher_type',
 		'fieldtype': 'Select',
-		'idx': 11,
 		'in_filter': 1,
 		'label': 'Voucher Type',
 		'oldfieldname': 'voucher_type',
@@ -229,7 +218,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'voucher_no',
 		'fieldtype': 'Data',
-		'idx': 12,
 		'in_filter': 1,
 		'label': 'Voucher No',
 		'oldfieldname': 'voucher_no',
@@ -242,7 +230,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'remarks',
 		'fieldtype': 'Text',
-		'idx': 13,
 		'in_filter': 1,
 		'label': 'Remarks',
 		'no_copy': 1,
@@ -256,7 +243,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'is_cancelled',
 		'fieldtype': 'Select',
-		'idx': 14,
 		'in_filter': 1,
 		'label': 'Is Cancelled',
 		'oldfieldname': 'is_cancelled',
@@ -270,7 +256,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'is_opening',
 		'fieldtype': 'Select',
-		'idx': 15,
 		'in_filter': 1,
 		'label': 'Is Opening',
 		'oldfieldname': 'is_opening',
@@ -284,7 +269,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'is_advance',
 		'fieldtype': 'Select',
-		'idx': 16,
 		'in_filter': 0,
 		'label': 'Is Advance',
 		'oldfieldname': 'is_advance',
@@ -298,7 +282,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'fiscal_year',
 		'fieldtype': 'Select',
-		'idx': 17,
 		'in_filter': 1,
 		'label': 'Fiscal Year',
 		'oldfieldname': 'fiscal_year',
@@ -312,7 +295,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'company',
 		'fieldtype': 'Link',
-		'idx': 18,
 		'in_filter': 1,
 		'label': 'Company',
 		'oldfieldname': 'company',
diff --git a/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.js b/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.js
index bcd5c44..a5ec2b6 100644
--- a/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.js
+++ b/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.js
@@ -2,7 +2,6 @@
 // --------------------
 
 cur_frm.fields_dict.voucher_no.get_query = function(doc) {
-
 	if (!doc.account) msgprint("Please select Account first");
 	else {
 		return repl("select voucher_no, posting_date \
diff --git a/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.py b/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.py
index 7c34546..24a7db5 100644
--- a/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.py
+++ b/erpnext/accounts/doctype/internal_reconciliation/internal_reconciliation.py
@@ -81,7 +81,7 @@
 			and ifnull(t2.against_voucher, '')='' and ifnull(t2.against_invoice, '')='' and ifnull(t2.against_jv, '')=''
 			and t2.%s > 0
 			%s
-			group by t1.name
+			group by t1.name, t2.name
 		"""% ('%s', dc, cond), self.doc.account, as_dict=1)
 
 		return gle
@@ -112,6 +112,9 @@
 			2. split into multiple rows if partially adjusted, assign against voucher
 			3. submit payment voucher
 		"""
+		if not self.doc.voucher_no or not sql("select name from `tab%s` where name = %s" %(self.dt[self.doc.voucher_type], '%s'),  self.doc.voucher_no):
+			msgprint("Please select valid Voucher No to proceed", raise_exception=1)
+		
 		lst = []
 		for d in getlist(self.doclist, 'ir_payment_details'):
 			if d.selected and flt(d.amt_to_be_reconciled) > 0:
@@ -129,8 +132,7 @@
 			
 				lst.append(args)
 		
-		if not sql("select name from `tab%s` where name = %s" %(self.dt[self.doc.voucher_type], '%s'),  self.doc.voucher_no):
-			msgprint("Please select valid Voucher No to proceed", raise_exception=1)
+
 		if lst:
 			get_obj('GL Control').reconcile_against_document(lst)
 			msgprint("Successfully reconciled.")
diff --git a/erpnext/accounts/doctype/pv_detail/pv_detail.txt b/erpnext/accounts/doctype/pv_detail/pv_detail.txt
index eb24976..4e05a5c 100755
--- a/erpnext/accounts/doctype/pv_detail/pv_detail.txt
+++ b/erpnext/accounts/doctype/pv_detail/pv_detail.txt
@@ -5,7 +5,7 @@
 	{
 		'creation': '2010-08-08 17:09:17',
 		'docstatus': 0,
-		'modified': '2011-11-24 15:07:02',
+		'modified': '2011-12-08 15:58:58',
 		'modified_by': 'Administrator',
 		'owner': 'Administrator'
 	},
@@ -14,7 +14,6 @@
 	{
 		'autoname': 'EVD.######',
 		'colour': 'White:FFF',
-		'default_print_format': 'Standard',
 		'doctype': 'DocType',
 		'istable': 1,
 		'module': 'Accounts',
@@ -22,7 +21,7 @@
 		'section_style': 'Tray',
 		'server_code_error': ' ',
 		'show_in_menu': 0,
-		'version': 31
+		'version': 28
 	},
 
 	# These values are common for all DocField
@@ -115,7 +114,7 @@
 		'doctype': 'DocField',
 		'fieldname': 'rate',
 		'fieldtype': 'Currency',
-		'label': 'Rate (Default Curr.)',
+		'label': 'Rate *(Default Curr.)',
 		'oldfieldname': 'rate',
 		'oldfieldtype': 'Currency',
 		'permlevel': 0,
@@ -129,7 +128,7 @@
 		'doctype': 'DocField',
 		'fieldname': 'import_rate',
 		'fieldtype': 'Currency',
-		'label': 'Rate',
+		'label': 'Rate ',
 		'oldfieldname': 'import_rate',
 		'oldfieldtype': 'Currency',
 		'permlevel': 0,
@@ -141,6 +140,15 @@
 	# DocField
 	{
 		'doctype': 'DocField',
+		'fieldname': 'discount_rate',
+		'fieldtype': 'Currency',
+		'label': 'Discount %',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
 		'fieldname': 'qty',
 		'fieldtype': 'Currency',
 		'label': 'Qty',
@@ -212,19 +220,6 @@
 
 	# DocField
 	{
-		'colour': 'White:FFF',
-		'doctype': 'DocField',
-		'fieldname': 'project_name',
-		'fieldtype': 'Link',
-		'in_filter': 1,
-		'label': 'Project Name',
-		'options': 'Project',
-		'permlevel': 0,
-		'print_hide': 1
-	},
-
-	# DocField
-	{
 		'doctype': 'DocField',
 		'fieldname': 'purchase_order',
 		'fieldtype': 'Link',
@@ -324,16 +319,7 @@
 		'doctype': 'DocField',
 		'fieldname': 'import_ref_rate',
 		'fieldtype': 'Currency',
-		'label': 'Ref Rate',
-		'permlevel': 0
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'discount_rate',
-		'fieldtype': 'Currency',
-		'label': 'Discount Rate',
+		'label': 'Ref Rate ',
 		'permlevel': 0
 	}
-]
\ No newline at end of file
+]
diff --git a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js
index bb19681..363da2e 100644
--- a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js
+++ b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.js
@@ -433,3 +433,12 @@
 	}
 	loadreport('GL Entry','General Ledger', callback);
 }
+
+// Default values for recurring invoices
+cur_frm.cscript.convert_into_recurring_invoice = function(doc) {
+	if (doc.convert_into_recurring_invoice) {
+		doc.repeat_on_day_of_month = doc.posting_date.split('-')[2];
+		doc.notification_email_address = doc.owner + ', ' + doc.contact_email;
+		refresh_field(['repeat_on_day_of_month', 'notification_email_address']);
+	}		
+}
diff --git a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py
index 6d1f80a..13ed8d3 100644
--- a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py
+++ b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.py
@@ -1,12 +1,13 @@
 # Please edit this list and import only required elements
 import webnotes
 
-from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
+from webnotes.utils import add_days, add_months, add_years, cint, cstr,date_diff, default_fields, flt, fmt_money, formatdate, generate_hash,getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common,month_name, now, nowdate, replace_newlines, sendmail, set_default,str_esc_quote, user_format, validate_email_add
 from webnotes.model import db_exists
 from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
 from webnotes.model.doclist import getlist, copy_doclist
 from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
 from webnotes import session, form, is_testing, msgprint, errprint
+from webnotes.utils.scheduler import set_event, cancel_event, Scheduler
 
 set = webnotes.conn.set
 sql = webnotes.conn.sql
@@ -528,7 +529,6 @@
 	def make_gl_entries(self, is_cancel=0):
 		mapper = self.doc.is_pos and self.doc.write_off_account and 'POS with write off' or self.doc.is_pos and not self.doc.write_off_account and 'POS' or ''
 		update_outstanding = self.doc.is_pos and self.doc.write_off_account and 'No' or 'Yes'
-
 		get_obj(dt='GL Control').make_gl_entries(self.doc, self.doclist,cancel = is_cancel, use_mapper = mapper, update_outstanding = update_outstanding, merge_entries = cint(self.doc.is_pos) != 1 and 1 or 0)
 		
 
@@ -546,7 +546,8 @@
 			get_obj("Sales Common").update_prevdoc_detail(1,self)
 
 			# Check for Approving Authority
-			get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self)
+			if not self.doc.recurring_id:
+				get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self)
 
 		# this sequence because outstanding may get -ve		
 		self.make_gl_entries()
@@ -618,9 +619,61 @@
 
 		set(self.doc,'outstanding_amount',flt(self.doc.grand_total) - flt(self.doc.total_advance) - flt(self.doc.paid_amount) - flt(self.doc.write_off_amount))
 
-
 ########################################################################
 # Repair Outstanding
 #######################################################################
 	def repair_rv_outstanding(self):
 		get_obj(dt = 'GL Control').repair_voucher_outstanding(self)
+
+	def on_update_after_submit(self):
+		self.convert_into_recurring()
+		
+
+	def convert_into_recurring(self):
+		if self.doc.convert_into_recurring_invoice:
+			event = 'accounts.doctype.gl_control.gl_control.manage_recurring_invoices'
+			self.set_next_date()
+			if not self.doc.recurring_id:
+				set(self.doc, 'recurring_id', make_autoname('RECINV/.#####'))
+
+			if sql("select name from `tabReceivable Voucher` where ifnull(convert_into_recurring_invoice, 0) = 1 and next_date <= end_date"):
+				if not self.check_event_exists(event):
+					set_event(event,  interval = 60*60, recurring = 1)
+			else:
+				cancel_event(event)
+
+		elif self.doc.recurring_id:
+			sql("""update `tabReceivable Voucher` set convert_into_recurring_invoice = 0 where recurring_id = %s""", self.doc.recurring_id)
+
+
+	def check_event_exists(self, event):
+		try:
+			ev = Scheduler().get_events()
+		except:
+			msgprint("Scheduler database not exists. Please mail to support@erpnext.com", raise_exception=1)
+
+		if event in [d['event'] for d in ev]:
+			return 1
+
+
+	def set_next_date(self):
+		""" Set next date on which auto invoice will be created"""
+
+		if not self.doc.repeat_on_day_of_month:
+			msgprint("""Please enter 'Repeat on Day of Month' field value. \nThe day of the month on which auto invoice 
+						will be generated e.g. 05, 28 etc.""", raise_exception=1)
+
+		import datetime
+		m = getdate(self.doc.posting_date).month + 1
+		y = getdate(self.doc.posting_date).year
+		if m > 12:
+			m, y = 1, y+1
+		try:
+			next_date = datetime.date(y, m, cint(self.doc.repeat_on_day_of_month))
+		except:
+			import calendar
+			last_day = calendar.monthrange(y, m)[1]
+			next_date = datetime.date(y, m, last_day)
+		next_date = next_date.strftime("%Y-%m-%d")
+
+		set(self.doc, 'next_date', next_date)
diff --git a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.txt b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.txt
index 1abd6a7..e2fc0c6 100644
--- a/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.txt
+++ b/erpnext/accounts/doctype/receivable_voucher/receivable_voucher.txt
@@ -5,7 +5,7 @@
 	{
 		'creation': '2010-08-08 17:09:18',
 		'docstatus': 0,
-		'modified': '2011-10-19 16:31:54',
+		'modified': '2011-12-06 13:17:26',
 		'modified_by': 'Administrator',
 		'owner': 'Administrator'
 	},
@@ -21,7 +21,7 @@
 
 	# These values are common for all DocType
 	{
-		'_last_update': '1319014846',
+		'_last_update': '1323156733',
 		'change_log': '1. Change in pull_details method dt.-26-06-2009',
 		'colour': 'White:FFF',
 		'default_print_format': 'Standard',
@@ -34,7 +34,7 @@
 		'server_code_error': ' ',
 		'show_in_menu': 0,
 		'subject': 'To %(customer_name)s worth %(currency)s %(grand_total_export)s due on %(due_date)s | %(outstanding_amount)s outstanding',
-		'version': 363
+		'version': 383
 	},
 
 	# These values are common for all DocFormat
@@ -1343,5 +1343,115 @@
 		'permlevel': 0,
 		'print_hide': 1,
 		'report_hide': 1
+	},
+
+	# DocField
+	{
+		'depends_on': 'eval:doc.docstatus==1',
+		'doctype': 'DocField',
+		'fieldtype': 'Section Break',
+		'label': 'Recurring Invoice',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldtype': 'Column Break',
+		'permlevel': 0,
+		'width': '50%'
+	},
+
+	# DocField
+	{
+		'allow_on_submit': 1,
+		'colour': 'White:FFF',
+		'depends_on': 'eval:doc.docstatus==1',
+		'description': 'Check if recurring invoice, uncheck to stop recurring or put proper End Date',
+		'doctype': 'DocField',
+		'fieldname': 'convert_into_recurring_invoice',
+		'fieldtype': 'Check',
+		'label': 'Convert into Recurring Invoice',
+		'no_copy': 1,
+		'permlevel': 0,
+		'print_hide': 1,
+		'trigger': 'Client'
+	},
+
+	# DocField
+	{
+		'allow_on_submit': 1,
+		'depends_on': 'eval:doc.convert_into_recurring_invoice==1',
+		'description': 'The day of the month on which auto invoice will be generated e.g. 05, 28 etc ',
+		'doctype': 'DocField',
+		'fieldname': 'repeat_on_day_of_month',
+		'fieldtype': 'Data',
+		'label': 'Repeat on Day of Month',
+		'no_copy': 1,
+		'permlevel': 0,
+		'print_hide': 1
+	},
+
+	# DocField
+	{
+		'allow_on_submit': 1,
+		'depends_on': 'eval:doc.convert_into_recurring_invoice==1',
+		'description': 'The date on which recurring invoice will be stop',
+		'doctype': 'DocField',
+		'fieldname': 'end_date',
+		'fieldtype': 'Date',
+		'label': 'End Date',
+		'no_copy': 1,
+		'permlevel': 0,
+		'print_hide': 1
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldtype': 'Column Break',
+		'no_copy': 0,
+		'permlevel': 0,
+		'width': '50%'
+	},
+
+	# DocField
+	{
+		'allow_on_submit': 1,
+		'depends_on': 'eval:doc.convert_into_recurring_invoice==1',
+		'description': 'Enter email id separated by commas, invoice will be mailed automatically on particular date',
+		'doctype': 'DocField',
+		'fieldname': 'notification_email_address',
+		'fieldtype': 'Small Text',
+		'label': 'Notification Email Address',
+		'no_copy': 1,
+		'permlevel': 0,
+		'print_hide': 1
+	},
+
+	# DocField
+	{
+		'depends_on': 'eval:doc.convert_into_recurring_invoice==1',
+		'description': 'The unique id for tracking all recurring invoices ',
+		'doctype': 'DocField',
+		'fieldname': 'recurring_id',
+		'fieldtype': 'Data',
+		'label': 'Recurring Id',
+		'no_copy': 1,
+		'permlevel': 1,
+		'print_hide': 1
+	},
+
+	# DocField
+	{
+		'depends_on': 'eval:doc.convert_into_recurring_invoice==1',
+		'description': 'The date on which next invoice will be generated ',
+		'doctype': 'DocField',
+		'fieldname': 'next_date',
+		'fieldtype': 'Date',
+		'label': 'Next Date',
+		'no_copy': 1,
+		'permlevel': 1,
+		'print_hide': 1
 	}
 ]
\ No newline at end of file
diff --git a/erpnext/accounts/search_criteria/payment_receipt_report/payment_receipt_report.py b/erpnext/accounts/search_criteria/payment_receipt_report/payment_receipt_report.py
index 737e658..f92f72c 100644
--- a/erpnext/accounts/search_criteria/payment_receipt_report/payment_receipt_report.py
+++ b/erpnext/accounts/search_criteria/payment_receipt_report/payment_receipt_report.py
@@ -7,21 +7,18 @@
   raise Exception
 
 if not filter_values.get('company'):
-  msgprint("Select Comapny.")
+  msgprint("Select Company to proceed.")
   raise Exception
 
 
-#for r in res:
-#  par_acc = sql("SELECT parent.name FROM `tabAccount` AS node,`tabAccount` AS parent WHERE node.lft BETWEEN parent.lft AND parent.rgt AND node.name = '%s' and parent.cash_flow_level = 'Yes' ORDER BY parent.lft DESC"% r[0])
-#  r.append(par_acc and par_acc[0][0] or '')
 
 col_list = [['Account', 'Link', '150px', 'Account']
            ,['Total', 'Currency', '150px', '']
-#           ,['Parent Account', 'Link', '150px', 'Account']
            ]
+           
 for c in col_list:
   colnames.append(c[0])
   coltypes.append(c[1])
   colwidths.append(c[2])
   coloptions.append(c[3])
-  col_idx[c[0]] = len(colnames) - 1
\ No newline at end of file
+  col_idx[c[0]] = len(colnames) - 1
diff --git a/erpnext/buying/doctype/po_detail/po_detail.txt b/erpnext/buying/doctype/po_detail/po_detail.txt
index d79c8a6..aac949d 100755
--- a/erpnext/buying/doctype/po_detail/po_detail.txt
+++ b/erpnext/buying/doctype/po_detail/po_detail.txt
@@ -5,7 +5,7 @@
 	{
 		'creation': '2010-08-08 17:09:12',
 		'docstatus': 0,
-		'modified': '2011-11-24 15:04:47',
+		'modified': '2011-12-08 16:05:27',
 		'modified_by': 'Administrator',
 		'owner': 'Administrator'
 	},
@@ -14,7 +14,6 @@
 	{
 		'autoname': 'POD/.#####',
 		'colour': 'White:FFF',
-		'default_print_format': 'Standard',
 		'doctype': 'DocType',
 		'istable': 1,
 		'module': 'Buying',
@@ -22,7 +21,7 @@
 		'section_style': 'Tray',
 		'server_code_error': ' ',
 		'show_in_menu': 0,
-		'version': 68
+		'version': 54
 	},
 
 	# These values are common for all DocField
@@ -107,28 +106,13 @@
 	{
 		'default': '0.00',
 		'doctype': 'DocField',
-		'fieldname': 'qty',
+		'fieldname': 'purchase_rate',
 		'fieldtype': 'Currency',
-		'label': 'Quantity',
-		'oldfieldname': 'qty',
+		'label': 'Rate (Default Curr.) *',
+		'oldfieldname': 'purchase_rate',
 		'oldfieldtype': 'Currency',
 		'permlevel': 0,
-		'reqd': 1,
-		'trigger': 'Client',
-		'width': '60px'
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'uom',
-		'fieldtype': 'Link',
-		'label': 'UOM',
-		'oldfieldname': 'uom',
-		'oldfieldtype': 'Link',
-		'options': 'UOM',
-		'permlevel': 0,
-		'print_hide': 0,
+		'print_hide': 1,
 		'reqd': 1,
 		'trigger': 'Client',
 		'width': '100px'
@@ -136,16 +120,6 @@
 
 	# DocField
 	{
-		'default': '0',
-		'doctype': 'DocField',
-		'fieldname': 'discount_rate',
-		'fieldtype': 'Currency',
-		'label': 'Discount',
-		'permlevel': 0
-	},
-
-	# DocField
-	{
 		'doctype': 'DocField',
 		'fieldname': 'purchase_ref_rate',
 		'fieldtype': 'Currency',
@@ -155,18 +129,12 @@
 
 	# DocField
 	{
-		'default': '0.00',
 		'doctype': 'DocField',
-		'fieldname': 'purchase_rate',
+		'fieldname': 'discount_rate',
 		'fieldtype': 'Currency',
-		'label': 'Rate (Default Curr.)',
-		'oldfieldname': 'purchase_rate',
-		'oldfieldtype': 'Currency',
+		'label': 'Discount Rate %',
 		'permlevel': 0,
-		'print_hide': 1,
-		'reqd': 1,
-		'trigger': 'Client',
-		'width': '100px'
+		'trigger': 'Client'
 	},
 
 	# DocField
@@ -185,6 +153,35 @@
 
 	# DocField
 	{
+		'default': '0.00',
+		'doctype': 'DocField',
+		'fieldname': 'qty',
+		'fieldtype': 'Currency',
+		'label': 'Quantity',
+		'oldfieldname': 'qty',
+		'oldfieldtype': 'Currency',
+		'permlevel': 0,
+		'reqd': 1,
+		'trigger': 'Client',
+		'width': '60px'
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldname': 'import_rate',
+		'fieldtype': 'Currency',
+		'hidden': 0,
+		'label': 'Rate ',
+		'oldfieldname': 'import_rate',
+		'oldfieldtype': 'Currency',
+		'permlevel': 0,
+		'print_hide': 0,
+		'trigger': 'Client'
+	},
+
+	# DocField
+	{
 		'doctype': 'DocField',
 		'fieldname': 'import_ref_rate',
 		'fieldtype': 'Currency',
@@ -195,15 +192,17 @@
 	# DocField
 	{
 		'doctype': 'DocField',
-		'fieldname': 'import_rate',
-		'fieldtype': 'Currency',
-		'hidden': 0,
-		'label': 'Rate',
-		'oldfieldname': 'import_rate',
-		'oldfieldtype': 'Currency',
+		'fieldname': 'uom',
+		'fieldtype': 'Link',
+		'label': 'UOM',
+		'oldfieldname': 'uom',
+		'oldfieldtype': 'Link',
+		'options': 'UOM',
 		'permlevel': 0,
 		'print_hide': 0,
-		'trigger': 'Client'
+		'reqd': 1,
+		'trigger': 'Client',
+		'width': '100px'
 	},
 
 	# DocField
@@ -254,17 +253,15 @@
 	{
 		'colour': 'White:FFF',
 		'doctype': 'DocField',
-		'fieldname': 'stock_qty',
-		'fieldtype': 'Currency',
-		'hidden': 0,
-		'label': 'Stock Qty',
-		'no_copy': 1,
-		'oldfieldname': 'stock_qty',
-		'oldfieldtype': 'Currency',
-		'permlevel': 0,
-		'print_hide': 1,
-		'trigger': 'Client',
-		'width': '100px'
+		'fieldname': 'prevdoc_doctype',
+		'fieldtype': 'Data',
+		'hidden': 1,
+		'label': 'Prevdoc DocType',
+		'no_copy': 0,
+		'oldfieldname': 'prevdoc_doctype',
+		'oldfieldtype': 'Data',
+		'permlevel': 1,
+		'print_hide': 1
 	},
 
 	# DocField
@@ -284,34 +281,6 @@
 
 	# DocField
 	{
-		'doctype': 'DocField',
-		'fieldname': 'project_name',
-		'fieldtype': 'Link',
-		'in_filter': 1,
-		'label': 'Project Name',
-		'options': 'Project',
-		'permlevel': 0,
-		'print_hide': 1,
-		'report_hide': 0
-	},
-
-	# DocField
-	{
-		'colour': 'White:FFF',
-		'doctype': 'DocField',
-		'fieldname': 'prevdoc_doctype',
-		'fieldtype': 'Data',
-		'hidden': 1,
-		'label': 'Prevdoc DocType',
-		'no_copy': 0,
-		'oldfieldname': 'prevdoc_doctype',
-		'oldfieldtype': 'Data',
-		'permlevel': 1,
-		'print_hide': 1
-	},
-
-	# DocField
-	{
 		'colour': 'White:FFF',
 		'doctype': 'DocField',
 		'fieldname': 'prevdoc_docname',
@@ -394,6 +363,22 @@
 	# DocField
 	{
 		'doctype': 'DocField',
+		'fieldname': 'stock_qty',
+		'fieldtype': 'Currency',
+		'hidden': 0,
+		'label': 'Stock Qty',
+		'no_copy': 1,
+		'oldfieldname': 'stock_qty',
+		'oldfieldtype': 'Currency',
+		'permlevel': 0,
+		'print_hide': 1,
+		'trigger': 'Client',
+		'width': '100px'
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
 		'fieldname': 'received_qty',
 		'fieldtype': 'Currency',
 		'hidden': 0,
@@ -438,7 +423,7 @@
 
 	# DocField
 	{
-		'allow_on_submit': 0,
+		'allow_on_submit': 1,
 		'doctype': 'DocField',
 		'fieldname': 'page_break',
 		'fieldtype': 'Check',
@@ -450,4 +435,4 @@
 		'permlevel': 0,
 		'print_hide': 1
 	}
-]
\ No newline at end of file
+]
diff --git a/erpnext/home/page/my_company/my_company.py b/erpnext/home/page/my_company/my_company.py
index 3ff1482..c96d998 100644
--- a/erpnext/home/page/my_company/my_company.py
+++ b/erpnext/home/page/my_company/my_company.py
@@ -140,7 +140,9 @@
 	if 'new_password' in args:
 		if cint(webnotes.conn.get_value('Control Panel',None,'sync_with_gateway')):
 			import server_tools.gateway_utils
-			webnotes.msgprint(server_tools.gateway_utils.change_password('', args['new_password'], args['user'], args['sys_admin_pwd'])['message'])
+			res = server_tools.gateway_utils.change_password('', args['new_password'], args['user'], args['sys_admin_pwd'])
+			if 'Traceback' not in res['message']:
+				webnotes.msgprint(res['message'])
 		else:
 			webnotes.conn.sql("update tabProfile set password=password(%s) where name=%s", (args['new_password'], args['user']))
-	else: webnotes.msgprint('Settings Updated')
\ No newline at end of file
+	else: webnotes.msgprint('Settings Updated')
diff --git a/erpnext/patches/index_patch.py b/erpnext/patches/index_patch.py
index 3ef8ec3..788b68d 100644
--- a/erpnext/patches/index_patch.py
+++ b/erpnext/patches/index_patch.py
@@ -293,3 +293,6 @@
 				sql("commit")
 		except:
 			continue
+			
+def execute():
+	create_proper_index()	
diff --git a/erpnext/patches/reload_address.py b/erpnext/patches/reload_address.py
new file mode 100644
index 0000000..252339b
--- /dev/null
+++ b/erpnext/patches/reload_address.py
@@ -0,0 +1,5 @@
+def execute():
+	import webnotes
+	from webnotes.modules.module_manager import reload_doc
+
+	reload_doc('utilities', 'doctype', 'address')
diff --git a/erpnext/patches/reload_doclayer.py b/erpnext/patches/reload_doclayer.py
new file mode 100644
index 0000000..8ee4919
--- /dev/null
+++ b/erpnext/patches/reload_doclayer.py
@@ -0,0 +1,16 @@
+"""
+	Reload DocLayer, DocLayerField and Print Format doctypes
+"""
+def execute():
+	from webnotes.modules.module_manager import reload_doc
+	reload_doc('core', 'doctype', 'print_format')
+	reload_doc('core', 'doctype', 'doclayer')
+	reload_doc('core', 'doctype', 'doclayerfield')
+	reload_doc('accounts', 'doctype', 'gl_entry')
+	from webnotes.model.doc import Document
+	d = Document('DocType Label')
+	d.dt = "DocLayer"
+	d.dt_label = "Customize Form View"
+	d.save(1)
+	from webnotes.session_cache import clear
+	clear()
diff --git a/erpnext/patches/reload_reco.py b/erpnext/patches/reload_reco.py
new file mode 100644
index 0000000..6b9ecc4
--- /dev/null
+++ b/erpnext/patches/reload_reco.py
@@ -0,0 +1,6 @@
+def execute():
+	import webnotes
+	from webnotes.modules.module_manager import reload_doc
+	
+	reload_doc('stock', 'doctype', 'stock_reconciliation')
+	webnotes.conn.sql("delete from `tabDocField` where (label in ('Validate Data', 'Attachment HTML', 'Attachment') or fieldname in ('next_step', 'company', 'fiscal_year', 'amendment_date')) and parent = 'Stock Reconciliation'")
diff --git a/erpnext/patches/reload_rv.py b/erpnext/patches/reload_rv.py
new file mode 100644
index 0000000..5f3bc21
--- /dev/null
+++ b/erpnext/patches/reload_rv.py
@@ -0,0 +1,8 @@
+def execute():
+	import webnotes
+	from webnotes.modules.module_manager import reload_doc
+	from webnotes.model.code import get_obj
+
+	reload_doc('accounts', 'doctype', 'receivable_voucher')
+
+	get_obj('Features setup').validate()
diff --git a/erpnext/patches/repost_stock.py b/erpnext/patches/repost_stock.py
new file mode 100644
index 0000000..680e06f
--- /dev/null
+++ b/erpnext/patches/repost_stock.py
@@ -0,0 +1,22 @@
+def execute():
+    import webnotes
+    sql = webnotes.conn.sql
+    from webnotes.model.code import get_obj
+
+    # update incoming rate in serial nos
+    sr = sql("""select name, item_code, purchase_document_no from `tabSerial No`
+            where docstatus = 1 and purchase_document_type = 'Purchase Receipt'""")
+    for d in sr:
+        val_rate = sql("""select valuation_rate from `tabPurchase Receipt Detail`
+            where item_code = %s and parent = %s""", (d[1], d[2]))
+        sql("""update `tabSerial No` set purchase_rate = %s where name = %s""",
+           (val_rate and flt(val_rate[0][0]) or 0, d[0]))
+    
+    
+    # repost for all serialized item
+    bin = sql("""select t1.name from `tabBin` t1, tabItem t2 where t1.item_code = t2.name and ifnull(has_serial_no, 'No') = 'Yes'""")
+    for d in bin:
+        get_obj('Bin', d[0]).update_entries_after(posting_date = '2000-01-01', posting_time = '12:00')
+        sql("commit")
+        sql("start transaction")
+
diff --git a/erpnext/production/doctype/workstation/workstation.txt b/erpnext/production/doctype/workstation/workstation.txt
index bb7cc21..dd0868d 100644
--- a/erpnext/production/doctype/workstation/workstation.txt
+++ b/erpnext/production/doctype/workstation/workstation.txt
@@ -5,16 +5,19 @@
 	{
 		'creation': '2010-08-08 17:09:31',
 		'docstatus': 0,
-		'modified': '2011-01-04 13:40:42',
-		'modified_by': 'rahul@webnotestech.com',
+		'modified': '2011-11-24 14:34:41',
+		'modified_by': 'Administrator',
 		'owner': 'Administrator'
 	},
 
 	# These values are common for all DocType
 	{
+		'_last_update': '1322125389',
+		'allow_email': 0,
 		'allow_trash': 1,
 		'autoname': 'field:workstation_name',
 		'colour': 'White:FFF',
+		'default_print_format': 'Standard',
 		'doctype': 'DocType',
 		'document_type': 'Master',
 		'module': 'Production',
@@ -22,7 +25,7 @@
 		'section_style': 'Simple',
 		'server_code_error': ' ',
 		'show_in_menu': 0,
-		'version': 11
+		'version': 13
 	},
 
 	# These values are common for all DocField
@@ -55,7 +58,6 @@
 		'cancel': 1,
 		'create': 1,
 		'doctype': 'DocPerm',
-		'idx': 1,
 		'permlevel': 0,
 		'role': 'System Manager',
 		'write': 1
@@ -64,7 +66,6 @@
 	# DocPerm
 	{
 		'doctype': 'DocPerm',
-		'idx': 2,
 		'permlevel': 1,
 		'role': 'System Manager'
 	},
@@ -74,7 +75,6 @@
 		'cancel': 1,
 		'create': 1,
 		'doctype': 'DocPerm',
-		'idx': 3,
 		'permlevel': 0,
 		'role': 'Production User',
 		'write': 1
@@ -85,7 +85,6 @@
 		'cancel': 1,
 		'create': 1,
 		'doctype': 'DocPerm',
-		'idx': 4,
 		'permlevel': 0,
 		'role': 'Production User',
 		'write': 1
@@ -94,7 +93,6 @@
 	# DocPerm
 	{
 		'doctype': 'DocPerm',
-		'idx': 5,
 		'permlevel': 1,
 		'role': 'Production Manager'
 	},
@@ -102,7 +100,6 @@
 	# DocPerm
 	{
 		'doctype': 'DocPerm',
-		'idx': 6,
 		'permlevel': 1,
 		'role': 'Production User'
 	},
@@ -112,7 +109,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'trash_reason',
 		'fieldtype': 'Small Text',
-		'idx': 1,
 		'label': 'Trash Reason',
 		'oldfieldname': 'trash_reason',
 		'oldfieldtype': 'Small Text',
@@ -124,7 +120,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'workstation_name',
 		'fieldtype': 'Data',
-		'idx': 2,
 		'label': 'Workstation Name',
 		'oldfieldname': 'workstation_name',
 		'oldfieldtype': 'Data',
@@ -137,7 +132,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'warehouse',
 		'fieldtype': 'Link',
-		'idx': 3,
 		'label': 'Warehouse',
 		'oldfieldname': 'warehouse',
 		'oldfieldtype': 'Link',
@@ -151,7 +145,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'description',
 		'fieldtype': 'Text',
-		'idx': 4,
 		'label': 'Description',
 		'oldfieldname': 'description',
 		'oldfieldtype': 'Text',
@@ -165,7 +158,6 @@
 		'fieldname': 'capacity',
 		'fieldtype': 'Data',
 		'hidden': 1,
-		'idx': 5,
 		'label': 'Capacity',
 		'oldfieldname': 'capacity',
 		'oldfieldtype': 'Data',
@@ -179,7 +171,6 @@
 		'fieldname': 'capacity_units',
 		'fieldtype': 'Select',
 		'hidden': 1,
-		'idx': 6,
 		'label': 'Capacity Units',
 		'oldfieldname': 'capacity_units',
 		'oldfieldtype': 'Select',
@@ -194,7 +185,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'hour_rate_labour',
 		'fieldtype': 'Currency',
-		'idx': 7,
 		'label': 'Hour Rate Labour',
 		'oldfieldname': 'hour_rate_labour',
 		'oldfieldtype': 'Currency',
@@ -206,7 +196,6 @@
 	{
 		'doctype': 'DocField',
 		'fieldtype': 'Section Break',
-		'idx': 8,
 		'label': 'Over Heads',
 		'oldfieldtype': 'Section Break',
 		'permlevel': 0
@@ -217,7 +206,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'hour_rate_electricity',
 		'fieldtype': 'Currency',
-		'idx': 9,
 		'label': 'Hour Rate Electricity',
 		'oldfieldname': 'hour_rate_electricity',
 		'oldfieldtype': 'Currency',
@@ -229,7 +217,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'hour_rate_consumable',
 		'fieldtype': 'Currency',
-		'idx': 10,
 		'label': 'Hour Rate Consumable',
 		'oldfieldname': 'hour_rate_consumable',
 		'oldfieldtype': 'Currency',
@@ -241,7 +228,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'hour_rate_rent',
 		'fieldtype': 'Currency',
-		'idx': 11,
 		'label': 'Hour Rate Rent',
 		'oldfieldname': 'hour_rate_rent',
 		'oldfieldtype': 'Currency',
@@ -253,7 +239,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'overhead',
 		'fieldtype': 'Currency',
-		'idx': 12,
 		'label': 'Overhead',
 		'oldfieldname': 'overhead',
 		'oldfieldtype': 'Currency',
@@ -264,7 +249,6 @@
 	{
 		'doctype': 'DocField',
 		'fieldtype': 'Section Break',
-		'idx': 13,
 		'label': 'Hour Rate',
 		'oldfieldtype': 'Section Break',
 		'permlevel': 0
@@ -275,7 +259,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'hour_rate',
 		'fieldtype': 'Currency',
-		'idx': 14,
 		'label': 'Hour Rate',
 		'oldfieldname': 'hour_rate',
 		'oldfieldtype': 'Currency',
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index 9930bf4..4504191 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -34,9 +34,9 @@
 	'customer_name'     :  details and details[0]['customer_name'] or ''
       }
       #get primary contact details(this is done separately coz. , if join query used & no primary contact thn it would not be able to fetch customer details)
-      contact_det = sql("select contact_name, contact_no, email_id from `tabContact` where customer_name='%s' and is_customer=1 and is_primary_contact='Yes' and docstatus!=2" %(self.doc.customer), as_dict = 1)
+      contact_det = sql("select contact_name, phone, email_id from `tabContact` where customer_name='%s' and is_customer=1 and is_primary_contact=1 and docstatus!=2" %(self.doc.customer), as_dict = 1)
       ret['contact_person'] = contact_det and contact_det[0]['contact_name'] or ''
-      ret['contact_no'] = contact_det and contact_det[0]['contact_no'] or ''
+      ret['contact_no'] = contact_det and contact_det[0]['phone'] or ''
       ret['email_id'] = contact_det and contact_det[0]['email_id'] or ''    
       return ret
     else:
diff --git a/erpnext/sandbox/test_stock_reco.py b/erpnext/sandbox/test_stock_reco.py
new file mode 100644
index 0000000..bcde49e
--- /dev/null
+++ b/erpnext/sandbox/test_stock_reco.py
@@ -0,0 +1,94 @@
+import unittest
+
+import webnotes
+import webnotes.profile
+webnotes.user = webnotes.profile.Profile()
+
+
+from webnotes.model.doc import Document
+from webnotes.model.code import get_obj
+from webnotes.utils import cstr, flt
+from webnotes.model.doclist import getlist
+sql = webnotes.conn.sql
+
+from sandbox.testdata.masters import *
+from sandbox.testdata.sle_data import sle, bin
+from sandbox.testdata.stock_reco import *
+#----------------------------------------------------------
+
+
+class TestStockEntry(unittest.TestCase):
+	def assertDoc(self, lst):
+		"""assert all values"""
+		for d in lst:
+			cl, vl = [], []
+			for k in d.keys():
+				if k!='doctype':
+					cl.append('%s=%s' % (k, '%s'))
+					vl.append(d[k])
+
+			self.assertTrue(sql("select name from `tab%s` where %s limit 1" % (d['doctype'], ' and '.join(cl)), vl))
+
+	#===========================================================================
+	def setUp(self):
+		print "====================================="
+		webnotes.conn.begin()		
+		create_master_records()
+		print 'Master Data Created'
+		
+		for d in sle:
+			d.save(1)
+		print "Existing SLE created"
+		
+		bin.save(1)
+		
+		sreco.save(1)
+		print "Stock Reco saved"
+		
+	#===========================================================================
+	def test_diff_in_both(self):
+		reco = get_obj('Stock Reconciliation', sreco.name)
+		reco.doc.docstatus = 1
+		reco.doc.save()
+		reco.validate()
+		reco.on_submit()
+		print "Stock Reco submitted"
+		
+		print "Checking stock ledger entry........."
+		self.assertDoc(self.get_expected_sle('diff_in_both'))
+
+	#===========================================================================
+	def tearDown(self):
+		webnotes.conn.rollback()
+		
+	# Expected Result Set
+	#===================================================================================================
+	def get_expected_sle(self, action):
+		expected_sle = {
+			'diff_in_both': [{
+							'doctype': 'Stock Ledger Entry',
+							'item_code':'it',
+							'warehouse':'wh1', 
+							'voucher_type': 'Stock Reconciliation',
+							'voucher_no': sreco.name,
+							'actual_qty': 15,
+							'bin_aqat': 20,
+							'valuation_rate': 150,
+							#'stock_value': 3000,
+							'is_cancelled': 'No'
+						},{
+							'doctype': 'Stock Ledger Entry',
+							'posting_date': '2011-09-10',
+							'posting_time': '15:00',
+							'item_code': 'it',
+							'warehouse': 'wh1',
+							'actual_qty': 20,
+							'incoming_rate': 200,
+							'bin_aqat': 40,
+							'valuation_rate': 175,
+							#'stock_value': 4500,
+							'is_cancelled': 'No'
+						}
+						]
+		}
+		return expected_sle[action]
diff --git a/erpnext/sandbox/testdata/sle_data.py b/erpnext/sandbox/testdata/sle_data.py
new file mode 100644
index 0000000..eab0376
--- /dev/null
+++ b/erpnext/sandbox/testdata/sle_data.py
@@ -0,0 +1,85 @@
+from webnotes.model.doc import Document
+
+# Existing SLE data
+#---------------------------
+
+sle = [
+	Document(
+		fielddata = {
+			'doctype': 'Stock Ledger Entry',
+			'name': 'sle1',
+			'posting_date': '2011-09-01',
+			'posting_time': '12:00',
+			'item_code': 'it',
+			'warehouse': 'wh1',
+			'actual_qty': 10,
+			'incoming_rate': 100,
+			'bin_aqat': 10,
+			'valuation_rate': 100,
+			'fcfs_stack': '',
+			'stock_value': 1000,
+			'is_cancelled': 'No'			
+		}
+	),
+		Document(
+		fielddata = {
+			'doctype': 'Stock Ledger Entry',
+			'name': 'sle2',
+			'posting_date': '2011-09-01',
+			'posting_time': '12:00',
+			'item_code': 'it',
+			'warehouse': 'wh1',
+			'actual_qty': -5,
+			'incoming_rate': 100,
+			'bin_aqat': 5,
+			'valuation_rate': 100,
+			'fcfs_stack': '',
+			'stock_value': 500,
+			'is_cancelled': 'No'
+		}
+	),
+	Document(
+		fielddata = {
+			'doctype': 'Stock Ledger Entry',
+			'name': 'sle3',
+			'posting_date': '2011-09-10',
+			'posting_time': '15:00',
+			'item_code': 'it',
+			'warehouse': 'wh1',
+			'actual_qty': 20,
+			'incoming_rate': 200,
+			'bin_aqat': 25,
+			'valuation_rate': 180,
+			'fcfs_stack': '',
+			'stock_value': 4500,
+			'is_cancelled': 'No'			
+		}
+	),
+	Document(
+		fielddata = {
+			'doctype': 'Stock Ledger Entry',
+			'name': 'sle4',
+			'posting_date': '2011-09-15',
+			'posting_time': '09:30',
+			'item_code': 'it',
+			'warehouse': 'wh1',
+			'actual_qty': -5,
+			'incoming_rate': 180,
+			'bin_aqat': 20,
+			'valuation_rate': 180,
+			'fcfs_stack': '',
+			'stock_value': 3600,
+			'is_cancelled': 'No'			
+		}
+	)
+]
+
+bin = Document(
+	fielddata = {
+		'doctype': 'Bin',
+		'name': 'bin01',
+		'item_code': 'it',
+		'warehouse': 'wh1',
+		'actual_qty': 20,
+	}
+)
diff --git a/erpnext/sandbox/testdata/stock_reco.py b/erpnext/sandbox/testdata/stock_reco.py
new file mode 100644
index 0000000..efcbbc5
--- /dev/null
+++ b/erpnext/sandbox/testdata/stock_reco.py
@@ -0,0 +1,43 @@
+from webnotes.model.doc import Document
+
+# Stock Reconciliation
+#---------------------------
+
+sreco = Document(
+		fielddata = {
+			'doctype': 'Stock Reconciliation',
+			'name': 'sreco',
+			'reconciliation_date': '2011-09-08',
+			'reconciliation_time': '20:00',
+		}
+	)
+
+# diff in both
+csv_data1 = [
+	['Item', 'Warehouse', 'Quantity', 'Rate'],
+	['it', 'wh1', 20, 150]
+]
+
+# diff in qty, no rate
+csv_data2 = [
+	['Item', 'Warehouse', 'Quantity'],
+	['it', 'wh1', 20]
+]
+
+# diff in rate, no qty
+csv_data3 = [
+	['Item', 'Warehouse', 'Rate'],
+	['it', 'wh1', 200]
+]
+
+# diff in rate, same qty
+csv_data4 = [
+	['Item', 'Warehouse', 'Quantity', 'Rate'],
+	['it', 'wh1', 5, 200]
+]
+
+# no diff
+csv_data1 = [
+	['Item', 'Warehouse', 'Quantity', 'Rate'],
+	['it', 'wh1', 5, 100]
+]
diff --git a/erpnext/setup/doctype/email_digest/email_digest.coffee b/erpnext/setup/doctype/email_digest/email_digest.coffee
deleted file mode 100644
index 1b17d5b..0000000
--- a/erpnext/setup/doctype/email_digest/email_digest.coffee
+++ /dev/null
@@ -1,101 +0,0 @@
-content_items = ['Sales','Expenses','Bank Balance','Activity']
-
-# make a grid with items and columns of checkboxes
-# Parameters:
-#   parent
-# 	label (main heading)
-#	items = [] (rows)
-#	columns = [] (columns of checks)
-#	widths
-#	description
-
-class CheckGrid
-	constructor: (@args) ->
-		$.extend @, args
-		@wrapper = $a @parent, 'div', 'check-grid round'
-		@render()
-		
-	render: ->
-		$a @wrapper, 'h3', 'check-grid-title', null, @label
-		
-		if @description
-			$a @wrapper, 'div', 'help-box', null, @description
-		
-		@tab = make_table @wrapper, @items.length + 1, @columns.length, '100%', @widths
-		@checks = {}
-
-		# render heads
-		for i in [0..@columns.length-1]
-			$($td(@tab, 0, i))
-				.addClass('check-grid-head gradient')
-				.html @columns[i]
-
-		@render_rows()
-	
-	render_rows: ->
-		# render rows
-		for i in [0..@items.length-1]
-			$td(@tab, i+1, 0).innerHTML = @items[i]
-			
-			# render checkboxes for this row
-			@checks[@items[i]] = {}
-			for c in [1..@columns.length-1]
-				check = $a_input $td(@tab, i+1, c), 'checkbox'
-				
-				# tag keys to checkbox
-				check.item = @items[i]
-				check.column = @columns[c]
-				
-				# add in my checks
-				@checks[@items[i]][@columns[c]] = check
-	
-	# get the values of the checkbox in a double dict
-	get: =>
-		val = {}
-		for item in keys @checks
-			for column in keys @checks[item]
-				check = @checks[item][column]
-				val[check.item] or= {}
-				val[check.item][check.column] = if check.checked then 1 else 0
-		val
-	
-	# set the values of the grid
-	set: (val) =>
-		for item in keys @checks
-			for column in keys @checks[item]
-				if val[item][column]
-					@checks[item][column] .checked = val[item][column] 
-		return
-
-# attach it to onload
-cx = cur_frm.cscript
-cx.onload = (doc, dt, dn) ->
-
-	# make the content grid
-	cx.content_grid = new CheckGrid 
-		parent: cur_frm.fields_dict.Body.wrapper
-		label: 'Email Settings'
-		items: content_items
-		columns: ['Item','Daily','Weekly']
-		widths: ['60%', '20%', '20%']
-		description: 'Select items to be compiled for Email Digest'
-
-	# make the email grid
-	cx.email_grid = new CheckGrid 
-		parent: cur_frm.fields_dict.Body.wrapper
-		label: 'Send To'
-		items: ['test1@erpnext', 'test2@erpnext']
-		columns: ['Email','Daily','Weekly']
-		widths: ['60%', '20%', '20%']
-		description: 'Select who gets daily and weekly mails'
-		
-	cx.content_grid.set JSON.parse doc.content_config if doc.content_config
-	cx.email_grid.set JSON.parse doc.email_config if doc.email_config
-	
-	return
-
-# update the data before sending
-cx.validate = (doc, dt, dn) ->
-	doc.content_config = JSON.stringify cx.content_grid.get()
-	doc.email_config = JSON.stringify cx.email_grid.get()
-		
\ No newline at end of file
diff --git a/erpnext/setup/doctype/email_digest/email_digest.css b/erpnext/setup/doctype/email_digest/email_digest.css
deleted file mode 100644
index f61dacc..0000000
--- a/erpnext/setup/doctype/email_digest/email_digest.css
+++ /dev/null
@@ -1,18 +0,0 @@
-
-div.check-grid {
-	margin: 17px;
-}
-
-div.check-grid table {
-	border-collapse: collapse;
-}
-
-div.check-grid table td {
-	padding: 3px;
-	border: 1px solid #aaa;
-}
-
-td.check-grid-head {
-	font-weight: bold;
-	text-align: center;
-}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/email_digest/email_digest.js b/erpnext/setup/doctype/email_digest/email_digest.js
deleted file mode 100644
index ddb13f4..0000000
--- a/erpnext/setup/doctype/email_digest/email_digest.js
+++ /dev/null
@@ -1,108 +0,0 @@
-(function() {
-  var CheckGrid, content_items, cx;
-  var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
-  content_items = ['Sales', 'Expenses', 'Bank Balance', 'Activity'];
-  CheckGrid = (function() {
-    function CheckGrid(args) {
-      this.args = args;
-      this.set = __bind(this.set, this);
-      this.get = __bind(this.get, this);
-      $.extend(this, args);
-      this.wrapper = $a(this.parent, 'div', 'check-grid round');
-      this.render();
-    }
-    CheckGrid.prototype.render = function() {
-      var i, _ref;
-      $a(this.wrapper, 'h3', 'check-grid-title', null, this.label);
-      if (this.description) {
-        $a(this.wrapper, 'div', 'help-box', null, this.description);
-      }
-      this.tab = make_table(this.wrapper, this.items.length + 1, this.columns.length, '100%', this.widths);
-      this.checks = {};
-      for (i = 0, _ref = this.columns.length - 1; 0 <= _ref ? i <= _ref : i >= _ref; 0 <= _ref ? i++ : i--) {
-        $($td(this.tab, 0, i)).addClass('check-grid-head gradient').html(this.columns[i]);
-      }
-      return this.render_rows();
-    };
-    CheckGrid.prototype.render_rows = function() {
-      var c, check, i, _ref, _results;
-      _results = [];
-      for (i = 0, _ref = this.items.length - 1; 0 <= _ref ? i <= _ref : i >= _ref; 0 <= _ref ? i++ : i--) {
-        $td(this.tab, i + 1, 0).innerHTML = this.items[i];
-        this.checks[this.items[i]] = {};
-        _results.push((function() {
-          var _ref2, _results2;
-          _results2 = [];
-          for (c = 1, _ref2 = this.columns.length - 1; 1 <= _ref2 ? c <= _ref2 : c >= _ref2; 1 <= _ref2 ? c++ : c--) {
-            check = $a_input($td(this.tab, i + 1, c), 'checkbox');
-            check.item = this.items[i];
-            check.column = this.columns[c];
-            _results2.push(this.checks[this.items[i]][this.columns[c]] = check);
-          }
-          return _results2;
-        }).call(this));
-      }
-      return _results;
-    };
-    CheckGrid.prototype.get = function() {
-      var check, column, item, val, _i, _j, _len, _len2, _name, _ref, _ref2;
-      val = {};
-      _ref = keys(this.checks);
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        item = _ref[_i];
-        _ref2 = keys(this.checks[item]);
-        for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
-          column = _ref2[_j];
-          check = this.checks[item][column];
-          val[_name = check.item] || (val[_name] = {});
-          val[check.item][check.column] = check.checked ? 1 : 0;
-        }
-      }
-      return val;
-    };
-    CheckGrid.prototype.set = function(val) {
-      var column, item, _i, _j, _len, _len2, _ref, _ref2;
-      _ref = keys(this.checks);
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        item = _ref[_i];
-        _ref2 = keys(this.checks[item]);
-        for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
-          column = _ref2[_j];
-          if (val[item][column]) {
-            this.checks[item][column].checked = val[item][column];
-          }
-        }
-      }
-    };
-    return CheckGrid;
-  })();
-  cx = cur_frm.cscript;
-  cx.onload = function(doc, dt, dn) {
-    cx.content_grid = new CheckGrid({
-      parent: cur_frm.fields_dict.Body.wrapper,
-      label: 'Email Settings',
-      items: content_items,
-      columns: ['Item', 'Daily', 'Weekly'],
-      widths: ['60%', '20%', '20%'],
-      description: 'Select items to be compiled for Email Digest'
-    });
-    cx.email_grid = new CheckGrid({
-      parent: cur_frm.fields_dict.Body.wrapper,
-      label: 'Send To',
-      items: ['test1@erpnext', 'test2@erpnext'],
-      columns: ['Email', 'Daily', 'Weekly'],
-      widths: ['60%', '20%', '20%'],
-      description: 'Select who gets daily and weekly mails'
-    });
-    if (doc.content_config) {
-      cx.content_grid.set(JSON.parse(doc.content_config));
-    }
-    if (doc.email_config) {
-      cx.email_grid.set(JSON.parse(doc.email_config));
-    }
-  };
-  cx.validate = function(doc, dt, dn) {
-    doc.content_config = JSON.stringify(cx.content_grid.get());
-    return doc.email_config = JSON.stringify(cx.email_grid.get());
-  };
-}).call(this);
diff --git a/erpnext/setup/doctype/features_setup/features_setup.txt b/erpnext/setup/doctype/features_setup/features_setup.txt
index 909882e..d0f02d5 100644
--- a/erpnext/setup/doctype/features_setup/features_setup.txt
+++ b/erpnext/setup/doctype/features_setup/features_setup.txt
@@ -5,14 +5,14 @@
 	{
 		'creation': '2011-09-07 11:59:05',
 		'docstatus': 0,
-		'modified': '2011-10-05 10:50:17',
+		'modified': '2011-12-06 18:48:53',
 		'modified_by': 'Administrator',
 		'owner': 'Administrator'
 	},
 
 	# These values are common for all DocType
 	{
-		'_last_update': '1317790484',
+		'_last_update': '1323176623',
 		'colour': 'White:FFF',
 		'default_print_format': 'Standard',
 		'doctype': 'DocType',
@@ -22,7 +22,7 @@
 		'name_case': 'Title Case',
 		'section_style': 'Simple',
 		'show_in_menu': 1,
-		'version': 21
+		'version': 24
 	},
 
 	# These values are common for all DocField
@@ -215,6 +215,39 @@
 	{
 		'doctype': 'DocField',
 		'fieldtype': 'Section Break',
+		'label': 'Accounts'
+	},
+
+	# DocField
+	{
+		'colour': 'White:FFF',
+		'description': 'Check if you need automatic recurring invoices. After submitting any sales invoice, Recurring section will be visible.',
+		'doctype': 'DocField',
+		'fieldname': 'fs_recurring_invoice',
+		'fieldtype': 'Check',
+		'label': 'Recurring Invoice'
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldtype': 'Column Break'
+	},
+
+	# DocField
+	{
+		'colour': 'White:FFF',
+		'description': 'To enable <b>Point of Sale</b> features',
+		'doctype': 'DocField',
+		'fieldname': 'fs_pos',
+		'fieldtype': 'Check',
+		'label': 'Point of Sale'
+	},
+
+	# DocField
+	{
+		'doctype': 'DocField',
+		'fieldtype': 'Section Break',
 		'label': 'Production'
 	},
 
@@ -246,16 +279,6 @@
 
 	# DocField
 	{
-		'colour': 'White:FFF',
-		'description': 'To enable <b>Point of Sale</b> features',
-		'doctype': 'DocField',
-		'fieldname': 'fs_pos',
-		'fieldtype': 'Check',
-		'label': 'Point of Sale'
-	},
-
-	# DocField
-	{
 		'doctype': 'DocField',
 		'fieldtype': 'Section Break',
 		'label': 'Miscelleneous'
diff --git a/erpnext/setup/page/setup/setup.js b/erpnext/setup/page/setup/setup.js
index 7c1245a..92ba9db 100644
--- a/erpnext/setup/page/setup/setup.js
+++ b/erpnext/setup/page/setup/setup.js
@@ -169,7 +169,9 @@
     ['Manage Users',2,'My Company','','Add / remove users and manage their roles'],
     ['Web Forms',2,'Webforms','', 'Code to embed forms in yor website'],
     ['Permissions Manager',2,'Permission Engine','', 'Manage all permissions from one tool (beta)'],
-    ['Property Setter',1,'Property Setter','', 'Customize properties of a Form (DocType) or Field'],
+    //['Property Setter',1,'Property Setter','', 'Customize properties of a Form (DocType) or Field'],
+    ['Customize Form View',3,'DocLayer','', 'Customize properties of a Form (DocType) or Field'],
+	['Print Formats', 1, 'Print Format', '', 'Manage Print Formats'],
     ['Letter Head',1,'Letter Head','','Manage different letter heads for Prints'],
     ['SMS Settings',3,'SMS Settings','','Integrate your personalized SMS gateway which support http web service'],
     ['SMS Center',3,'SMS Center','','Send mass sms to your leads, contacts and partners'],
@@ -181,6 +183,7 @@
     ['Print Heading',1,'Print Heading','','Manage headings for printing transactions'],
     ['Term',1,'Term','','Manage template of standard Terms for order / invoices etc'],
     ['Currency',1,'Currency','','Manage list of currencies'],
+    ['Address',1,'Address','','Manage Address of customers, suppliers'],
     ['Country',1,'Country','','Country master'],
     ['State',1,'State','','State master'],
     ['Rename Tool',3,'Rename Tool','','Rename a record'],
diff --git a/erpnext/startup/startup.js b/erpnext/startup/startup.js
index fcb097b..291265b 100644
--- a/erpnext/startup/startup.js
+++ b/erpnext/startup/startup.js
@@ -690,6 +690,9 @@
 	},
 	'fs_pos': {
 		'Receivable Voucher': {'fields':['is_pos']}
+	},
+	'fs_recurring_invoice': {
+		'Receivable Voucher': {'fields': ['Recurring Invoice']}
 	}
 }
 
diff --git a/erpnext/stock/doctype/bin/bin.py b/erpnext/stock/doctype/bin/bin.py
index e3af0a2..bb1101e 100644
--- a/erpnext/stock/doctype/bin/bin.py
+++ b/erpnext/stock/doctype/bin/bin.py
@@ -146,7 +146,7 @@
 			in_rate = flt(sql("select ifnull(avg(purchase_rate), 0) from `tabSerial No` where name in (%s)" % (serial_nos))[0][0])
 
 		if in_rate and val_rate == 0: # First entry
-			val_rate = in_rate		
+			val_rate = in_rate
 		# val_rate is same as previous entry if val_rate is negative
 		# Otherwise it will be calculated as per moving average
 		elif opening_qty + actual_qty > 0 and ((opening_qty * val_rate) + (actual_qty * in_rate)) > 0:
diff --git a/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.py b/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.py
index 2b828f9..c791e86 100644
--- a/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.py
+++ b/erpnext/stock/doctype/landed_cost_wizard/landed_cost_wizard.py
@@ -166,7 +166,7 @@
 			  tax_amount = flt(rate) * (flt(ocd[row-1].total_tax_amount)+flt(ocd[row-1].total_amount)) / 100
 			elif ocd[row-1].add_deduct_tax == 'Deduct':
 			  tax_amount = flt(rate) * (flt(ocd[row-1].total_tax_amount)-flt(ocd[row-1].total_amount)) / 100
-			  
+		
 		return tax_amount  
 
 	def add_deduct_taxes(self, ocd, oc, tax_amount, total, prev_total, item_tax):
@@ -202,7 +202,8 @@
 			for d in getlist(pr_obj.doclist, 'purchase_receipt_details'):
 				if flt(d.qty):
 					d.valuation_rate = (flt(d.purchase_rate) + (flt(d.rm_supp_cost)/flt(d.qty)) + (flt(d.item_tax_amount)/flt(d.qty))) / flt(d.conversion_factor)
-					d.save()	
+					d.save()
+					self.update_serial_no(d.serial_no, d.valuation_rate)
 				sql("update `tabStock Ledger Entry` set incoming_rate = '%s' where voucher_detail_no = '%s'"%(flt(d.valuation_rate), d.name))
 				
 				bin = sql("select t1.name, t2.posting_date, t2.posting_time from `tabBin` t1, `tabStock Ledger Entry` t2 where t2.voucher_detail_no = '%s' and t2.item_code = t1.item_code and t2.warehouse = t1.warehouse LIMIT 1" % d.name)
@@ -211,6 +212,13 @@
 				if bin and bin[0][0]:
 					obj = get_obj('Bin', bin[0][0]).update_entries_after(bin[0][1], bin[0][2])
 
+	
+	def update_serial_no(self, sr_no, rate):
+		""" update valuation rate in serial no"""
+		sr_no = sr_no.split('\n')
+		for d in sr_no:
+			sql("update `tabSerial No` set purchase_rate = %s where name = %s", (rate, d))
+
 				
 	def update_landed_cost(self):
 		""" 
diff --git a/erpnext/stock/doctype/purchase_receipt_detail/purchase_receipt_detail.txt b/erpnext/stock/doctype/purchase_receipt_detail/purchase_receipt_detail.txt
index 733e864..9fa0c40 100755
--- a/erpnext/stock/doctype/purchase_receipt_detail/purchase_receipt_detail.txt
+++ b/erpnext/stock/doctype/purchase_receipt_detail/purchase_receipt_detail.txt
@@ -5,7 +5,7 @@
 	{
 		'creation': '2010-08-08 17:09:16',
 		'docstatus': 0,
-		'modified': '2011-12-08 13:00:59',
+		'modified': '2011-12-08 17:28:34',
 		'modified_by': 'Administrator',
 		'owner': 'Administrator'
 	},
@@ -21,7 +21,7 @@
 		'section_style': 'Tray',
 		'server_code_error': ' ',
 		'show_in_menu': 0,
-		'version': 60
+		'version': 69
 	},
 
 	# These values are common for all DocField
@@ -117,23 +117,6 @@
 
 	# DocField
 	{
-		'colour': 'White:FFF',
-		'default': '0.00',
-		'doctype': 'DocField',
-		'fieldname': 'purchase_rate',
-		'fieldtype': 'Currency',
-		'label': 'Rate (Default Curr.)',
-		'oldfieldname': 'purchase_rate',
-		'oldfieldtype': 'Currency',
-		'permlevel': 0,
-		'print_hide': 1,
-		'reqd': 1,
-		'trigger': 'Client',
-		'width': '100px'
-	},
-
-	# DocField
-	{
 		'default': '0.00',
 		'doctype': 'DocField',
 		'fieldname': 'qty',
@@ -148,6 +131,32 @@
 
 	# DocField
 	{
+		'doctype': 'DocField',
+		'fieldname': 'purchase_ref_rate',
+		'fieldtype': 'Currency',
+		'label': 'Ref Rate *',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
+		'colour': 'White:FFF',
+		'default': '0.00',
+		'doctype': 'DocField',
+		'fieldname': 'purchase_rate',
+		'fieldtype': 'Currency',
+		'label': 'Rate *(Default Curr.)',
+		'oldfieldname': 'purchase_rate',
+		'oldfieldtype': 'Currency',
+		'permlevel': 0,
+		'print_hide': 1,
+		'reqd': 1,
+		'trigger': 'Client',
+		'width': '100px'
+	},
+
+	# DocField
+	{
 		'default': '0.00',
 		'doctype': 'DocField',
 		'fieldname': 'amount',
@@ -189,6 +198,15 @@
 
 	# DocField
 	{
+		'doctype': 'DocField',
+		'fieldname': 'import_ref_rate',
+		'fieldtype': 'Currency',
+		'label': 'Ref Rate ',
+		'permlevel': 0
+	},
+
+	# DocField
+	{
 		'colour': 'White:FFF',
 		'default': '0.00',
 		'doctype': 'DocField',
@@ -206,15 +224,6 @@
 	# DocField
 	{
 		'doctype': 'DocField',
-		'fieldname': 'ref_rate',
-		'fieldtype': 'Currency',
-		'label': 'Ref Rate',
-		'permlevel': 0
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
 		'fieldname': 'import_amount',
 		'fieldtype': 'Currency',
 		'label': 'Amount',
@@ -546,4 +555,4 @@
 		'permlevel': 0,
 		'print_hide': 1
 	}
-]
\ No newline at end of file
+]
diff --git a/erpnext/stock/doctype/stock_ledger/stock_ledger.py b/erpnext/stock/doctype/stock_ledger/stock_ledger.py
index 5165cc9..0970b78 100644
--- a/erpnext/stock/doctype/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/doctype/stock_ledger/stock_ledger.py
@@ -93,27 +93,27 @@
 	# ---------------------
 	def set_pur_serial_no_values(self, obj, serial_no, d, s, new_rec):
 		item_details = sql("select item_group, warranty_period from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now()) " %(d.item_code), as_dict=1)
-		s.purchase_document_type=	 obj.doc.doctype
-		s.purchase_document_no	=	 obj.doc.name
-		s.purchase_date		=	 obj.doc.posting_date
-		s.purchase_time		=	 obj.doc.posting_time
-		s.purchase_rate		=	 d.purchase_rate or d.incoming_rate
-		s.item_code		=	 d.item_code
-		s.brand			=	 d.brand
-		s.description		=	 d.description
-		s.item_group		=	 item_details and item_details[0]['item_group'] or ''
-		s.warranty_period	=	 item_details and item_details[0]['warranty_period'] or 0
-		s.supplier		=	 obj.doc.supplier
-		s.supplier_name		=	 obj.doc.supplier_name
-		s.supplier_address	=	 obj.doc.supplier_address
-		s.warehouse		=	 d.warehouse or d.t_warehouse
-		s.docstatus		=	 0
-		s.status		=	 'In Store'
-		s.modified		=	 nowdate()
-		s.modified_by		=	 session['user']
-		s.serial_no		=	 serial_no
-		s.fiscal_year		=	 obj.doc.fiscal_year
-		s.company		=	 obj.doc.company
+		s.purchase_document_type	=	obj.doc.doctype
+		s.purchase_document_no		=	obj.doc.name
+		s.purchase_date				=	obj.doc.posting_date
+		s.purchase_time				=	obj.doc.posting_time
+		s.purchase_rate				=	d.valuation_rate or d.incoming_rate
+		s.item_code					=	d.item_code
+		s.brand						=	d.brand
+		s.description				=	d.description
+		s.item_group				=	item_details and item_details[0]['item_group'] or ''
+		s.warranty_period			=	item_details and item_details[0]['warranty_period'] or 0
+		s.supplier					=	obj.doc.supplier
+		s.supplier_name				=	obj.doc.supplier_name
+		s.supplier_address			=	obj.doc.supplier_address
+		s.warehouse					=	d.warehouse or d.t_warehouse
+		s.docstatus					=	0
+		s.status					=	'In Store'
+		s.modified					=	nowdate()
+		s.modified_by				=	session['user']
+		s.serial_no					=	serial_no
+		s.fiscal_year				=	obj.doc.fiscal_year
+		s.company					=	obj.doc.company
 		s.save(new_rec)
 
 
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
index de89d80..2e428df 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
@@ -1,37 +1,7 @@
-cur_frm.cscript.onload = function(doc, cdt, cdn) {
-  cfn_set_fields(doc, cdt, cdn);
+cur_frm.cscript.refresh = function(doc) {	
+	if (doc.docstatus) hide_field('Steps');
 }
 
-cur_frm.cscript.refresh = function(doc, cdt, cdn) {
-  cfn_set_fields(doc, cdt, cdn);
+cur_frm.cscript['Download Template'] = function(doc, cdt, cdn) {
+	$c_obj_csv(make_doclist(cdt, cdn), 'get_template', '');
 }
-
-var cfn_set_fields = function(doc, cdt, cdn) {
-  refresh_field('remark');
-  refresh_field('next_step');
-  if (doc.docstatus == 0 && doc.next_step == 'Upload File and Save Document') 
-    doc.next_step = 'Validate Data';
-  
-  if (! doc.file_list)
-    doc.next_step = 'Upload File and Save Document'
-  
-  if (doc.next_step == 'Upload File and Save Document') {
-    //alert("Upload File and Save Document");
-    cur_frm.clear_tip();
-    cur_frm.set_tip("Please Enter Reconciliation Date and Attach CSV File with Columns in Following Sequence:-");
-    cur_frm.append_tip("Item Code , Warehouse , Qty , MAR");
-    hide_field("Validate Data");
-  }
-  if (doc.next_step == 'Validate Data') {
-    //alert("Validate Data");
-    cur_frm.clear_tip();
-    cur_frm.set_tip("Please Check Remarks");
-    unhide_field("Validate Data");
-  }
-  if (doc.next_step == 'Submit Document') {
-    //alert('Submit Document');
-    cur_frm.clear_tip();
-    cur_frm.set_tip("Please Submit the document.");
-    hide_field("Validate Data");
-  }
-}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index e133d6f..7b9d294 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -1,270 +1,23 @@
-# Please edit this list and import only required elements
 import webnotes
-
-from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
-from webnotes.model import db_exists
-from webnotes.model.doc import Document, addchild, removechild, getchildren, make_autoname, SuperDocType
-from webnotes.model.doclist import getlist, copy_doclist
-from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
-from webnotes import session, form, is_testing, msgprint, errprint
-
-set = webnotes.conn.set
+from webnotes.utils import cstr, flt, get_defaults, nowdate
+from webnotes import msgprint
+from webnotes.model.code import get_obj
 sql = webnotes.conn.sql
-get_value = webnotes.conn.get_value
-in_transaction = webnotes.conn.in_transaction
-convert_to_lists = webnotes.conn.convert_to_lists
 	
 # -----------------------------------------------------------------------------------------
 
-
 class DocType:
 	def __init__(self, doc, doclist=[]):
 		self.doc = doc
 		self.doclist = doclist
-		self.label = { 'item_code': 0 , 'warehouse': 1 , 'qty': 2, 'mar': 3,'stock_uom':4, 'actual_qty':5, 'diff': 6} # with mar
+		self.validated = 1
+		self.data = []
 
-	# autoname
-	#-----------------
-	def autoname(self):
-		 self.doc.name = make_autoname('SR/' + self.doc.fiscal_year + '/.######')
+	def get_template(self):
+		return [['Item Code', 'Warehouse', 'Quantity', 'Valuation Rate']]
 
-	# -----------------
-	# update next step
-	# -----------------
-	def update_next_step(self,next_step):
-		sql("update `tabStock Reconciliation` set next_step = '%s' where name = '%s'" % (next_step,self.doc.name))
-	
-
-	# -----------
-	# add remark
-	# -----------
-	def add_remark(self, text, next_step, first_time = 0):
-		if first_time:
-			sql("update `tabStock Reconciliation` set remark = '' where name = '%s'" % self.doc.name)
-		else:
-			sql("update `tabStock Reconciliation` set remark = concat(remark, '%s'), modified = '%s' where name = '%s'" % (text + "<br>", nowdate(), self.doc.name))
-		self.update_next_step(next_step)
-
-
-	# --------------
-	# validate item
-	# --------------
-	def validate_item(self, item, count, check_item = 1):
-		det = sql("select item_code, has_serial_no from `tabItem` where name = '%s'"% cstr(item), as_dict = 1)
-		if not det:
-			text = "Item: " + cstr(item) + " mentioned at Row No. " + cstr(count) + "does not exist in the system"
-			msgprint(text)
-			self.add_remark(text, 'Validate Data', 0)
-			check_item = 0
-		elif det and det[0]['has_serial_no'] == 'Yes':
-			text = "You cannot make Stock Reconciliation of items having serial no. You can directly upload serial no to update their inventory. Please remove Item Code : %s at Row No. %s" %(cstr(item), cstr(count))
-			msgprint(text)
-			self.add_remark(text, 'Validate Data', 0)
-			check_item = 0
-		return check_item
-
-
-	# -------------------
-	# validate warehouse
-	# -------------------
-	def validate_warehouse(self,wh,count, check_warehouse = 1):
-		if not sql("select name from `tabWarehouse` where name = '%s'" % cstr(wh)):
-			text = "Warehouse: " + cstr(wh) + " mentioned at Row No. " + cstr(count) + "does not exist in the system"
-			self.add_remark(text,'Validate Data',0)
-			check_warehouse = 0
-		return check_warehouse
-
-
-	# ---------------------------
-	# validate data of .csv file
-	# ---------------------------
-	def validate_data(self,stock):
-		self.add_remark('','Validate Data',1)
-
-		# check whether file uploaded
-		if not self.doc.file_list:
-			set(self.doc,'next_step','Upload File and Save Document')
-			msgprint("Please Attach File", raise_exception=1)
-
-		# validate item and warehouse
-		check_item,check_warehouse,count = 1, 1, 1
-		for s in stock:
-			count +=1
-			check_item = self.validate_item(s[self.label['item_code']],count) or 0
-			check_warehouse = self.validate_warehouse(s[self.label['warehouse']],count) or 0
-
-		if check_item and check_warehouse:
-			text = "Validation Completed Successfully..."
-			self.add_remark(text,'Submit Document',0)
-		return check_item and check_warehouse
-
-
-	# ------------------------------
-	# convert lines in .csv to list
-	# ------------------------------
-	def convert_into_list(self, stock, submit):
-		count, st_list = 1, []
-		for s in stock:
-			if submit and len(s) != 4:
-				msgprint("Data entered at Row No " + cstr(count) + " in Attachment File is not in correct format.", raise_exception=1)
-
-			l = [s[0].encode("ascii"), s[1].encode("ascii"), s[2].encode("ascii"), s[3].encode("ascii")]
-			st_list.append(l)
-			count += 1
-		return st_list
-
-	# ------------------
-	# get current stock
-	# ------------------
-	def get_current_stock(self, item_code, warehouse):
-		bin = sql("select name from `tabBin` where item_code = '%s' and warehouse = '%s'" % (item_code, warehouse))
-		prev_sle = bin and get_obj('Bin', bin[0][0]).get_prev_sle(self.doc.reconciliation_date,self.doc.reconciliation_time) or {}
-		stock_uom = sql("select stock_uom from `tabItem` where name = %s",item_code)
-		return {'actual_qty': prev_sle.get('bin_aqat', 0), 'stock_uom': stock_uom[0][0]}
-
-
-	# -----------
-	# update mar
-	# -----------
-	def update_mar(self, d, qty_diff):
-		"""
-			update item valuation in previous date and also on post date if no qty diff
-		"""
-		
-		self.update_entries_pre_date(d)
-		
-		if not flt(d[self.label['qty']]) and not flt(d[self.label['actual_qty']]):
-			# seems like a special condition when there is no actual quanitity but there is a rate, may be only for setting a rate!
-			self.make_sl_entry(1,d,1)
-			self.make_sl_entry(1,d,-1)
-		elif not qty_diff:
-			self.update_entries_post_date(d)
-				
-	# update valuation rate as csv file in all sle before reconciliation date
-	# ------------------------------------------------------------------------
-	def update_entries_pre_date(self, d):
-		mar = flt(d[self.label['mar']])		
-
-		# previous sle
-		prev_sle = sql("""
-			select name, fcfs_stack
-			from `tabStock Ledger Entry`
-			where item_code = %s
-			and warehouse = %s
-			and ifnull(is_cancelled, 'No') = 'No'
-			and timestamp(posting_date, posting_time) <= timestamp(%s, %s)
-			""", (d[self.label['item_code']], d[self.label['warehouse']], self.doc.reconciliation_date, self.doc.reconciliation_time))
-
-		for each in prev_sle:
-			# updated fifo stack
-			fstack = each[1] and [[i[0], mar] for i in eval(each[1])] or ''
-
-			# update incoming rate, valuation rate, stock value and fifo stack
-			sql("""update `tabStock Ledger Entry` 
-			set incoming_rate = %s, valuation_rate = %s, stock_value = bin_aqat*%s, fcfs_stack = %s 
-			where name = %s
-			""", (mar, mar, mar, cstr(fstack), each[0]))
-			
-				
-	# Update item valuation in all sle after the reconcliation date
-	# ---------------------------------------------------------
-	def update_entries_post_date(self, d):
-		bin = sql("select name from `tabBin` where item_code = '%s' and warehouse = '%s'" % (d[self.label['item_code']], d[self.label['warehouse']]))
-		bin_obj = get_obj('Bin', bin[0][0])
-
-		# update valuation in sle posted after reconciliation datetime
-		bin_obj.update_entries_after(posting_date = self.doc.reconciliation_date, posting_time = self.doc.reconciliation_time)
-
-	# --------------
-	# make sl entry
-	# --------------
-	def make_sl_entry(self, update_stock, stock, diff):
-		values = []
-		values.append({
-				'item_code'					: stock[self.label['item_code']],
-				'warehouse'					: stock[self.label['warehouse']],
-				'transaction_date'	 		: now(),
-				'posting_date'				: self.doc.reconciliation_date,
-				'posting_time'			 	: self.doc.reconciliation_time,
-				'voucher_type'			 	: self.doc.doctype,
-				'voucher_no'				: self.doc.name,
-				'voucher_detail_no'			: self.doc.name,
-				'actual_qty'				: flt(update_stock) * flt(diff),
-				'stock_uom'					: stock[self.label['stock_uom']],
-				'incoming_rate'				: stock[self.label['mar']] or 0,
-				'company'					: self.doc.company,
-				'fiscal_year'				: self.doc.fiscal_year,
-				'is_cancelled'			 	: (update_stock==1) and 'No' or 'Yes',
-				'batch_no'					: '',
-				'serial_no'					: ''
-		 })
-				
-		get_obj('Stock Ledger', 'Stock Ledger').update_stock(values)
-
-
-	# -----------------------
-	# get stock reco details
-	# -----------------------
-	def get_reconciliation_stock_details(self,submit = 0):
-		import csv 
-		stock = csv.reader(self.get_csv_file_data().splitlines())
-		stock = self.convert_into_list(stock, submit)
-		if stock[0][0] and stock[0][0].strip()=='Item Code':
-			stock.pop(0)		# remove the labels
-		check = self.validate_data(stock)
-		if not check:
-			return 0
-		return stock
-
-	# validate date and time
-	# ------------------------
-	def validate_datetime(self):
-		if not self.doc.reconciliation_date:
-			msgprint("Please Enter Reconciliation Date.", raise_exception=1)
-		if not self.doc.reconciliation_time:
-			msgprint("Please Enter Reconciliation Time.", raise_exception=1)
-
-
-
-	# ----------------------
-	# stock reconciliations
-	# ----------------------
-	def stock_reconciliations(self, submit = 0):
-		self.validate_datetime()
-
-		# get reco data
-		rec_stock_detail = self.get_reconciliation_stock_details(submit) or []
-		if not rec_stock_detail:
-			msgprint("Please Check Remarks", raise_exception=1)
-
-		count = 1
-		for stock in rec_stock_detail:
-			count += 1
-
-			# Get qty as per system
-			cur_stock_detail = self.get_current_stock(stock[self.label['item_code']],stock[self.label['warehouse']])
-			stock.append(cur_stock_detail['stock_uom'])
-			stock.append(cur_stock_detail['actual_qty'])
-
-			# Qty Diff between file and system
-			diff = flt(stock[self.label['qty']]) - flt(cur_stock_detail['actual_qty'])
-
-			# Update MAR
-			if not stock[self.label['mar']] == '~':
-				self.update_mar(stock, diff)
-			
-			# Make sl entry if qty differ
-			if diff:
-				self.make_sl_entry(submit, stock, diff)
-
-		if rec_stock_detail:
-			text = "Stock Reconciliation Completed Successfully..."
-			self.add_data_in_CSV(rec_stock_detail)
-			self.add_remark(text,'Completed', 0)
-
-	# Get csv data
-	#--------------------------
 	def get_csv_file_data(self):
+		"""Get csv data"""
 		filename = self.doc.file_list.split(',')
 		if not filename:
 			msgprint("Please Attach File. ", raise_exception=1)
@@ -274,37 +27,160 @@
 		
 		if not type(content) == str:
 			content = content.tostring()
+
 		return content
 
+	def convert_into_list(self, data):
+		"""Convert csv data into list"""
+		count = 1
+		for s in data:
+			if s[0].strip() != 'Item Code': # remove the labels
+				# validate
+				if len(s) != 4:
+					msgprint("Data entered at Row No " + cstr(count) + " in Attachment File is not in correct format.", raise_exception=1)
+					self.validated = 0
+				self.validate_item(s[0], count)
+				self.validate_warehouse(s[1], count)
+			
+				# encode as ascii
+				self.data.append([d.encode("ascii") for d in s])
+				count += 1
+			
+		if not self.validated:
+			raise Exception
 
-	def getCSVelement(self,v):
-		v = cstr(v)
-		if not v: return ''
-		if (',' in v) or ('' in v) or ('"' in	v):
-			if '"' in v: v = v.replace('"', '""')
-			return '"'+v+'"'
-		else: return v or ''
 
-	# Add qty diff column in attached file
-	#----------------------------------------
-	def add_data_in_CSV(self,data):
-		filename = self.doc.file_list.split(',')
-		head = []
-		for h in ['Item Code','Warehouse','Qty','Actual','Difference','MAR']:
-			head.append(self.getCSVelement(h))
-		dset = (','.join(head) + "\n")
-		for d in data:
-			l = [d[self.label['item_code']],d[self.label['warehouse']],d[self.label['qty']],d[self.label['actual_qty']],flt(d[self.label['qty']])-flt(d[self.label['actual_qty']]),d[self.label['mar']]]
-			s =[]
-			for i in l:
-				s.append(self.getCSVelement(i))
-			dset +=(','.join(s)+"\n")
+	def get_reconciliation_data(self,submit = 0):
+		"""Read and validate csv data"""
+		import csv 
+		data = csv.reader(self.get_csv_file_data().splitlines())
+		self.convert_into_list(data)
 		
-		from webnotes.utils import file_manager
-		file_manager.write_file(filename[1], dset)
 
-	# ----------
-	# on submit
-	# ----------
+	def validate_item(self, item, count):
+		""" Validate item exists and non-serialized"""
+		det = sql("select item_code, has_serial_no from `tabItem` where name = '%s'"% cstr(item), as_dict = 1)
+		if not det:
+			msgprint("Item: " + cstr(item) + " mentioned at Row No. " + cstr(count) + "does not exist in the system")
+			self.validated = 0
+		elif det and det[0]['has_serial_no'] == 'Yes':
+			msgprint("""You cannot make Stock Reconciliation of items having serial no. \n
+			You can directly upload serial no to update their inventory. \n
+			Please remove Item Code : %s at Row No. %s""" %(cstr(item), cstr(count)))
+			self.validated = 0
+
+
+	def validate_warehouse(self, wh, count,):
+		"""Validate warehouse exists"""
+		if not sql("select name from `tabWarehouse` where name = '%s'" % cstr(wh)):
+			msgprint("Warehouse: " + cstr(wh) + " mentioned at Row No. " + cstr(count) + " does not exist in the system")
+			self.validated = 0
+
+
+
+	def validate(self):
+		"""Validate attachment data"""
+		#self.data = [['it', 'wh1', 20, 150]]
+		if self.doc.file_list:
+			self.get_reconciliation_data()
+
+			
+
+	def get_system_stock(self, it, wh):
+		"""get actual qty on reconciliation date and time as per system"""
+		bin = sql("select name from tabBin where item_code=%s and warehouse=%s", (it, wh))
+		prev_sle = bin and get_obj('Bin', bin[0][0]).get_sle_prev_timebucket(self.doc.reconciliation_date, self.doc.reconciliation_time) or {}
+		return {
+			'actual_qty': prev_sle.get('bin_aqat', 0), 
+			'stock_uom' : sql("select stock_uom from tabItem where name = %s", it)[0][0], 
+			'val_rate'  : prev_sle.get('valuation_rate', 0)
+		}
+
+
+	def make_sl_entry(self, is_submit, row, qty_diff, sys_stock):
+		"""Make stock ledger entry"""
+		in_rate = self.get_incoming_rate(row, qty_diff, sys_stock)	
+		values = [{
+				'item_code'					: row[0],
+				'warehouse'					: row[1],
+				'transaction_date'	 		: nowdate(),
+				'posting_date'				: self.doc.reconciliation_date,
+				'posting_time'			 	: self.doc.reconciliation_time,
+				'voucher_type'			 	: self.doc.doctype,
+				'voucher_no'				: self.doc.name,
+				'voucher_detail_no'			: self.doc.name,
+				'actual_qty'				: flt(is_submit) * flt(qty_diff),
+				'stock_uom'					: sys_stock['stock_uom'],
+				'incoming_rate'				: in_rate,
+				'company'					: get_defaults()['company'],
+				'fiscal_year'				: get_defaults()['fiscal_year'],
+				'is_cancelled'			 	: (is_submit==1) and 'No' or 'Yes',
+				'batch_no'					: '',
+				'serial_no'					: ''
+		 }]		
+		get_obj('Stock Ledger', 'Stock Ledger').update_stock(values)
+		
+		
+	def get_incoming_rate(self, row, qty_diff, sys_stock):
+		"""Calculate incoming rate to maintain valuation rate"""
+		in_rate = flt(row[3]) + (flt(sys_stock['actual_qty'])*(flt(row[3]) - flt(sys_stock['val_rate'])))/ flt(qty_diff)
+		return in_rate
+
+
+	def do_stock_reco(self, is_submit = 1):
+		"""
+			Make stock entry of qty diff, calculate incoming rate to maintain valuation rate.
+			If no qty diff, but diff in valuation rate, make (+1,-1) entry to update valuation
+		"""
+		for row in self.data:
+			# Get qty as per system
+			sys_stock = self.get_system_stock(row[0],row[1])
+			
+			# Diff between file and system
+			qty_diff = row[2] != '~' and flt(row[2]) - flt(sys_stock['actual_qty']) or 0
+			rate_diff = row[3] != '~' and flt(row[3]) - flt(sys_stock['val_rate']) or 0
+
+			# Make sl entry
+			if qty_diff:
+				self.make_sl_entry(is_submit, row, qty_diff, sys_stock)
+			elif rate_diff:
+				self.make_sl_entry(is_submit, row, 1, sys_stock)
+				sys_stock['val_rate'] = row[3]
+				sys_stock['actual_qty'] += 1
+				self.make_sl_entry(is_submit, row, -1, sys_stock)
+
+			if is_submit == 1:
+				self.add_data_in_CSV(qty_diff, rate_diff)
+				
+			msgprint("Stock Reconciliation Completed Successfully...")
+			
+
+	def add_data_in_CSV(self, qty_diff, rate_diff):
+		"""Add diffs column in attached file"""
+		
+		# add header
+		out = "'Item Code', 'Warehouse', 'Qty', 'Valuation Rate', 'Qty Diff', 'Val Rate Diff'"
+		
+		# add data
+		for d in self.data:
+			s = [cstr(i) for i in d] + [cstr(qty_diff), cstr(rate_diff)]
+			out += "\n" + ','.join(s)
+		
+		# write to file
+		fname = self.doc.file_list.split(',')
+		from webnotes.utils import file_manager
+		file_manager.write_file(fname[1], out)
+		
+			
+
 	def on_submit(self):
-		self.stock_reconciliations(submit = 1)
+		if not self.doc.file_list:
+			msgprint("Please attach file before submitting.", raise_exception=1)
+		else:
+			self.do_stock_reco(is_submit = 1)
+			
+
+
+	def on_cancel(self):
+		self.validate()
+		self.do_stock_reco(is_submit = -1)
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.txt b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.txt
index 771068d..9a21130 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.txt
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.txt
@@ -5,16 +5,18 @@
 	{
 		'creation': '2010-08-08 17:09:26',
 		'docstatus': 0,
-		'modified': '2011-04-25 11:46:21',
+		'modified': '2011-11-24 12:04:03',
 		'modified_by': 'Administrator',
 		'owner': 'Administrator'
 	},
 
 	# These values are common for all DocType
 	{
-		'_last_update': '1309508840',
+		'_last_update': '1321617741',
 		'allow_attach': 1,
+		'autoname': 'SR/.######',
 		'colour': 'White:FFF',
+		'default_print_format': 'Standard',
 		'doctype': 'DocType',
 		'max_attachments': 1,
 		'module': 'Stock',
@@ -23,7 +25,8 @@
 		'section_style': 'Tray',
 		'server_code_error': ' ',
 		'show_in_menu': 0,
-		'version': 85
+		'subject': 'Date: %(reconciliation_date)s, Time: %(reconciliation_time)s',
+		'version': 107
 	},
 
 	# These values are common for all DocField
@@ -37,6 +40,7 @@
 
 	# These values are common for all DocPerm
 	{
+		'amend': 0,
 		'doctype': 'DocPerm',
 		'name': '__common__',
 		'parent': 'Stock Reconciliation',
@@ -53,11 +57,9 @@
 
 	# DocPerm
 	{
-		'amend': 1,
 		'cancel': 1,
 		'create': 1,
 		'doctype': 'DocPerm',
-		'idx': 1,
 		'permlevel': 0,
 		'role': 'Material Manager',
 		'submit': 1,
@@ -66,11 +68,9 @@
 
 	# DocPerm
 	{
-		'amend': 0,
 		'cancel': 0,
 		'create': 0,
 		'doctype': 'DocPerm',
-		'idx': 2,
 		'permlevel': 1,
 		'role': 'Material Manager',
 		'submit': 0,
@@ -79,44 +79,21 @@
 
 	# DocPerm
 	{
-		'amend': 1,
 		'cancel': 1,
 		'create': 1,
 		'doctype': 'DocPerm',
-		'idx': 3,
 		'permlevel': 0,
 		'role': 'System Manager',
 		'submit': 1,
 		'write': 1
 	},
 
-	# DocPerm
-	{
-		'doctype': 'DocPerm',
-		'idx': 4,
-		'permlevel': 1,
-		'role': 'System Manager'
-	},
-
 	# DocField
 	{
 		'doctype': 'DocField',
-		'fieldtype': 'Button',
-		'hidden': 1,
-		'idx': 1,
-		'label': 'Validate Data',
-		'oldfieldtype': 'Button',
-		'options': 'get_reconciliation_stock_details',
-		'permlevel': 0
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldtype': 'Section Break',
-		'idx': 2,
-		'label': 'Summary',
-		'oldfieldtype': 'Section Break',
+		'fieldtype': 'HTML',
+		'label': 'Steps',
+		'options': '<div class="field_description"><b>Steps:</b><br>1. Enter Reconciliation Date and Time<br>2. Save the document<br>3. Attach csv file as per template.<br>4. Submit the document<br>5. Enter tilde (~) sign if no difference in qty or valuation rate</div>',
 		'permlevel': 0
 	},
 
@@ -125,14 +102,12 @@
 		'doctype': 'DocField',
 		'fieldname': 'reconciliation_date',
 		'fieldtype': 'Date',
-		'idx': 3,
 		'in_filter': 0,
 		'label': 'Reconciliation Date',
 		'oldfieldname': 'reconciliation_date',
 		'oldfieldtype': 'Date',
 		'permlevel': 0,
-		'reqd': 1,
-		'search_index': 1
+		'reqd': 1
 	},
 
 	# DocField
@@ -140,7 +115,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'reconciliation_time',
 		'fieldtype': 'Time',
-		'idx': 4,
 		'in_filter': 0,
 		'label': 'Reconciliation Time',
 		'oldfieldname': 'reconciliation_time',
@@ -152,97 +126,20 @@
 	# DocField
 	{
 		'doctype': 'DocField',
-		'fieldname': 'next_step',
-		'fieldtype': 'Select',
-		'idx': 5,
-		'label': 'Next Steps',
-		'oldfieldname': 'next_step',
-		'oldfieldtype': 'Select',
-		'options': 'Upload File and Save Document\nValidate Data\nSubmit Document\nCompleted',
-		'permlevel': 1
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
 		'fieldname': 'remark',
 		'fieldtype': 'Text',
-		'idx': 6,
 		'label': 'Remark',
 		'oldfieldname': 'remark',
 		'oldfieldtype': 'Text',
-		'permlevel': 1
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'company',
-		'fieldtype': 'Link',
-		'idx': 7,
-		'in_filter': 1,
-		'label': 'Company',
-		'oldfieldname': 'company',
-		'oldfieldtype': 'Link',
-		'options': 'Company',
-		'permlevel': 0,
-		'search_index': 0
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'fiscal_year',
-		'fieldtype': 'Select',
-		'idx': 8,
-		'in_filter': 1,
-		'label': 'Fiscal Year',
-		'oldfieldname': 'fiscal_year',
-		'oldfieldtype': 'Select',
-		'options': 'link:Fiscal Year',
-		'permlevel': 0,
-		'search_index': 0
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'amended_from',
-		'fieldtype': 'Data',
-		'idx': 9,
-		'label': 'Amended From',
-		'permlevel': 1
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldname': 'amendment_date',
-		'fieldtype': 'Date',
-		'idx': 10,
-		'label': 'Amendment Date',
-		'permlevel': 1
-	},
-
-	# DocField
-	{
-		'doctype': 'DocField',
-		'fieldtype': 'Section Break',
-		'idx': 11,
-		'label': 'Attachment',
-		'oldfieldtype': 'Section Break',
 		'permlevel': 0
 	},
 
 	# DocField
 	{
 		'doctype': 'DocField',
-		'fieldtype': 'HTML',
-		'idx': 12,
-		'label': 'Attachment HTML',
-		'oldfieldtype': 'HTML',
-		'options': 'The attachment must be a CSV(Comma Seperated Value) file',
-		'permlevel': 1
+		'fieldtype': 'Button',
+		'label': 'Download Template',
+		'permlevel': 0
 	},
 
 	# DocField
@@ -251,8 +148,8 @@
 		'fieldname': 'file_list',
 		'fieldtype': 'Text',
 		'hidden': 1,
-		'idx': 13,
 		'label': 'File List',
+		'no_copy': 1,
 		'oldfieldname': 'file_list',
 		'oldfieldtype': 'Text',
 		'permlevel': 1,
diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py
index b59ce75..0b099fd 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.py
+++ b/erpnext/stock/doctype/warehouse/warehouse.py
@@ -18,73 +18,88 @@
 
 
 class DocType:
-  def __init__(self, doc, doclist=[]):
-    self.doc = doc
-    self.doclist = doclist
-    
-  def get_bin(self, item_code):
-    bin = sql("select name from tabBin where item_code = '%s' and warehouse = '%s'" % (item_code, self.doc.name))
-    bin = bin and bin[0][0] or ''
-    if not bin:
-      if not self.doc.warehouse_type :
-        msgprint("[Warehouse Type is Mandatory] Please Enter warehouse type in Warehouse " + self.doc.name)
-        raise Exception
-      bin = Document('Bin')
-      bin.item_code = item_code
-      bin.stock_uom = get_value('Item', item_code, 'stock_uom')
-      bin.warehouse = self.doc.name
-      bin.warehouse_type = self.doc.warehouse_type
-      bin_obj = get_obj(doc=bin)
-      bin_obj.validate()
-      bin.save(1)
-      bin = bin.name
-    else:
-      bin_obj = get_obj('Bin',bin)
+	def __init__(self, doc, doclist=[]):
+		self.doc = doc
+		self.doclist = doclist
+		
+	def get_bin(self, item_code):
+		bin = sql("select name from tabBin where item_code = '%s' and warehouse = '%s'" % (item_code, self.doc.name))
+		bin = bin and bin[0][0] or ''
+		if not bin:
+			if not self.doc.warehouse_type :
+				msgprint("[Warehouse Type is Mandatory] Please Enter warehouse type in Warehouse " + self.doc.name)
+				raise Exception
+			bin = Document('Bin')
+			bin.item_code = item_code
+			bin.stock_uom = get_value('Item', item_code, 'stock_uom')
+			bin.warehouse = self.doc.name
+			bin.warehouse_type = self.doc.warehouse_type
+			bin_obj = get_obj(doc=bin)
+			bin_obj.validate()
+			bin.save(1)
+			bin = bin.name
+		else:
+			bin_obj = get_obj('Bin',bin)
 
-    return bin_obj
-  
+		return bin_obj
+	
 
-  def validate_asset(self, item_code):
-    if sql("select is_asset_item from tabItem where name=%s", item_code)[0][0] == 'Yes' and self.doc.warehouse_type != 'Fixed Asset':
-      msgprint("Fixed Asset Item %s can only be transacted in a Fixed Asset type Warehouse" % item_code)
-      raise Exception
+	def validate_asset(self, item_code):
+		if sql("select is_asset_item from tabItem where name=%s", item_code)[0][0] == 'Yes' and self.doc.warehouse_type != 'Fixed Asset':
+			msgprint("Fixed Asset Item %s can only be transacted in a Fixed Asset type Warehouse" % item_code)
+			raise Exception
 
 
-  # update bin
-  # ----------
-  def update_bin(self, actual_qty, reserved_qty, ordered_qty, indented_qty, planned_qty, item_code, dt, sle_id = '',posting_time = '', serial_no = '', is_cancelled = 'No'):
-    self.validate_asset(item_code)
-    it_det = get_value('Item', item_code, 'is_stock_item')
-    if it_det and it_det == 'Yes':
-      bin = self.get_bin(item_code)
-      bin.update_stock(actual_qty, reserved_qty, ordered_qty, indented_qty, planned_qty, dt, sle_id, posting_time, serial_no, is_cancelled)
-      return bin
-    else:
-      msgprint("[Stock Update] Ignored %s since it is not a stock item" % item_code)
+	# update bin
+	# ----------
+	def update_bin(self, actual_qty, reserved_qty, ordered_qty, indented_qty, planned_qty, item_code, dt, sle_id = '',posting_time = '', serial_no = '', is_cancelled = 'No'):
+		self.validate_asset(item_code)
+		it_det = get_value('Item', item_code, 'is_stock_item')
+		if it_det and it_det == 'Yes':
+			bin = self.get_bin(item_code)
+			bin.update_stock(actual_qty, reserved_qty, ordered_qty, indented_qty, planned_qty, dt, sle_id, posting_time, serial_no, is_cancelled)
+			return bin
+		else:
+			msgprint("[Stock Update] Ignored %s since it is not a stock item" % item_code)
 
-  # repost stock
-  # ------------
-  def repost_stock(self):
-    bl = sql("select name from tabBin where warehouse=%s", self.doc.name)
-    for b in bl:
-      bobj = get_obj('Bin',b[0])
-      bobj.update_entries_after(posting_date = '0000-00-00', posting_time = '00:00')
+	# repost stock
+	# ------------
+	def repost_stock(self):
+		bl = sql("select name from tabBin where warehouse=%s", self.doc.name)
+		for b in bl:
+			bobj = get_obj('Bin',b[0])
+			bobj.update_entries_after(posting_date = '0000-00-00', posting_time = '00:00')
 
-      sql("COMMIT")
-      sql("START TRANSACTION")
+			sql("COMMIT")
+			sql("START TRANSACTION")
 
-  def check_state(self):
-    return "\n" + "\n".join([i[0] for i in sql("select state_name from `tabState` where `tabState`.country='%s' " % self.doc.country)])
+	def check_state(self):
+		return "\n" + "\n".join([i[0] for i in sql("select state_name from `tabState` where `tabState`.country='%s' " % self.doc.country)])
 
-  def validate(self):
-    if self.doc.email_id:
-      if not validate_email_add(self.doc.email_id):
-        msgprint("Please enter valid Email Id.")
-        raise Exception
-    if not self.doc.warehouse_type:
-      msgprint("[Warehouse Type is Mandatory] Please Enter  Please Entry warehouse type in Warehouse " + self.doc.name)
-      raise Exception
-    wt = sql("select warehouse_type from `tabWarehouse` where name ='%s'" % self.doc.name)
-    if cstr(self.doc.warehouse_type) != cstr(wt and wt[0][0] or ''):
-      sql("update `tabStock Ledger Entry` set warehouse_type = '%s' where warehouse = '%s'" % (self.doc.warehouse_type, self.doc.name))
-      msgprint("All Stock Ledger Entries Updated.")
+	def validate(self):
+		if self.doc.email_id:
+			if not validate_email_add(self.doc.email_id):
+				msgprint("Please enter valid Email Id.")
+				raise Exception
+		if not self.doc.warehouse_type:
+			msgprint("[Warehouse Type is Mandatory] Please Enter	Please Entry warehouse type in Warehouse " + self.doc.name)
+			raise Exception
+		wt = sql("select warehouse_type from `tabWarehouse` where name ='%s'" % self.doc.name)
+		if cstr(self.doc.warehouse_type) != cstr(wt and wt[0][0] or ''):
+			sql("update `tabStock Ledger Entry` set warehouse_type = '%s' where warehouse = '%s'" % (self.doc.warehouse_type, self.doc.name))
+			msgprint("All Stock Ledger Entries Updated.")
+			
+	def on_trash(self):
+		# delete bin
+		bins = sql("select * from `tabBin` where warehouse = %s", self.doc.name, as_dict=1)
+		for d in bins:
+			if d['actual_qty'] or d['reserved_qty'] or d['ordered_qty'] or d['indented_qty'] or d['projected_qty'] or d['planned_qty']:
+				msgprint("Warehouse: %s can not be deleted as qty exists for item: %s" % (self.doc.name, d['item_code']), raise_exception=1)
+			else:
+				sql("delete from `tabBin` where name = %s", d['name'])
+				
+		# delete cancelled sle
+		if sql("select name from `tabStock Ledger Entry` where warehouse = %s and ifnull('is_cancelled', '') = 'No'", self.doc.name):
+			mdgprint("Warehosue can not be deleted as stock ledger entry exists for this warehosue.", raise_exception=1)
+		else:
+			sql("delete from `tabStock Ledger Entry` where warehouse = %s", self.doc.name)
diff --git a/erpnext/stock/doctype/warehouse/warehouse.txt b/erpnext/stock/doctype/warehouse/warehouse.txt
index da29dfa..87b0eda 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.txt
+++ b/erpnext/stock/doctype/warehouse/warehouse.txt
@@ -5,14 +5,14 @@
 	{
 		'creation': '2010-08-08 17:09:30',
 		'docstatus': 0,
-		'modified': '2011-09-28 16:19:59',
+		'modified': '2011-11-15 15:06:24',
 		'modified_by': 'Administrator',
 		'owner': 'Administrator'
 	},
 
 	# These values are common for all DocType
 	{
-		'_last_update': '1311621379',
+		'_last_update': '1319016431',
 		'allow_trash': 1,
 		'autoname': 'field:warehouse_name',
 		'colour': 'White:FFF',
@@ -25,7 +25,7 @@
 		'section_style': 'Tabbed',
 		'server_code_error': ' ',
 		'show_in_menu': 0,
-		'version': 56
+		'version': 58
 	},
 
 	# These values are common for all DocField
@@ -319,27 +319,6 @@
 
 	# DocField
 	{
-		'allow_on_submit': 0,
-		'doctype': 'DocField',
-		'fieldname': 'country',
-		'fieldtype': 'Link',
-		'hidden': 0,
-		'in_filter': 0,
-		'label': 'Country',
-		'no_copy': 0,
-		'oldfieldname': 'country',
-		'oldfieldtype': 'Link',
-		'options': 'Country',
-		'permlevel': 0,
-		'print_hide': 0,
-		'report_hide': 0,
-		'reqd': 0,
-		'search_index': 0,
-		'trigger': 'Client'
-	},
-
-	# DocField
-	{
 		'colour': 'White:FFF',
 		'doctype': 'DocField',
 		'fieldname': 'state',
diff --git a/erpnext/utilities/doctype/address/address.txt b/erpnext/utilities/doctype/address/address.txt
index 4f44806..776321b 100644
--- a/erpnext/utilities/doctype/address/address.txt
+++ b/erpnext/utilities/doctype/address/address.txt
@@ -3,26 +3,28 @@
 
 	# These values are common in all dictionaries
 	{
-		'creation': '2011-05-24 10:14:48',
+		'creation': '2011-05-24 14:57:59',
 		'docstatus': 0,
-		'modified': '2011-06-09 12:28:53',
+		'modified': '2011-11-23 13:21:00',
 		'modified_by': 'Administrator',
 		'owner': 'Administrator'
 	},
 
 	# These values are common for all DocType
 	{
-		'_last_update': '1307602735',
+		'_last_update': '1319016431',
 		'allow_trash': 1,
 		'colour': 'White:FFF',
+		'default_print_format': 'Standard',
 		'doctype': 'DocType',
 		'document_type': 'Master',
 		'in_dialog': 1,
 		'module': 'Utilities',
 		'name': '__common__',
+		'search_fields': 'customer, supplier, sales_partner, country, state',
 		'section_style': 'Simple',
 		'show_in_menu': 0,
-		'version': 42
+		'version': 43
 	},
 
 	# These values are common for all DocField
@@ -39,7 +41,6 @@
 		'cancel': 1,
 		'create': 1,
 		'doctype': 'DocPerm',
-		'idx': 1,
 		'name': '__common__',
 		'parent': 'Address',
 		'parentfield': 'permissions',
@@ -66,7 +67,6 @@
 		'colour': 'White:FFF',
 		'doctype': 'DocField',
 		'fieldtype': 'Section Break',
-		'idx': 1,
 		'label': 'Address Details',
 		'permlevel': 0
 	},
@@ -78,7 +78,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'address_type',
 		'fieldtype': 'Data',
-		'idx': 2,
 		'label': 'Address Type',
 		'permlevel': 0,
 		'reqd': 1
@@ -90,7 +89,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'address_line1',
 		'fieldtype': 'Data',
-		'idx': 3,
 		'label': 'Address Line1',
 		'permlevel': 0,
 		'reqd': 1
@@ -101,7 +99,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'address_line2',
 		'fieldtype': 'Data',
-		'idx': 4,
 		'label': 'Address Line2',
 		'permlevel': 0
 	},
@@ -112,12 +109,11 @@
 		'doctype': 'DocField',
 		'fieldname': 'city',
 		'fieldtype': 'Data',
-		'idx': 5,
 		'in_filter': 1,
 		'label': 'City/Town',
 		'permlevel': 0,
 		'reqd': 1,
-		'search_index': 0
+		'search_index': 1
 	},
 
 	# DocField
@@ -125,11 +121,10 @@
 		'doctype': 'DocField',
 		'fieldname': 'pincode',
 		'fieldtype': 'Data',
-		'idx': 6,
 		'in_filter': 1,
 		'label': 'Pincode',
 		'permlevel': 0,
-		'search_index': 0
+		'search_index': 1
 	},
 
 	# DocField
@@ -138,13 +133,12 @@
 		'doctype': 'DocField',
 		'fieldname': 'country',
 		'fieldtype': 'Select',
-		'idx': 7,
 		'in_filter': 1,
 		'label': 'Country',
 		'options': 'link:Country',
 		'permlevel': 0,
 		'reqd': 1,
-		'search_index': 0,
+		'search_index': 1,
 		'trigger': 'Client'
 	},
 
@@ -154,7 +148,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'state',
 		'fieldtype': 'Data',
-		'idx': 8,
 		'in_filter': 1,
 		'label': 'State',
 		'options': 'Suggest',
@@ -166,7 +159,6 @@
 	{
 		'doctype': 'DocField',
 		'fieldtype': 'Column Break',
-		'idx': 9,
 		'permlevel': 0,
 		'print_hide': 0,
 		'width': '50%'
@@ -177,7 +169,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'phone',
 		'fieldtype': 'Data',
-		'idx': 10,
 		'label': 'Phone',
 		'permlevel': 0,
 		'reqd': 1
@@ -188,7 +179,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'email_id',
 		'fieldtype': 'Data',
-		'idx': 11,
 		'label': 'Email Id',
 		'permlevel': 0
 	},
@@ -198,7 +188,7 @@
 		'doctype': 'DocField',
 		'fieldname': 'fax',
 		'fieldtype': 'Data',
-		'idx': 12,
+		'in_filter': 1,
 		'label': 'Fax',
 		'permlevel': 0
 	},
@@ -210,12 +200,9 @@
 		'doctype': 'DocField',
 		'fieldname': 'customer',
 		'fieldtype': 'Link',
-		'idx': 13,
 		'label': 'Customer',
 		'options': 'Customer',
-		'permlevel': 0,
-		'search_index': 1,
-		'trigger': 'Client'
+		'permlevel': 0
 	},
 
 	# DocField
@@ -225,7 +212,7 @@
 		'doctype': 'DocField',
 		'fieldname': 'customer_name',
 		'fieldtype': 'Data',
-		'idx': 14,
+		'in_filter': 1,
 		'label': 'Customer Name',
 		'permlevel': 1
 	},
@@ -237,12 +224,9 @@
 		'doctype': 'DocField',
 		'fieldname': 'supplier',
 		'fieldtype': 'Link',
-		'idx': 15,
 		'label': 'Supplier',
 		'options': 'Supplier',
-		'permlevel': 0,
-		'search_index': 1,
-		'trigger': 'Client'
+		'permlevel': 0
 	},
 
 	# DocField
@@ -252,9 +236,10 @@
 		'doctype': 'DocField',
 		'fieldname': 'supplier_name',
 		'fieldtype': 'Data',
-		'idx': 16,
+		'in_filter': 1,
 		'label': 'Supplier Name',
-		'permlevel': 1
+		'permlevel': 1,
+		'search_index': 0
 	},
 
 	# DocField
@@ -264,7 +249,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'sales_partner',
 		'fieldtype': 'Link',
-		'idx': 17,
 		'label': 'Sales Partner',
 		'options': 'Sales Partner',
 		'permlevel': 0
@@ -278,7 +262,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'is_primary_address',
 		'fieldtype': 'Check',
-		'idx': 18,
 		'label': 'Is Primary Address',
 		'permlevel': 0
 	},
@@ -291,7 +274,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'is_shipping_address',
 		'fieldtype': 'Check',
-		'idx': 19,
 		'label': 'Is Shipping Address',
 		'permlevel': 0
 	},
@@ -301,7 +283,6 @@
 		'doctype': 'DocField',
 		'fieldname': 'trash_reason',
 		'fieldtype': 'Small Text',
-		'idx': 20,
 		'label': 'Trash Reason',
 		'permlevel': 0
 	}
diff --git a/index.html b/index.html
index c28b0aa..db7c228 100644
--- a/index.html
+++ b/index.html
@@ -3,7 +3,7 @@
 	<meta charset="utf-8">
 	<title>ERPNext</title>
 	<meta name="author" content="">
-	<script type="text/javascript">window._version_number="325"
+	<script type="text/javascript">window._version_number="337"
 
 wn={}
 wn.provide=function(namespace){var nsl=namespace.split('.');var l=nsl.length;var parent=window;for(var i=0;i<l;i++){var n=nsl[i];if(!parent[n]){parent[n]={}}
@@ -79,4 +79,4 @@
 	</div>
 	<script>wn.require('js/app.js');</script>
 	<div id="dialog_back"></div>
-</body>
+</body>
\ No newline at end of file
diff --git a/versions-master.db b/versions-master.db
index 5707243..0c1c75c 100644
--- a/versions-master.db
+++ b/versions-master.db
Binary files differ