Merge branch 'master' of github.com:webnotes/erpnext
diff --git a/accounts/doctype/journal_voucher/journal_voucher.js b/accounts/doctype/journal_voucher/journal_voucher.js
index 2e89a67..ab4b2b0 100644
--- a/accounts/doctype/journal_voucher/journal_voucher.js
+++ b/accounts/doctype/journal_voucher/journal_voucher.js
@@ -104,14 +104,6 @@
 	if (doc.is_opening == 'Yes') unhide_field('aging_date');
 }
 
-cur_frm.fields_dict['entries'].grid.onrowadd = function(doc, cdt, cdn){
-	var d = locals[cdt][cdn];
-	if(d.idx == 1){
-		d.debit = 0;
-		d.credit = 0;
-	}
-}
-
 cur_frm.cscript.against_voucher = function(doc,cdt,cdn) {
 	var d = locals[cdt][cdn];
 	if (d.against_voucher && !flt(d.debit)) {
diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.js b/accounts/doctype/purchase_invoice/purchase_invoice.js
index 2bdab8a..e73386f 100644
--- a/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -22,7 +22,7 @@
 wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js');
 wn.require('app/buying/doctype/purchase_common/purchase_common.js');
 
-erpnext.accounts.PurchaseInvoiceController = erpnext.buying.BuyingController.extend({
+erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
 	onload: function() {
 		this._super();
 		
@@ -103,29 +103,14 @@
 	tc_name: function() {
 		this.get_terms();
 	},
-
+	
+	entries_add: function(doc, cdt, cdn) {
+		var row = wn.model.get_doc(cdt, cdn);
+		this.frm.script_manager.copy_from_first_row("entries", row, ["expense_head", "cost_center"]);
+	}
 });
 
-// for backward compatibility: combine new and previous states
-$.extend(cur_frm.cscript, new erpnext.accounts.PurchaseInvoiceController({frm: cur_frm}));
-
-cur_frm.fields_dict['entries'].grid.onrowadd = function(doc, cdt, cdn){
-	
-	cl = getchildren('Purchase Invoice Item', doc.name, cur_frm.cscript.fname, doc.doctype);
-	acc = '';
-	cc = '';
-
-	for(var i = 0; i<cl.length; i++) {
-		if (cl[i].idx == 1){
-			acc = cl[i].expense_head;
-			cc = cl[i].cost_center;
-		}
-		else{
-			if (! cl[i].expense_head) { cl[i].expense_head = acc; refresh_field('expense_head', cl[i].name, 'entries');}
-			if (! cl[i].cost_center)	{cl[i].cost_center = cc; refresh_field('cost_center', cl[i].name, 'entries');}
-		}
-	}
-}
+cur_frm.script_manager.make(erpnext.accounts.PurchaseInvoice);
 
 cur_frm.cscript.is_opening = function(doc, dt, dn) {
 	hide_field('aging_date');
diff --git a/accounts/doctype/sales_invoice/sales_invoice.js b/accounts/doctype/sales_invoice/sales_invoice.js
index 90239fa..773956a 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/accounts/doctype/sales_invoice/sales_invoice.js
@@ -150,6 +150,11 @@
 	paid_amount: function() {
 		this.write_off_outstanding_amount_automatically();
 	},
+	
+	entries_add: function(doc, cdt, cdn) {
+		var row = wn.model.get_doc(cdt, cdn);
+		this.frm.script_manager.copy_from_first_row("entries", row, ["income_account", "cost_center"]);
+	}
 });
 
 // for backward compatibility: combine new and previous states
@@ -197,25 +202,6 @@
 	cur_frm.cscript.hide_fields(doc, dt, dn);
 }
 
-cur_frm.fields_dict['entries'].grid.onrowadd = function(doc, cdt, cdn){
-
-	cl = getchildren('Sales Invoice Item', doc.name, cur_frm.cscript.fname, doc.doctype);
-	acc = '';
-	cc = '';
-
-	for(var i = 0; i<cl.length; i++) {
-
-		if (cl[i].idx == 1){
-			acc = cl[i].income_account;
-			cc = cl[i].cost_center;
-		}
-		else{
-			if (! cl[i].income_account) { cl[i].income_account = acc; refresh_field('income_account', cl[i].name, 'entries');}
-			if (! cl[i].cost_center)	{cl[i].cost_center = cc;refresh_field('cost_center', cl[i].name, 'entries');}
-		}
-	}
-}
-
 cur_frm.cscript.is_opening = function(doc, dt, dn) {
 	hide_field('aging_date');
 	if (doc.is_opening == 'Yes') unhide_field('aging_date');
diff --git a/patches/patch_list.py b/patches/patch_list.py
index d484f16..e8a03ff 100644
--- a/patches/patch_list.py
+++ b/patches/patch_list.py
@@ -163,9 +163,6 @@
 	"patches.february_2013.p05_leave_application",
 	"patches.february_2013.gle_floating_point_issue_revisited",
 	"patches.february_2013.fix_outstanding",
-	'execute:webnotes.reload_doc("selling", "Print Format", "Quotation Classic") # 2013-02-19',
-	'execute:webnotes.reload_doc("selling", "Print Format", "Quotation Modern") # 2013-02-19',
-	'execute:webnotes.reload_doc("selling", "Print Format", "Quotation Spartan") # 2013-02-19',
 	"execute:webnotes.delete_doc('DocType', 'Service Order')",
 	"execute:webnotes.delete_doc('DocType', 'Service Quotation')",
 	"execute:webnotes.delete_doc('DocType', 'Service Order Detail')",
@@ -176,9 +173,6 @@
 	"execute:webnotes.conn.sql(\"update `tabReport` set report_type=if(ifnull(query, '')='', 'Report Builder', 'Query Report') where is_standard='No'\")",
 	"execute:webnotes.conn.sql(\"update `tabReport` set report_name=name where ifnull(report_name,'')='' and is_standard='No'\")",
 	"patches.february_2013.p08_todo_query_report",
-	'execute:webnotes.reload_doc("accounts", "Print Format", "Sales Invoice Classic") # 2013-02-26',
-	'execute:webnotes.reload_doc("accounts", "Print Format", "Sales Invoice Modern") # 2013-02-26',
-	'execute:webnotes.reload_doc("accounts", "Print Format", "Sales Invoice Spartan") # 2013-02-26',
 	"execute:(not webnotes.conn.exists('Role', 'Projects Manager')) and webnotes.doc({'doctype':'Role', 'role_name':'Projects Manager'}).insert()",
 	"patches.february_2013.p09_remove_cancelled_warehouses",
 	"patches.march_2013.update_po_prevdoc_doctype",
@@ -210,9 +204,6 @@
 	"patches.april_2013.p01_update_serial_no_valuation_rate",
 	"patches.april_2013.p02_add_country_and_currency",
 	"patches.april_2013.p03_fixes_for_lead_in_quotation",
-	'execute:webnotes.reload_doc("selling", "Print Format", "Quotation Classic") # 2013-04-02',
-	'execute:webnotes.reload_doc("selling", "Print Format", "Quotation Modern") # 2013-04-02',
-	'execute:webnotes.reload_doc("selling", "Print Format", "Quotation Spartan") # 2013-04-02',
 	"patches.april_2013.p04_reverse_modules_list",
 	"patches.april_2013.p04_update_role_in_pages",
 	"patches.april_2013.p05_update_file_data",
@@ -257,4 +248,17 @@
 	"patches.july_2013.p05_custom_doctypes_in_list_view",
 	"patches.july_2013.p06_same_sales_rate",
 	"patches.july_2013.p07_repost_billed_amt_in_sales_cycle",
+	"execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Classic') # 2013-07-22",
+	"execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Modern') # 2013-07-22",
+	"execute:webnotes.reload_doc('accounts', 'Print Format', 'Sales Invoice Spartan') # 2013-07-22",
+	"execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Classic') # 2013-07-22",
+	"execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Modern') # 2013-07-22",
+	"execute:webnotes.reload_doc('selling', 'Print Format', 'Quotation Spartan') # 2013-07-22",
+	"execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Classic') # 2013-07-22",
+	"execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Modern') # 2013-07-22",
+	"execute:webnotes.reload_doc('selling', 'Print Format', 'Sales Order Spartan') # 2013-07-22",
+	"execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Classic') # 2013-07-22",
+	"execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Modern') # 2013-07-22",
+	"execute:webnotes.reload_doc('stock', 'Print Format', 'Delivery Note Spartan') # 2013-07-22",
+	"patches.july_2013.p08_custom_print_format_net_total_export",
 ]
\ No newline at end of file
diff --git a/selling/doctype/customer/customer.txt b/selling/doctype/customer/customer.txt
index 5b8e323..f4e068b 100644
--- a/selling/doctype/customer/customer.txt
+++ b/selling/doctype/customer/customer.txt
@@ -2,7 +2,7 @@
  {
   "creation": "2013-06-11 14:26:44", 
   "docstatus": 0, 
-  "modified": "2013-07-11 16:53:18", 
+  "modified": "2013-07-22 12:47:19", 
   "modified_by": "Administrator", 
   "owner": "Administrator"
  }, 
@@ -334,6 +334,21 @@
   "permlevel": 0
  }, 
  {
+  "doctype": "DocField", 
+  "fieldname": "customer_discount_section", 
+  "fieldtype": "Section Break", 
+  "label": "Customer Discount", 
+  "permlevel": 0
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "customer_discounts", 
+  "fieldtype": "Table", 
+  "label": "Customer Discounts", 
+  "options": "Customer Discount", 
+  "permlevel": 0
+ }, 
+ {
   "amend": 0, 
   "cancel": 0, 
   "create": 1, 
diff --git a/selling/doctype/customer_discount/__init__.py b/selling/doctype/customer_discount/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/selling/doctype/customer_discount/__init__.py
diff --git a/selling/doctype/customer_discount/customer_discount.py b/selling/doctype/customer_discount/customer_discount.py
new file mode 100644
index 0000000..928aa9f
--- /dev/null
+++ b/selling/doctype/customer_discount/customer_discount.py
@@ -0,0 +1,8 @@
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import webnotes
+
+class DocType:
+	def __init__(self, d, dl):
+		self.doc, self.doclist = d, dl
\ No newline at end of file
diff --git a/selling/doctype/customer_discount/customer_discount.txt b/selling/doctype/customer_discount/customer_discount.txt
new file mode 100644
index 0000000..e7b7822
--- /dev/null
+++ b/selling/doctype/customer_discount/customer_discount.txt
@@ -0,0 +1,42 @@
+[
+ {
+  "creation": "2013-07-22 12:43:40", 
+  "docstatus": 0, 
+  "modified": "2013-07-22 12:49:32", 
+  "modified_by": "Administrator", 
+  "owner": "Administrator"
+ }, 
+ {
+  "doctype": "DocType", 
+  "istable": 1, 
+  "module": "Selling", 
+  "name": "__common__"
+ }, 
+ {
+  "doctype": "DocField", 
+  "in_list_view": 1, 
+  "name": "__common__", 
+  "parent": "Customer Discount", 
+  "parentfield": "fields", 
+  "parenttype": "DocType", 
+  "permlevel": 0, 
+  "reqd": 1
+ }, 
+ {
+  "doctype": "DocType", 
+  "name": "Customer Discount"
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "item_group", 
+  "fieldtype": "Link", 
+  "label": "Item Group", 
+  "options": "Item Group"
+ }, 
+ {
+  "doctype": "DocField", 
+  "fieldname": "discount", 
+  "fieldtype": "Currency", 
+  "label": "Discount (%)"
+ }
+]
\ No newline at end of file
diff --git a/selling/utils.py b/selling/utils.py
index 5f2cfbd..cbfaee7 100644
--- a/selling/utils.py
+++ b/selling/utils.py
@@ -66,6 +66,8 @@
 		
 		if args.price_list_name and args.price_list_currency:
 			out.update(_get_price_list_rate(args, item_bean, meta))
+			
+	out.update(_get_item_discount(out.item_group, args.customer))
 	
 	if out.warehouse or out.reserved_warehouse:
 		out.update(get_available_qty(args.item_code, out.warehouse or out.reserved_warehouse))
@@ -119,7 +121,6 @@
 				or webnotes.conn.get_value("Company", args.company, "default_expense_account"),
 			"cost_center": item.default_sales_cost_center or args.cost_center,
 			"qty": 1.0,
-			"adj_rate": 0.0,
 			"export_amount": 0.0,
 			"amount": 0.0,
 			"batch_no": None,
@@ -147,6 +148,23 @@
 	validate_currency(args, item_bean.doc, meta)
 	
 	return {"ref_rate": flt(base_ref_rate[0].ref_rate * args.plc_conversion_rate / args.conversion_rate)}
+	
+def _get_item_discount(item_group, customer):
+	parent_item_groups = [x[0] for x in webnotes.conn.sql("""SELECT parent.name 
+		FROM `tabItem Group` AS node, `tabItem Group` AS parent 
+		WHERE parent.lft <= node.lft and parent.rgt >= node.rgt and node.name = %s
+		GROUP BY parent.name 
+		ORDER BY parent.lft desc""", item_group)]
+		
+	discount = 0
+	for d in parent_item_groups:
+		res = webnotes.conn.sql("""select discount, name from `tabCustomer Discount` 
+			where parent = %s and item_group = %s""", (customer, d))
+		if res:
+			discount = flt(res[0][0])
+			break
+			
+	return {"adj_rate": discount}
 
 @webnotes.whitelist()
 def get_available_qty(item_code, warehouse):
@@ -162,7 +180,7 @@
 def get_pos_settings(company):
 	pos_settings = webnotes.conn.sql("""select * from `tabPOS Setting` where user = %s 
 		and company = %s""", (webnotes.session['user'], company), as_dict=1)
-		
+	
 	if not pos_settings:
 		pos_settings = webnotes.conn.sql("""select * from `tabPOS Setting` 
 			where ifnull(user,'') = '' and company = %s""", company, as_dict=1)
diff --git a/stock/doctype/item/item.js b/stock/doctype/item/item.js
index b2a1ffe..b1bb269 100644
--- a/stock/doctype/item/item.js
+++ b/stock/doctype/item/item.js
@@ -14,8 +14,25 @@
 // You should have received a copy of the GNU General Public License
 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-cur_frm.add_fetch("price_list_name", "currency", "ref_currency");
-cur_frm.add_fetch("price_list_name", "buying_or_selling", "buying_or_selling");
+wn.provide("erpnext.stock");
+
+erpnext.stock.Item = wn.ui.form.Controller.extend({
+	onload: function() {
+		this.frm.add_fetch("price_list_name", "currency", "ref_currency");
+		this.frm.add_fetch("price_list_name", "buying_or_selling", "buying_or_selling");
+	},
+	
+	ref_rate_details_add: function(doc, cdt, cdn) {
+		var row = wn.model.get_doc(cdt, cdn);
+		if(row.price_list_name && !row.ref_currency) {
+			// execute fetch
+			var df = wn.meta.get_docfield(row.doctype, "price_list_name", row.parent);
+			this.frm.script_manager.validate_link_and_fetch(df, row.name, row.price_list_name);
+		}
+	}
+});
+
+cur_frm.script_manager.make(erpnext.stock.Item);
 
 cur_frm.cscript.refresh = function(doc) {
 	// make sensitive fields(has_serial_no, is_stock_item, valuation_method)
@@ -157,11 +174,6 @@
   cur_frm.cscript.weight_to_validate(doc,cdt,cdn);
 }
 
-cur_frm.fields_dict['ref_rate_details'].grid.onrowadd = function(doc, cdt, cdn){
-	locals[cdt][cdn].ref_currency = sys_defaults.currency;
-	refresh_field('ref_currency',cdn,'ref_rate_details');
-}
-
 cur_frm.fields_dict.item_customer_details.grid.get_field("customer_name").get_query = 
 function(doc,cdt,cdn) {
 		return{	query:"controllers.queries.customer_query" } }
diff --git a/stock/doctype/stock_entry/stock_entry.js b/stock/doctype/stock_entry/stock_entry.js
index 123c9fb..7032f92 100644
--- a/stock/doctype/stock_entry/stock_entry.js
+++ b/stock/doctype/stock_entry/stock_entry.js
@@ -234,9 +234,15 @@
 		}
 	},
 
