Changes for Recurring PO/PI
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
index 49ed12c..680c6a0 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
@@ -232,6 +232,42 @@
 	}
 }
 
+//added by sambhaji
+
+
+cur_frm.cscript.is_recurring = function(doc, dt, dn) {
+	// set default values for recurring invoices
+	if(doc.is_recurring) {
+		var owner_email = doc.owner=="Administrator"
+			? frappe.user_info("Administrator").email
+			: doc.owner;
+
+		doc.notification_email_address = $.map([cstr(owner_email),
+			cstr(doc.contact_email)], function(v) { return v || null; }).join(", ");
+		doc.repeat_on_day_of_month = frappe.datetime.str_to_obj(doc.posting_date).getDate();
+	}
+
+	refresh_many(["notification_email_address", "repeat_on_day_of_month"]);
+}
+
+
+cur_frm.cscript.from_date = function(doc, dt, dn) {
+	// set to_date
+	if(doc.from_date) {
+		var recurring_type_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6,
+			'Yearly': 12};
+
+		var months = recurring_type_map[doc.recurring_type];
+		if(months) {
+			var to_date = frappe.datetime.add_months(doc.from_date,
+				months);
+			doc.to_date = frappe.datetime.add_days(to_date, -1);
+			refresh_field('to_date');
+		}
+	}
+}
+
+//end of added by sambhajii
 
 cur_frm.cscript.select_print_heading = function(doc,cdt,cdn){
 	if(doc.select_print_heading){
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
index 489bc46..dab029f 100755
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
@@ -1,4 +1,5 @@
 {
+ "allow_attach": 1, 
  "allow_import": 1,
  "autoname": "naming_series:",
  "creation": "2013-05-21 16:16:39",
@@ -143,16 +144,34 @@
    "search_index": 1
   },
   {
-   "fieldname": "amended_from",
-   "fieldtype": "Link",
-   "ignore_user_permissions": 1,
-   "label": "Amended From",
-   "no_copy": 1,
-   "oldfieldname": "amended_from",
-   "oldfieldtype": "Link",
-   "options": "Purchase Invoice",
-   "permlevel": 0,
-   "print_hide": 1,
+   "allow_on_submit": 1, 
+   "description": "Start date of current invoice's period", 
+   "fieldname": "from_date", 
+   "fieldtype": "Date", 
+   "label": "From", 
+   "no_copy": 1, 
+   "permlevel": 0
+  }, 
+  {
+   "allow_on_submit": 1, 
+   "description": "End date of current invoice's period", 
+   "fieldname": "to_date", 
+   "fieldtype": "Date", 
+   "label": "To", 
+   "no_copy": 1, 
+   "permlevel": 0
+  }, 
+  {
+   "fieldname": "amended_from", 
+   "fieldtype": "Link", 
+   "ignore_user_permissions": 1, 
+   "label": "Amended From", 
+   "no_copy": 1, 
+   "oldfieldname": "amended_from", 
+   "oldfieldtype": "Link", 
+   "options": "Purchase Invoice", 
+   "permlevel": 0, 
+   "print_hide": 1, 
    "read_only": 1
   },
   {
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 956dacb..7d35f41 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -4,7 +4,10 @@
 from __future__ import unicode_literals
 import frappe
 
-from frappe.utils import cint, cstr, flt, formatdate
+
+from frappe.utils import add_days, cint, cstr, date_diff, formatdate, flt, getdate, nowdate, \
+	get_first_day, get_last_day
+from frappe.model.naming import make_autoname
 
 from frappe import msgprint, _, throw
 from erpnext.setup.utils import get_company_currency
@@ -14,6 +17,8 @@
 from erpnext.controllers.buying_controller import BuyingController
 from erpnext.accounts.party import get_party_account, get_due_date
 
+from erpnext.controllers.recurring_document import *
+
 form_grid_templates = {
 	"entries": "templates/form_grid/item_grid.html"
 }
@@ -61,6 +66,7 @@
 		self.validate_multiple_billing("Purchase Receipt", "pr_detail", "amount",
 			"purchase_receipt_details")
 		self.create_remarks()
+		validate_recurring_document(self)
 
 	def create_remarks(self):
 		if not self.remarks:
@@ -259,6 +265,11 @@
 		self.update_against_document_in_jv()
 		self.update_prevdoc_status()
 		self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
+		convert_to_recurring(self, "RECINV.#####", self.posting_date)
+
+	def on_update_after_submit(self):
+		validate_recurring_document(self)
+		convert_to_recurring(self, "RECINV.#####", self.posting_date)
 
 	def make_gl_entries(self):
 		auto_accounting_for_stock = \
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 9433ebe..071d622 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -205,7 +205,40 @@
 		cur_frm.email_doc(frappe.boot.notification_settings.purchase_order_message);
 	}
 }
+//added by sambhaji
 
+cur_frm.cscript.is_recurring = function(doc, dt, dn) {
+	// set default values for recurring orders
+	if(doc.is_recurring) {
+		var owner_email = doc.owner=="Administrator"
+			? frappe.user_info("Administrator").email
+			: doc.owner;
+
+		doc.notification_email_address = $.map([cstr(owner_email),
+			cstr(doc.contact_email)], function(v) { return v || null; }).join(", ");
+		doc.repeat_on_day_of_month = frappe.datetime.str_to_obj(doc.posting_date).getDate();
+	}
+
+	refresh_many(["notification_email_address", "repeat_on_day_of_month"]);
+}
+
+cur_frm.cscript.from_date = function(doc, dt, dn) {
+	// set to_date
+	if(doc.from_date) {
+		var recurring_type_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6,
+			'Yearly': 12};
+
+		var months = recurring_type_map[doc.recurring_type];
+		if(months) {
+			var to_date = frappe.datetime.add_months(doc.from_date,
+				months);
+			doc.to_date = frappe.datetime.add_days(to_date, -1);
+			refresh_field('to_date');
+		}
+	}
+}
+
+//end of added by sambhaji
 cur_frm.cscript.send_sms = function() {
 	frappe.require("assets/erpnext/js/sms_manager.js");
 	var sms_man = new SMSManager(cur_frm.doc);
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.json b/erpnext/buying/doctype/purchase_order/purchase_order.json
index 647823c..289567f 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.json
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.json
@@ -1,4 +1,5 @@
 {
+  "allow_attach": 1, 
   "allow_import": 1, 
  "autoname": "naming_series:", 
  "creation": "2013-05-21 16:16:39", 
@@ -102,6 +103,24 @@
    "search_index": 1
   }, 
   {
+   "allow_on_submit": 1, 
+   "description": "Start date of current order's period", 
+   "fieldname": "from_date", 
+   "fieldtype": "Date", 
+   "label": "From", 
+   "no_copy": 1, 
+   "permlevel": 0
+  }, 
+  {
+   "allow_on_submit": 1, 
+   "description": "End date of current order's period", 
+   "fieldname": "to_date", 
+   "fieldtype": "Date", 
+   "label": "To", 
+   "no_copy": 1, 
+   "permlevel": 0
+  }, 
+  {
    "fieldname": "amended_from", 
    "fieldtype": "Link", 
    "hidden": 0, 
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 6c7c0c6..beebf0b 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -6,6 +6,9 @@
 from frappe.utils import cstr, flt
 from frappe import msgprint, _, throw
 from frappe.model.mapper import get_mapped_doc
+
+from erpnext.controllers.recurring_document import convert_to_recurring, validate_recurring_document
+
 from erpnext.controllers.buying_controller import BuyingController
 
 form_grid_templates = {
@@ -52,6 +55,8 @@
 		self.validate_for_subcontracting()
 		self.validate_minimum_order_qty()
 		self.create_raw_materials_supplied("po_raw_material_details")
+		
+		validate_recurring_document(self)
 
 	def validate_with_previous_doc(self):
 		super(PurchaseOrder, self).validate_with_previous_doc(self.tname, {
@@ -173,6 +178,8 @@
 		purchase_controller.update_last_purchase_rate(self, is_submit = 1)
 
 		frappe.db.set(self,'status','Submitted')
+		
+		convert_to_recurring(self, "SO/REC/.#####", self.transaction_date)
 
 	def on_cancel(self):
 		pc_obj = frappe.get_doc('Purchase Common')
@@ -197,6 +204,10 @@
 	def on_update(self):
 		pass
 
+def on_update_after_submit(self):
+		validate_recurring_document(self)
+		convert_to_recurring(self, "SO/REC/.#####", self.transaction_date)
+
 def set_missing_values(source, target):
 	target.ignore_pricing_rule = 1
 	target.run_method("set_missing_values")
diff --git a/erpnext/buying/doctype/purchase_order/test_purchase_order.py b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
index d1d183a..0c9f912 100644
--- a/erpnext/buying/doctype/purchase_order/test_purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/test_purchase_order.py
@@ -107,6 +107,11 @@
 		po.get("po_details")[0].qty = 3.4
 		self.assertRaises(UOMMustBeIntegerError, po.insert)
 
+	def test_recurring_order(self):
+		from erpnext.controllers.tests.test_recurring_document import test_recurring_document
+
+		test_recurring_document(self, test_records)
+
 
 test_dependencies = ["BOM"]
 
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 5f418c4..a3f5908 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -4,7 +4,11 @@
 from __future__ import unicode_literals
 import frappe
 from frappe import _, msgprint
-from frappe.utils import flt, rounded
+
+from frappe.utils import add_days, cint, cstr, today, date_diff, flt, rounded, getdate, nowdate, \
+	get_first_day, get_last_day
+from frappe.model.naming import make_autoname
+
 from erpnext.setup.utils import get_company_currency
 from erpnext.accounts.party import get_party_details