From e3d2643f2bae41de6a0aea1ad14f3e907e352566 Mon Sep 17 00:00:00 2001 From: Sambhaji Kolate Date: Wed, 10 Sep 2014 13:07:59 +0530 Subject: [PATCH] Changes for Recurring PO/PI --- .../purchase_invoice/purchase_invoice.js | 36 +++++++++++++++++ .../purchase_invoice/purchase_invoice.json | 39 ++++++++++++++----- .../purchase_invoice/purchase_invoice.py | 13 ++++++- .../doctype/purchase_order/purchase_order.js | 33 ++++++++++++++++ .../purchase_order/purchase_order.json | 19 +++++++++ .../doctype/purchase_order/purchase_order.py | 11 ++++++ .../purchase_order/test_purchase_order.py | 5 +++ erpnext/controllers/buying_controller.py | 6 ++- 8 files changed, 150 insertions(+), 12 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index 49ed12cc24..680c6a0bbd 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -232,6 +232,42 @@ cur_frm.fields_dict['entries'].grid.get_field('project_name').get_query = functi } } +//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 489bc4648a..dab029f191 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 956dacb55f..7d35f41c96 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 @@ import frappe.defaults 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 @@ class PurchaseInvoice(BuyingController): 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 @@ class PurchaseInvoice(BuyingController): 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 9433ebe20c..071d622cdd 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.cscript.on_submit = function(doc, cdt, cdn) { 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 647823cab6..289567f34c 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", @@ -101,6 +102,24 @@ "reqd": 1, "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", diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py index 6c7c0c6d08..beebf0b1fb 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order.py +++ b/erpnext/buying/doctype/purchase_order/purchase_order.py @@ -6,6 +6,9 @@ import frappe 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 @@ class PurchaseOrder(BuyingController): 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 @@ class PurchaseOrder(BuyingController): 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 @@ class PurchaseOrder(BuyingController): 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 d1d183a7a1..0c9f912dbb 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 @@ class TestPurchaseOrder(unittest.TestCase): 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 5f418c4df2..a3f59082f6 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