Merge branch 'hotfix'
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 7c5133a..6b59a18 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -2,7 +2,7 @@
 from __future__ import unicode_literals
 import frappe
 
-__version__ = '7.0.31'
+__version__ = '7.0.32'
 
 def get_default_company(user=None):
 	'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 871a151..35df299 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -381,9 +381,11 @@
 			if d.delivery_note:
 				msgprint(_("Stock cannot be updated against Delivery Note {0}").format(d.delivery_note), raise_exception=1)
 
-
 	def validate_write_off_account(self):
 		if flt(self.write_off_amount) and not self.write_off_account:
+			self.write_off_account = frappe.db.get_value('Company', self.company, 'write_off_account')
+
+		if flt(self.write_off_amount) and not self.write_off_account:
 			msgprint(_("Please enter Write Off Account"), raise_exception=1)
 
 	def validate_account_for_change_amount(self):
diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js
index 06606a9..5947bde 100644
--- a/erpnext/accounts/page/pos/pos.js
+++ b/erpnext/accounts/page/pos/pos.js
@@ -509,7 +509,7 @@
 			this.remove_zero_qty_item();
 		}
 
-		this.refresh();
+		this.update_paid_amount_status(false)
 	},
 
 	remove_zero_qty_item: function(){
@@ -591,7 +591,7 @@
 		if (!caught)
 			this.add_new_item_to_grid();
 
-		this.refresh();
+		this.update_paid_amount_status(false)
 	},
 
 	add_new_item_to_grid: function() {
@@ -616,6 +616,14 @@
 			? this.item_serial_no[this.child.item_code][0] : '');
 	},
 
+	update_paid_amount_status: function(update_paid_amount){
+		if(this.name){
+			update_paid_amount = update_paid_amount ? false : true;
+		}
+
+		this.refresh(update_paid_amount);
+	},
+
 	refresh: function(update_paid_amount) {
 		var me = this;
 		this.refresh_fields(update_paid_amount);
@@ -623,6 +631,7 @@
 		this.update_rate();
 		this.set_primary_action();
 	},