+	mtn_details_add: function(doc, cdt, cdn) {
+		var row = wn.model.get_doc(cdt, cdn);
+		
+		if(!row.s_warehouse) row.s_warehouse = this.frm.doc.from_warehouse;
+		if(!row.t_warehouse) row.t_warehouse = this.frm.doc.to_warehouse;
+	},
 });
 
-cur_frm.cscript = new erpnext.stock.StockEntry({frm: cur_frm});
+cur_frm.script_manager.make(erpnext.stock.StockEntry);
 
 cur_frm.cscript.toggle_related_fields = function(doc) {
 	disable_from_warehouse = inList(["Material Receipt", "Sales Return"], doc.purpose);
@@ -296,19 +302,6 @@
 	cur_frm.cscript.toggle_related_fields(doc, cdt, cdn);
 }
 
-// copy over source and target warehouses
-cur_frm.fields_dict['mtn_details'].grid.onrowadd = function(doc, cdt, cdn){
-	var d = locals[cdt][cdn];
-	if(!d.s_warehouse && doc.from_warehouse) {
-		d.s_warehouse = doc.from_warehouse
-		refresh_field('s_warehouse', cdn, 'mtn_details')
-	}
-	if(!d.t_warehouse && doc.to_warehouse) {
-		d.t_warehouse = doc.to_warehouse
-		refresh_field('t_warehouse', cdn, 'mtn_details')
-	}
-}
-
 // Overloaded query for link batch_no
 cur_frm.fields_dict['mtn_details'].grid.get_field('batch_no').get_query = function(doc, cdt, cdn) {
 	var d = locals[cdt][cdn];