+
 	refresh_fields: function(update_paid_amount) {
 		this.apply_pricing_rule();
 		this.discount_amount_applied = false;
@@ -698,7 +707,8 @@
 
 		if (this.frm.doc.docstatus==0) {
 			this.page.set_primary_action(__("Pay"), function() {
-				me.validate()
+				me.validate();
+				me.update_paid_amount_status(true);
 				me.create_invoice();
 				me.make_payment();
 			}, "octicon octicon-credit-card");
diff --git a/erpnext/change_log/v7/v7_0_0.md b/erpnext/change_log/v7/v7_0_0.md
new file mode 100644
index 0000000..144d74d
--- /dev/null
+++ b/erpnext/change_log/v7/v7_0_0.md
@@ -0,0 +1,58 @@
+#### New POS
+- Offline
+- Multiple Payment Modes
+- Standard documents cannot be edited in POS view
+
+#### Payment Entry
+- Dedicated form for managing Payments
+- Designed for normal users who do not have accounting background
+
+#### Request for Quotation
+- Updated workflow: Material Request -> **Request for Quotation** -> Supplier Quotation -> Purchase Order
+
+#### Fixed Asset Management
+- Manage fixed asset records and their depreciation
+
+#### Improved Navigation
+- Heatmaps
+- Centralized navigation from Masters like Item, Customer, Supplier, Employee etc.
+
+#### Timesheets
+- New grid
+- Multiple time logs in one timesheets
+- Linked to Payroll and Billing
+
+#### Graphs in Reports
+- Added graphs in some important reports like Balance Sheet, Accounts Receivable etc.
+
+#### Sub-warehouse
+- Tree view for Warehouse
+
+#### New Portal Design
+- New Homepage Design
+- Sidebar in Portal View
+- New Cart View
+
+#### Collaborative Project Management
+- Web View
+- Customers/Suppliers can add/edit issues and view timesheets
+
+#### Budget
+- Dedicated budget form
+- Budget can be assigned against Cost Center Group
+
+#### Check Printing Format
+- Ability to customize Cheque Printing Format for any bank
+
+#### Schools application is now part of ERPNext
+
+#### Minor
+
+- Selling Price calculation based on Margin defined in the Pricing Rule
+- Document flow-chart on Sales / Purchase Transactions
+- Domain specific desktop views
+- Add opening Stock and Rate while creating a new Item
+- Book payments and update stock directly from Purchase Invoice
+- List view for Products on Website
+- Features Setup is deprecated, settings moved to individual module setup views
+- Added Safety Stock to Item Master
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index fcdff21..3f25e02 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -204,10 +204,10 @@
 		from erpnext.stock.stock_ledger import make_sl_entries
 		make_sl_entries(sl_entries, is_amended, allow_negative_stock, via_landed_cost_voucher)
 
-	def make_gl_entries_on_cancel(self):
+	def make_gl_entries_on_cancel(self, repost_future_gle=True):
 		if frappe.db.sql("""select name from `tabGL Entry` where voucher_type=%s
 			and voucher_no=%s""", (self.doctype, self.name)):
-				self.make_gl_entries()
+				self.make_gl_entries(repost_future_gle)
 
 	def get_serialized_items(self):
 		serialized_items = []
@@ -261,7 +261,7 @@
 
 	future_stock_vouchers = get_future_stock_vouchers(posting_date, posting_time, for_warehouses, for_items)
 	gle = get_voucherwise_gl_entries(future_stock_vouchers, posting_date)
-
+	
 	for voucher_type, voucher_no in future_stock_vouchers:
 		existing_gle = gle.get((voucher_type, voucher_no), [])
 		voucher_obj = frappe.get_doc(voucher_type, voucher_no)
diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py
index 125f4fe..da803cf 100644
--- a/erpnext/controllers/taxes_and_totals.py
+++ b/erpnext/controllers/taxes_and_totals.py
@@ -471,7 +471,8 @@
 
 	def calculate_write_off_amount(self):
 		if flt(self.doc.change_amount) > 0:
-			self.doc.write_off_amount = self.doc.grand_total - self.doc.paid_amount + self.doc.change_amount
+			self.doc.write_off_amount = flt(self.doc.grand_total - self.doc.paid_amount + self.doc.change_amount,
+				self.doc.precision("write_off_amount"))
 			self.doc.base_write_off_amount = flt(self.doc.write_off_amount * self.doc.conversion_rate,
 				self.doc.precision("base_write_off_amount"))
 
diff --git a/erpnext/manufacturing/doctype/operation/operation.py b/erpnext/manufacturing/doctype/operation/operation.py
index 2c75fee..69e8329 100644
--- a/erpnext/manufacturing/doctype/operation/operation.py
+++ b/erpnext/manufacturing/doctype/operation/operation.py
@@ -2,13 +2,9 @@
 # For license information, please see license.txt
 
 from __future__ import unicode_literals
-import frappe
 from frappe.model.document import Document
 
 class Operation(Document):
-	def calculate_op_cost(self):
-		if self.hour_rate and self.time_in_mins:
-			self.operating_cost = flt(self.hour_rate) * flt(self.time_in_mins) / 60.0
-		else :
-			self.operating_cost = 0
-
+	def validate(self):
+		if not self.description:
+			self.description = self.name
diff --git a/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json b/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json
index 3493ccf..00bf934 100644
--- a/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json
+++ b/erpnext/manufacturing/doctype/production_order_operation/production_order_operation.json
@@ -58,7 +58,7 @@
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
-   "reqd": 0, 
+   "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
@@ -85,7 +85,7 @@
    "print_hide_if_no_value": 0, 
    "read_only": 1, 
    "report_hide": 0, 
-   "reqd": 1, 
+   "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
@@ -539,7 +539,7 @@
  "issingle": 0, 
  "istable": 1, 
  "max_attachments": 0, 
- "modified": "2016-07-11 03:28:04.235889", 
+ "modified": "2016-08-22 03:41:42.356833", 
  "modified_by": "Administrator", 
  "module": "Manufacturing", 
  "name": "Production Order Operation", 
diff --git a/erpnext/patches/v7_0/convert_timelog_to_timesheet.py b/erpnext/patches/v7_0/convert_timelog_to_timesheet.py
index b802656..d00980f 100644
--- a/erpnext/patches/v7_0/convert_timelog_to_timesheet.py
+++ b/erpnext/patches/v7_0/convert_timelog_to_timesheet.py
@@ -16,7 +16,6 @@
 		time_sheet = make_timesheet(data.production_order)
 		args = get_timelog_data(data)
 		add_timesheet_detail(time_sheet, args)
-		time_sheet.docstatus = data.docstatus
 		time_sheet.note = data.note
 		time_sheet.company = company
 		
@@ -25,6 +24,15 @@
 		time_sheet.calculate_total_amounts()
 		time_sheet.flags.ignore_validate = True
 		time_sheet.save(ignore_permissions=True)
+		
+		# To ignore validate_mandatory_fields function
+		if data.docstatus == 1:
+			time_sheet.db_set("docstatus", 1)
+			for d in time_sheet.get("time_logs"):
+				d.db_set("docstatus", 1)
+			time_sheet.update_production_order(time_sheet.name)
+			time_sheet.update_task_and_project()
+			
 
 def get_timelog_data(data):
 	return {
diff --git a/erpnext/patches/v7_0/migrate_schools_to_erpnext.py b/erpnext/patches/v7_0/migrate_schools_to_erpnext.py
index f64f400..2aa6f04 100644
--- a/erpnext/patches/v7_0/migrate_schools_to_erpnext.py
+++ b/erpnext/patches/v7_0/migrate_schools_to_erpnext.py
@@ -9,12 +9,13 @@
 	frappe.reload_doc('website', 'doctype', 'portal_menu_item')
 	frappe.reload_doc('buying', 'doctype', 'request_for_quotation')
 
-	if 'schools' in frappe.get_installed_apps():
+	if frappe.db.exists("Module Def", "Academics") \
+			and frappe.db.get_value("Module Def", "Academics", "app_name") == "schools":
 		frappe.db.sql("""delete from `tabDesktop Icon`""")
 		
 		if not frappe.db.exists('Module Def', 'Schools') and frappe.db.exists('Module Def', 'Academics'):
 			frappe.rename_doc("Module Def", "Academics", "Schools")
-			
+
 		remove_from_installed_apps("schools")
 
 def reload_doctypes_for_schools_icons():
diff --git a/erpnext/public/js/payment/payments.js b/erpnext/public/js/payment/payments.js
index 06df425..23db61f 100644
--- a/erpnext/public/js/payment/payments.js
+++ b/erpnext/public/js/payment/payments.js
@@ -112,15 +112,15 @@
 		$(this.$body).find('.form-control').click(function(){
 			me.idx = $(this).attr("idx");
 			me.set_outstanding_amount();
-			me.update_paid_amount();
+			me.update_paid_amount(true);
 		})
 		
 		$(this.$body).find('.write_off_amount').change(function(){
-			me.write_off_amount(flt($(this).val()));
+			me.write_off_amount(flt($(this).val()), precision("write_off_amount"));
 		})
 		
 		$(this.$body).find('.change_amount').change(function(){
-			me.change_amount(flt($(this).val()));
+			me.change_amount(flt($(this).val()), precision("change_amount"));
 		})
 	},
 
@@ -139,7 +139,7 @@
 			me.payment_val += $(this).text();
 			me.selected_mode.val(format_number(me.payment_val, 2))
 			me.idx = me.selected_mode.attr("idx")
-			me.selected_mode.change()
+			me.update_paid_amount()
 		})
 		
 		$(this.$body).find('.delete-btn').click(function(){
@@ -177,31 +177,29 @@
 	write_off_amount: function(write_off_amount) {
 		var me = this;
 
-		if(this.frm.doc.paid_amount > 0){
-			this.frm.doc.write_off_amount = write_off_amount;
-			this.frm.doc.base_write_off_amount = flt(this.frm.doc.write_off_amount * this.frm.doc.conversion_rate,
-				precision("base_write_off_amount"));
-			this.calculate_outstanding_amount(false)
-			this.show_amounts()
-		}
+		this.frm.doc.write_off_amount = flt(write_off_amount, precision("write_off_amount"));
+		this.frm.doc.base_write_off_amount = flt(this.frm.doc.write_off_amount * this.frm.doc.conversion_rate,
+			precision("base_write_off_amount"));
+		this.calculate_outstanding_amount(false)
+		this.show_amounts()
 	},
 
 	change_amount: function(change_amount) {
 		var me = this;
 
-		this.frm.doc.change_amount = change_amount;
+		this.frm.doc.change_amount = flt(change_amount, precision("change_amount"));
 		this.calculate_write_off_amount()
 		this.show_amounts()
 	},
 
-	update_paid_amount: function() {
+	update_paid_amount: function(update_write_off) {
 		var me = this;
 		if(in_list(['change_amount', 'write_off_amount'], this.idx)){
-			value = flt(me.selected_mode.val(), 2)
+			value = me.selected_mode.val();
 			if(me.idx == 'change_amount'){
 				me.change_amount(value)
 			} else{
-				if(value == 0) { 
+				if(value == 0 && update_write_off) {
 					value = me.frm.doc.outstanding_amount;
 				}
 				me.write_off_amount(value)
@@ -226,9 +224,9 @@
 
 	show_amounts: function(){
 		var me = this;
-		$(this.$body).find(".write_off_amount").val(format_number(this.frm.doc.write_off_amount, 2));
+		$(this.$body).find(".write_off_amount").val(format_number(this.frm.doc.write_off_amount, precision("write_off_amount")));
 		$(this.$body).find('.paid_amount').text(format_currency(this.frm.doc.paid_amount, this.frm.doc.currency));
-		$(this.$body).find('.change_amount').val(format_number(this.frm.doc.change_amount, 2))
+		$(this.$body).find('.change_amount').val(format_number(this.frm.doc.change_amount, precision("change_amount")))
 		$(this.$body).find('.outstanding_amount').text(format_currency(this.frm.doc.outstanding_amount, this.frm.doc.currency))
 		this.update_invoice();
 	}
diff --git a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
index ac59e06..cdf7263 100644
--- a/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
+++ b/erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
@@ -84,7 +84,7 @@
 		self.update_landed_cost()
 
 	def update_landed_cost(self):
-		for d in self.get("items"):
+		for d in self.get("purchase_receipts"):
 			doc = frappe.get_doc(d.receipt_document_type, d.receipt_document)
 
 			# set landed cost voucher amount in pr item
@@ -103,7 +103,7 @@
 			# update stock & gl entries for cancelled state of PR
 			doc.docstatus = 2
 			doc.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True)
-			doc.make_gl_entries_on_cancel()
+			doc.make_gl_entries_on_cancel(repost_future_gle=False)
 
 
 			# update stock & gl entries for submit state of PR