From 5e50ffa308fe4790f48f15d8cbd23af4d028718a Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 21 May 2013 15:31:32 +0530 Subject: [PATCH 01/14] [fixes] employee query in leave application --- .../leave_application/leave_application.py | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/hr/doctype/leave_application/leave_application.py b/hr/doctype/leave_application/leave_application.py index 6e39751b716..7c47d6a09eb 100755 --- a/hr/doctype/leave_application/leave_application.py +++ b/hr/doctype/leave_application/leave_application.py @@ -335,15 +335,22 @@ def add_holidays(events, start, end, employee, company): def query_for_permitted_employees(doctype, txt, searchfield, start, page_len, filters): txt = "%" + cstr(txt) + "%" - return webnotes.conn.sql("""select name, employee_name from `tabEmployee` emp + if "Leave Approver" in webnotes.user.get_roles(): + condition = """and (exists(select ela.name from `tabEmployee Leave Approver` ela + where ela.parent=`tabEmployee`.name and ela.leave_approver= "%s") or + not exists(select ela.name from `tabEmployee Leave Approver` ela + where ela.parent=`tabEmployee`.name) + or user_id = "%s")""" % (webnotes.session.user, webnotes.session.user) + else: + from webnotes.widgets.reportview import build_match_conditions + condition = build_match_conditions("Employee") + condition = ("and " + condition) if condition else "" + + return webnotes.conn.sql("""select name, employee_name from `tabEmployee` where status = 'Active' and docstatus < 2 and - (`%s` like %s or employee_name like %s) and - (exists(select ela.name from `tabEmployee Leave Approver` ela - where ela.parent=emp.name and ela.leave_approver=%s) or - not exists(select ela.name from `tabEmployee Leave Approver` ela where ela.parent=emp.name) - or user_id = %s) + (`%s` like %s or employee_name like %s) %s order by case when name like %s then 0 else 1 end, case when employee_name like %s then 0 else 1 end, - name limit %s, %s""" % tuple([searchfield] + ["%s"]*8), - (txt, txt, webnotes.session.user, webnotes.session.user, txt, txt, start, page_len)) + name limit %s, %s""" % tuple([searchfield] + ["%s"]*2 + [condition] + ["%s"]*4), + (txt, txt, txt, txt, start, page_len)) From e2089fb7122e05f6722adf134ba9ef0907361150 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 21 May 2013 16:53:31 +0530 Subject: [PATCH 02/14] [fixes] set lead, contact and company on support ticket --- .../support_ticket/get_support_mails.py | 4 +- .../doctype/support_ticket/support_ticket.py | 24 ++++++-- .../doctype/support_ticket/support_ticket.txt | 59 +++++++------------ 3 files changed, 41 insertions(+), 46 deletions(-) diff --git a/support/doctype/support_ticket/get_support_mails.py b/support/doctype/support_ticket/get_support_mails.py index d1fe0dc8daf..82ae9a34b6e 100644 --- a/support/doctype/support_ticket/get_support_mails.py +++ b/support/doctype/support_ticket/get_support_mails.py @@ -50,7 +50,7 @@ class SupportMailbox(POP3Mailbox): "subject": mail.mail["Subject"], "raised_by": mail.from_email, "content_type": mail.content_type, - "status": "Open" + "status": "Open", }]) ticket.insert() new_ticket = True @@ -58,7 +58,7 @@ class SupportMailbox(POP3Mailbox): mail.save_attachments_in_doc(ticket.doc) make(content=mail.content, sender=mail.from_email, subject = ticket.doc.subject, - doctype="Support Ticket", name=ticket.doc.name, + doctype="Support Ticket", name=ticket.doc.name, lead = ticket.doc.lead, contact=ticket.doc.contact, date=mail.date) if new_ticket and cint(self.email_settings.send_autoreply) and \ diff --git a/support/doctype/support_ticket/support_ticket.py b/support/doctype/support_ticket/support_ticket.py index ca46a8e073c..5f01516ba06 100644 --- a/support/doctype/support_ticket/support_ticket.py +++ b/support/doctype/support_ticket/support_ticket.py @@ -18,7 +18,6 @@ from __future__ import unicode_literals import webnotes from utilities.transaction_base import TransactionBase -from home import update_feed from webnotes.utils import now class DocType(TransactionBase): @@ -44,6 +43,7 @@ class DocType(TransactionBase): def validate(self): self.update_status() + self.set_lead_contact(self.doc.raised_by) if self.doc.status == "Closed": from webnotes.widgets.form.assign_to import clear @@ -51,10 +51,24 @@ class DocType(TransactionBase): def on_communication_sent(self, comm): webnotes.conn.set(self.doc, 'status', 'Waiting for Customer') - if comm.lead and not self.doc.lead: - webnotes.conn.set(self.doc, 'lead', comm.lead) - if comm.contact and not self.doc.contact: - webnotes.conn.set(self.doc, 'contact', comm.contact) + + + def set_lead_contact(self, email_id): + import email.utils + email_id = email.utils.parseaddr(email_id) + if email_id: + if not self.doc.lead: + self.doc.lead = webnotes.conn.get_value("Lead", {"email_id": email_id}) + if not self.doc.contact: + self.doc.contact = webnotes.conn.get_value("Contact", {"email_id": email_id}) + + if not self.doc.company: + if self.doc.lead: + company = webnotes.conn.get_value("Lead", self.doc.lead, "company") + elif self.doc.contact: + company = webnotes.conn.get_value("Contact", self.doc.contact, "company") + + self.doc.company = company or webnotes.conn.get_default("company") def on_trash(self): webnotes.conn.sql("""update `tabCommunication` set support_ticket=NULL diff --git a/support/doctype/support_ticket/support_ticket.txt b/support/doctype/support_ticket/support_ticket.txt index 769bb9d7017..50e547ece7a 100644 --- a/support/doctype/support_ticket/support_ticket.txt +++ b/support/doctype/support_ticket/support_ticket.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-01-31 22:22:27", + "creation": "2013-02-01 10:36:25", "docstatus": 0, - "modified": "2013-01-31 22:17:24", + "modified": "2013-05-21 16:27:46", "modified_by": "Administrator", "owner": "Administrator" }, @@ -23,13 +23,18 @@ "permlevel": 0 }, { + "amend": 0, + "create": 1, "doctype": "DocPerm", "name": "__common__", "parent": "Support Ticket", "parentfield": "permissions", "parenttype": "DocType", + "permlevel": 0, "read": 1, - "submit": 0 + "report": 1, + "submit": 0, + "write": 1 }, { "doctype": "DocType", @@ -191,6 +196,15 @@ "oldfieldtype": "Time", "read_only": 1 }, + { + "doctype": "DocField", + "fieldname": "company", + "fieldtype": "Link", + "label": "Company", + "options": "Company", + "print_hide": 1, + "reqd": 0 + }, { "depends_on": "eval:!doc.__islocal", "doctype": "DocField", @@ -237,51 +251,18 @@ "label": "Content Type" }, { - "amend": 0, "cancel": 0, - "create": 1, "doctype": "DocPerm", - "permlevel": 0, - "report": 1, - "role": "Guest", - "write": 1 + "role": "Guest" }, { - "create": 1, + "cancel": 0, "doctype": "DocPerm", - "match": "customer", - "permlevel": 0, - "report": 1, - "role": "Customer", - "write": 1 + "role": "Customer" }, { "cancel": 1, - "create": 1, "doctype": "DocPerm", - "permlevel": 0, - "report": 1, - "role": "Support Team", - "write": 1 - }, - { - "amend": 0, - "cancel": 0, - "create": 0, - "doctype": "DocPerm", - "match": "", - "permlevel": 1, - "report": 1, - "role": "Support Team", - "write": 1 - }, - { - "amend": 0, - "cancel": 0, - "create": 0, - "doctype": "DocPerm", - "match": "", - "permlevel": 2, "role": "Support Team" } ] \ No newline at end of file From cb9904576427a1b0fe0487b9cb47044c9a91ea36 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 21 May 2013 17:17:40 +0530 Subject: [PATCH 03/14] [patch] update lead, contact in support ticket --- patches/may_2013/p03_update_support_ticket.py | 25 +++++++++++++++++++ patches/patch_list.py | 1 + .../doctype/support_ticket/support_ticket.py | 10 +++----- 3 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 patches/may_2013/p03_update_support_ticket.py diff --git a/patches/may_2013/p03_update_support_ticket.py b/patches/may_2013/p03_update_support_ticket.py new file mode 100644 index 00000000000..bbdb6e24ec5 --- /dev/null +++ b/patches/may_2013/p03_update_support_ticket.py @@ -0,0 +1,25 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import unicode_literals +import webnotes +def execute(): + for d in webnotes.conn.sql("""select name, raised_by from `tabSupport Ticket` + where docstatus < 2""", as_dict=True): + tic = webnotes.get_obj("Support Ticket", d.name) + tic.set_lead_contact(d.raised_by) + webnotes.conn.sql("""update `tabSupport Ticket` set lead = %s, contact = %s, company = %s + where name = %s""", (tic.doc.lead, tic.doc.contact, tic.doc.company, d.name)) \ No newline at end of file diff --git a/patches/patch_list.py b/patches/patch_list.py index bd7acb2fc69..f28751c8183 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -249,4 +249,5 @@ patch_list = [ "patches.may_2013.repost_stock_for_no_posting_time", "patches.may_2013.p01_conversion_factor_and_aii", "patches.may_2013.p02_update_valuation_rate", + "patches.may_2013.p03_update_support_ticket", ] \ No newline at end of file diff --git a/support/doctype/support_ticket/support_ticket.py b/support/doctype/support_ticket/support_ticket.py index 5f01516ba06..63548d3436d 100644 --- a/support/doctype/support_ticket/support_ticket.py +++ b/support/doctype/support_ticket/support_ticket.py @@ -62,13 +62,9 @@ class DocType(TransactionBase): if not self.doc.contact: self.doc.contact = webnotes.conn.get_value("Contact", {"email_id": email_id}) - if not self.doc.company: - if self.doc.lead: - company = webnotes.conn.get_value("Lead", self.doc.lead, "company") - elif self.doc.contact: - company = webnotes.conn.get_value("Contact", self.doc.contact, "company") - - self.doc.company = company or webnotes.conn.get_default("company") + if not self.doc.company: + self.doc.company = webnotes.conn.get_value("Lead", self.doc.lead, "company") or \ + webnotes.conn.get_default("company") def on_trash(self): webnotes.conn.sql("""update `tabCommunication` set support_ticket=NULL From b7e07ac6a5ce39a77d5337a515254993e1258175 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 22 May 2013 12:10:16 +0530 Subject: [PATCH 04/14] [fixes] updated no_copy field --- .../purchase_invoice_item.txt | 8 ++- .../sales_invoice_item/sales_invoice_item.txt | 8 ++- .../purchase_order_item.txt | 38 ++++++++++---- .../supplier_quotation_item.txt | 34 ++++++++---- .../doctype/quotation_item/quotation_item.txt | 13 ++++- .../sales_order_item/sales_order_item.txt | 15 +++++- .../delivery_note_item/delivery_note_item.txt | 7 ++- .../purchase_receipt_item.txt | 52 ++++++++++++++----- 8 files changed, 132 insertions(+), 43 deletions(-) diff --git a/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt b/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt index e33ab7c5698..8df4306f57b 100755 --- a/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt +++ b/accounts/doctype/purchase_invoice_item/purchase_invoice_item.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-04-10 08:35:38", + "creation": "2013-04-19 11:00:07", "docstatus": 0, - "modified": "2013-04-17 14:05:20", + "modified": "2013-05-22 12:01:56", "modified_by": "Administrator", "owner": "Administrator" }, @@ -224,6 +224,7 @@ "fieldtype": "Link", "in_filter": 1, "label": "Pur Order", + "no_copy": 1, "oldfieldname": "purchase_order", "oldfieldtype": "Link", "options": "Purchase Order", @@ -238,6 +239,7 @@ "hidden": 1, "in_filter": 1, "label": "Purchase Order Item", + "no_copy": 1, "oldfieldname": "po_detail", "oldfieldtype": "Data", "print_hide": 1, @@ -250,6 +252,7 @@ "fieldtype": "Link", "in_filter": 1, "label": "Pur Receipt", + "no_copy": 1, "oldfieldname": "purchase_receipt", "oldfieldtype": "Link", "options": "Purchase Receipt", @@ -264,6 +267,7 @@ "hidden": 1, "in_filter": 1, "label": "PR Detail", + "no_copy": 1, "oldfieldname": "pr_detail", "oldfieldtype": "Data", "print_hide": 1, diff --git a/accounts/doctype/sales_invoice_item/sales_invoice_item.txt b/accounts/doctype/sales_invoice_item/sales_invoice_item.txt index 2a6384d7629..89c86f82196 100644 --- a/accounts/doctype/sales_invoice_item/sales_invoice_item.txt +++ b/accounts/doctype/sales_invoice_item/sales_invoice_item.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-04-10 08:35:44", + "creation": "2013-04-19 11:00:07", "docstatus": 0, - "modified": "2013-04-17 14:05:20", + "modified": "2013-05-22 12:06:15", "modified_by": "Administrator", "owner": "Administrator" }, @@ -305,6 +305,7 @@ "fieldtype": "Link", "in_filter": 1, "label": "Sales Order", + "no_copy": 1, "oldfieldname": "sales_order", "oldfieldtype": "Link", "options": "Sales Order", @@ -319,6 +320,7 @@ "hidden": 1, "in_filter": 1, "label": "SO Detail ", + "no_copy": 1, "oldfieldname": "so_detail", "oldfieldtype": "Data", "print_hide": 1, @@ -331,6 +333,7 @@ "fieldtype": "Link", "in_filter": 1, "label": "Delivery Note", + "no_copy": 1, "oldfieldname": "delivery_note", "oldfieldtype": "Link", "options": "Delivery Note", @@ -345,6 +348,7 @@ "hidden": 1, "in_filter": 1, "label": "DN Detail", + "no_copy": 1, "oldfieldname": "dn_detail", "oldfieldtype": "Data", "print_hide": 1, diff --git a/buying/doctype/purchase_order_item/purchase_order_item.txt b/buying/doctype/purchase_order_item/purchase_order_item.txt index cd00f872534..01a144a1433 100755 --- a/buying/doctype/purchase_order_item/purchase_order_item.txt +++ b/buying/doctype/purchase_order_item/purchase_order_item.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-02-22 01:27:42", + "creation": "2013-03-07 11:42:55", "docstatus": 0, - "modified": "2013-03-07 07:03:27", + "modified": "2013-05-22 11:59:52", "modified_by": "Administrator", "owner": "Administrator" }, @@ -36,6 +36,7 @@ "oldfieldname": "schedule_date", "oldfieldtype": "Date", "print_hide": 1, + "read_only": 0, "reqd": 1, "search_index": 1 }, @@ -49,6 +50,7 @@ "oldfieldtype": "Link", "options": "Item", "print_hide": 0, + "read_only": 0, "reqd": 1, "search_index": 1 }, @@ -72,6 +74,7 @@ "oldfieldname": "item_name", "oldfieldtype": "Data", "print_hide": 1, + "read_only": 0, "reqd": 1, "search_index": 1 }, @@ -83,6 +86,7 @@ "oldfieldname": "description", "oldfieldtype": "Small Text", "print_width": "300px", + "read_only": 0, "reqd": 1, "width": "300px" }, @@ -95,6 +99,7 @@ "oldfieldname": "qty", "oldfieldtype": "Currency", "print_width": "60px", + "read_only": 0, "reqd": 1, "width": "60px" }, @@ -108,6 +113,7 @@ "options": "UOM", "print_hide": 0, "print_width": "100px", + "read_only": 0, "reqd": 1, "width": "100px" }, @@ -117,14 +123,16 @@ "fieldtype": "Currency", "label": "Ref Rate ", "options": "currency", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", "fieldname": "discount_rate", "fieldtype": "Float", "label": "Discount %", - "print_hide": 0 + "print_hide": 0, + "read_only": 0 }, { "doctype": "DocField", @@ -135,7 +143,8 @@ "oldfieldname": "import_rate", "oldfieldtype": "Currency", "options": "currency", - "print_hide": 0 + "print_hide": 0, + "read_only": 0 }, { "doctype": "DocField", @@ -153,7 +162,8 @@ "fieldtype": "Currency", "label": "Ref Rate*", "options": "Company:company:default_currency", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "default": "0.00", @@ -166,6 +176,7 @@ "options": "Company:company:default_currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 1, "width": "100px" }, @@ -192,6 +203,7 @@ "oldfieldtype": "Link", "options": "Warehouse", "print_hide": 1, + "read_only": 0, "reqd": 0 }, { @@ -202,6 +214,7 @@ "label": "Project Name", "options": "Project", "print_hide": 1, + "read_only": 0, "report_hide": 0 }, { @@ -214,6 +227,7 @@ "oldfieldtype": "Currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 1, "width": "100px" }, @@ -237,7 +251,7 @@ "fieldtype": "Data", "hidden": 1, "label": "Prevdoc DocType", - "no_copy": 0, + "no_copy": 1, "oldfieldname": "prevdoc_doctype", "oldfieldtype": "Data", "print_hide": 1, @@ -250,7 +264,7 @@ "hidden": 0, "in_filter": 1, "label": "Material Request No", - "no_copy": 0, + "no_copy": 1, "oldfieldname": "prevdoc_docname", "oldfieldtype": "Link", "options": "Material Request", @@ -267,6 +281,7 @@ "hidden": 1, "in_filter": 1, "label": "Material Request Date", + "no_copy": 1, "oldfieldname": "prevdoc_date", "oldfieldtype": "Date", "print_hide": 1, @@ -280,7 +295,7 @@ "hidden": 1, "in_filter": 1, "label": "Material Request Detail No", - "no_copy": 0, + "no_copy": 1, "oldfieldname": "prevdoc_detail_docname", "oldfieldtype": "Data", "print_hide": 1, @@ -294,6 +309,7 @@ "hidden": 1, "in_filter": 0, "label": "Supplier Quotation", + "no_copy": 1, "options": "Supplier Quotation", "read_only": 1, "search_index": 0 @@ -304,6 +320,7 @@ "fieldtype": "Link", "hidden": 1, "label": "Supplier Quotation Item", + "no_copy": 1, "options": "Supplier Quotation Item", "read_only": 1 }, @@ -395,6 +412,7 @@ "no_copy": 1, "oldfieldname": "page_break", "oldfieldtype": "Check", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 } ] \ No newline at end of file diff --git a/buying/doctype/supplier_quotation_item/supplier_quotation_item.txt b/buying/doctype/supplier_quotation_item/supplier_quotation_item.txt index 53fa9f8d953..6b24d2f86f9 100644 --- a/buying/doctype/supplier_quotation_item/supplier_quotation_item.txt +++ b/buying/doctype/supplier_quotation_item/supplier_quotation_item.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-02-22 01:27:43", + "creation": "2013-03-07 11:42:56", "docstatus": 0, - "modified": "2013-03-07 07:03:32", + "modified": "2013-05-22 12:02:28", "modified_by": "Administrator", "owner": "Administrator" }, @@ -35,6 +35,7 @@ "oldfieldtype": "Link", "options": "Item", "print_hide": 0, + "read_only": 0, "reqd": 1, "search_index": 1 }, @@ -58,6 +59,7 @@ "oldfieldname": "item_name", "oldfieldtype": "Data", "print_hide": 1, + "read_only": 0, "reqd": 1, "search_index": 1 }, @@ -69,6 +71,7 @@ "oldfieldname": "description", "oldfieldtype": "Small Text", "print_width": "300px", + "read_only": 0, "reqd": 1, "width": "300px" }, @@ -81,6 +84,7 @@ "oldfieldname": "qty", "oldfieldtype": "Currency", "print_width": "60px", + "read_only": 0, "reqd": 1, "width": "60px" }, @@ -94,6 +98,7 @@ "options": "UOM", "print_hide": 0, "print_width": "100px", + "read_only": 0, "reqd": 1, "width": "100px" }, @@ -103,14 +108,16 @@ "fieldtype": "Currency", "label": "Ref Rate ", "options": "currency", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", "fieldname": "discount_rate", "fieldtype": "Float", "label": "Discount %", - "print_hide": 0 + "print_hide": 0, + "read_only": 0 }, { "doctype": "DocField", @@ -121,7 +128,8 @@ "oldfieldname": "import_rate", "oldfieldtype": "Currency", "options": "currency", - "print_hide": 0 + "print_hide": 0, + "read_only": 0 }, { "doctype": "DocField", @@ -139,7 +147,8 @@ "fieldtype": "Currency", "label": "Ref Rate*", "options": "Company:company:default_currency", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "default": "0.00", @@ -152,6 +161,7 @@ "options": "Company:company:default_currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 1, "width": "100px" }, @@ -178,6 +188,7 @@ "oldfieldtype": "Link", "options": "Warehouse", "print_hide": 1, + "read_only": 0, "reqd": 0 }, { @@ -188,6 +199,7 @@ "label": "Project Name", "options": "Project", "print_hide": 1, + "read_only": 0, "report_hide": 0 }, { @@ -196,7 +208,7 @@ "fieldtype": "Data", "hidden": 1, "label": "Prevdoc DocType", - "no_copy": 0, + "no_copy": 1, "oldfieldname": "prevdoc_doctype", "oldfieldtype": "Data", "print_hide": 1, @@ -209,7 +221,7 @@ "hidden": 0, "in_filter": 1, "label": "Material Request No", - "no_copy": 0, + "no_copy": 1, "oldfieldname": "prevdoc_docname", "oldfieldtype": "Link", "options": "Material Request", @@ -226,6 +238,7 @@ "hidden": 1, "in_filter": 1, "label": "Material Request Date", + "no_copy": 1, "oldfieldname": "prevdoc_date", "oldfieldtype": "Date", "print_hide": 1, @@ -239,7 +252,7 @@ "hidden": 1, "in_filter": 1, "label": "Material Request Detail No", - "no_copy": 0, + "no_copy": 1, "oldfieldname": "prevdoc_detail_docname", "oldfieldtype": "Data", "print_hide": 1, @@ -295,6 +308,7 @@ "no_copy": 1, "oldfieldname": "page_break", "oldfieldtype": "Check", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 } ] \ No newline at end of file diff --git a/selling/doctype/quotation_item/quotation_item.txt b/selling/doctype/quotation_item/quotation_item.txt index dccc5037643..bcb9281cb96 100644 --- a/selling/doctype/quotation_item/quotation_item.txt +++ b/selling/doctype/quotation_item/quotation_item.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-02-22 01:27:52", + "creation": "2013-03-07 11:42:57", "docstatus": 0, - "modified": "2013-03-07 07:03:29", + "modified": "2013-05-22 12:08:32", "modified_by": "Administrator", "owner": "Administrator" }, @@ -37,6 +37,7 @@ "options": "Item", "print_hide": 0, "print_width": "150px", + "read_only": 0, "reqd": 1, "search_index": 1, "width": "150px" @@ -60,6 +61,7 @@ "oldfieldtype": "Data", "print_hide": 1, "print_width": "150px", + "read_only": 0, "reqd": 1, "search_index": 1, "width": "150px" @@ -73,6 +75,7 @@ "oldfieldtype": "Small Text", "print_hide": 0, "print_width": "300px", + "read_only": 0, "reqd": 1, "width": "300px" }, @@ -87,6 +90,7 @@ "oldfieldtype": "Currency", "print_hide": 0, "print_width": "100px", + "read_only": 0, "reqd": 1, "search_index": 0, "width": "100px" @@ -115,6 +119,7 @@ "options": "currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 0, "width": "100px" }, @@ -128,6 +133,7 @@ "oldfieldtype": "Float", "print_hide": 1, "print_width": "100px", + "read_only": 0, "width": "100px" }, { @@ -142,6 +148,7 @@ "options": "currency", "print_hide": 0, "print_width": "100px", + "read_only": 0, "reqd": 0, "search_index": 0, "width": "100px" @@ -188,6 +195,7 @@ "options": "Company:company:default_currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 0, "search_index": 0, "width": "100px" @@ -291,6 +299,7 @@ "oldfieldname": "page_break", "oldfieldtype": "Check", "print_hide": 1, + "read_only": 0, "report_hide": 1 } ] \ No newline at end of file diff --git a/selling/doctype/sales_order_item/sales_order_item.txt b/selling/doctype/sales_order_item/sales_order_item.txt index fff2d080f3b..c65ac0d9385 100644 --- a/selling/doctype/sales_order_item/sales_order_item.txt +++ b/selling/doctype/sales_order_item/sales_order_item.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-02-22 01:27:52", + "creation": "2013-03-07 11:42:58", "docstatus": 0, - "modified": "2013-03-07 07:03:30", + "modified": "2013-05-22 12:09:03", "modified_by": "Administrator", "owner": "Administrator" }, @@ -35,6 +35,7 @@ "oldfieldtype": "Link", "options": "Item", "print_width": "150px", + "read_only": 0, "reqd": 1, "search_index": 1, "width": "150px" @@ -57,6 +58,7 @@ "oldfieldtype": "Data", "print_hide": 1, "print_width": "150", + "read_only": 0, "reqd": 1, "width": "150" }, @@ -69,6 +71,7 @@ "oldfieldname": "description", "oldfieldtype": "Small Text", "print_width": "300px", + "read_only": 0, "reqd": 1, "search_index": 1, "width": "300px" @@ -82,6 +85,7 @@ "oldfieldname": "qty", "oldfieldtype": "Currency", "print_width": "100px", + "read_only": 0, "reqd": 1, "width": "100px" }, @@ -109,6 +113,7 @@ "options": "currency", "print_hide": 1, "print_width": "70px", + "read_only": 0, "reqd": 0, "width": "70px" }, @@ -122,6 +127,7 @@ "oldfieldtype": "Float", "print_hide": 1, "print_width": "70px", + "read_only": 0, "width": "70px" }, { @@ -134,6 +140,7 @@ "oldfieldtype": "Currency", "options": "currency", "print_width": "100px", + "read_only": 0, "reqd": 0, "width": "100px" }, @@ -176,6 +183,7 @@ "options": "Company:company:default_currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 0, "width": "100px" }, @@ -206,6 +214,7 @@ "options": "Warehouse", "print_hide": 1, "print_width": "150px", + "read_only": 0, "reqd": 0, "width": "150px" }, @@ -329,6 +338,7 @@ "hidden": 0, "in_filter": 1, "label": "Quotation No.", + "no_copy": 1, "oldfieldname": "prevdoc_docname", "oldfieldtype": "Link", "options": "Quotation", @@ -345,6 +355,7 @@ "oldfieldname": "page_break", "oldfieldtype": "Check", "print_hide": 1, + "read_only": 0, "report_hide": 1 }, { diff --git a/stock/doctype/delivery_note_item/delivery_note_item.txt b/stock/doctype/delivery_note_item/delivery_note_item.txt index 1073f0cdc25..f90ba69f532 100644 --- a/stock/doctype/delivery_note_item/delivery_note_item.txt +++ b/stock/doctype/delivery_note_item/delivery_note_item.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-04-01 10:49:21", + "creation": "2013-04-22 13:15:44", "docstatus": 0, - "modified": "2013-04-17 17:20:58", + "modified": "2013-05-22 12:05:32", "modified_by": "Administrator", "owner": "Administrator" }, @@ -340,6 +340,7 @@ "hidden": 1, "in_filter": 1, "label": "Document Type", + "no_copy": 1, "oldfieldname": "prevdoc_doctype", "oldfieldtype": "Data", "print_hide": 1, @@ -371,6 +372,7 @@ "hidden": 1, "in_filter": 1, "label": "Against Document Date", + "no_copy": 1, "oldfieldname": "prevdoc_date", "oldfieldtype": "Date", "print_hide": 1, @@ -383,6 +385,7 @@ "hidden": 1, "in_filter": 1, "label": "Against Document Detail No", + "no_copy": 1, "oldfieldname": "prevdoc_detail_docname", "oldfieldtype": "Data", "print_hide": 1, diff --git a/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt b/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt index 7f4e827aa30..8cef6a35340 100755 --- a/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt +++ b/stock/doctype/purchase_receipt_item/purchase_receipt_item.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-02-22 01:28:03", + "creation": "2013-03-07 11:42:59", "docstatus": 0, - "modified": "2013-03-07 07:03:28", + "modified": "2013-05-22 12:01:08", "modified_by": "Administrator", "owner": "Administrator" }, @@ -35,6 +35,7 @@ "oldfieldtype": "Link", "options": "Item", "print_width": "100px", + "read_only": 0, "reqd": 1, "search_index": 1, "width": "100px" @@ -48,6 +49,7 @@ "oldfieldname": "item_name", "oldfieldtype": "Data", "print_hide": 1, + "read_only": 0, "reqd": 1, "search_index": 0 }, @@ -59,6 +61,7 @@ "oldfieldname": "description", "oldfieldtype": "Text", "print_width": "300px", + "read_only": 0, "reqd": 1, "width": "300px" }, @@ -72,6 +75,7 @@ "oldfieldtype": "Currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 1, "width": "100px" }, @@ -84,6 +88,7 @@ "oldfieldname": "qty", "oldfieldtype": "Currency", "print_width": "100px", + "read_only": 0, "width": "100px" }, { @@ -97,6 +102,7 @@ "oldfieldtype": "Currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "search_index": 0, "width": "100px" }, @@ -110,6 +116,7 @@ "options": "UOM", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 1, "width": "100px" }, @@ -119,14 +126,16 @@ "fieldtype": "Currency", "label": "Ref Rate ", "options": "currency", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", "fieldname": "discount_rate", "fieldtype": "Float", "label": "Discount %", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "default": "0.00", @@ -139,6 +148,7 @@ "options": "currency", "print_hide": 0, "print_width": "100px", + "read_only": 0, "width": "100px" }, { @@ -157,7 +167,8 @@ "fieldtype": "Currency", "label": "Ref Rate*", "options": "Company:company:default_currency", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "default": "0.00", @@ -170,6 +181,7 @@ "options": "Company:company:default_currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 1, "width": "100px" }, @@ -184,6 +196,7 @@ "options": "Company:company:default_currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 0, "width": "100px" }, @@ -198,6 +211,7 @@ "options": "Warehouse", "print_hide": 1, "print_width": "100px", + "read_only": 0, "width": "100px" }, { @@ -209,6 +223,7 @@ "oldfieldtype": "Currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "reqd": 1, "width": "100px" }, @@ -235,6 +250,7 @@ "oldfieldname": "serial_no", "oldfieldtype": "Text", "print_hide": 0, + "read_only": 0, "report_hide": 0 }, { @@ -242,7 +258,8 @@ "fieldname": "rejected_serial_no", "fieldtype": "Text", "label": "Rejected Serial No", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -252,7 +269,8 @@ "oldfieldname": "batch_no", "oldfieldtype": "Link", "options": "Batch", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -278,6 +296,7 @@ "oldfieldname": "schedule_date", "oldfieldtype": "Date", "print_hide": 1, + "read_only": 0, "report_hide": 0, "reqd": 0 }, @@ -288,7 +307,8 @@ "in_filter": 1, "label": "Project Name", "options": "Project", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -299,7 +319,8 @@ "oldfieldname": "qa_no", "oldfieldtype": "Link", "options": "Quality Inspection", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -336,6 +357,7 @@ "oldfieldtype": "Currency", "print_hide": 1, "print_width": "100px", + "read_only": 0, "width": "100px" }, { @@ -344,9 +366,11 @@ "fieldtype": "Data", "hidden": 1, "label": "Prevdoc Doctype", + "no_copy": 1, "oldfieldname": "prevdoc_doctype", "oldfieldtype": "Data", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -355,7 +379,7 @@ "hidden": 0, "in_filter": 1, "label": "PO No", - "no_copy": 0, + "no_copy": 1, "oldfieldname": "prevdoc_docname", "oldfieldtype": "Link", "options": "Purchase Order", @@ -373,6 +397,7 @@ "hidden": 1, "in_filter": 1, "label": "PO Date", + "no_copy": 1, "oldfieldname": "prevdoc_date", "oldfieldtype": "Date", "print_hide": 1, @@ -418,7 +443,7 @@ "hidden": 1, "in_filter": 1, "label": "Purchase Order Item No", - "no_copy": 0, + "no_copy": 1, "oldfieldname": "prevdoc_detail_docname", "oldfieldtype": "Data", "print_hide": 1, @@ -479,6 +504,7 @@ "label": "Page Break", "oldfieldname": "page_break", "oldfieldtype": "Check", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 } ] \ No newline at end of file From dcfb4b7ab93d39361557e507474676c8871e25b9 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 22 May 2013 12:14:31 +0530 Subject: [PATCH 05/14] [website] [fix] explicitly pass meta description --- setup/doctype/item_group/item_group.py | 1 + website/doctype/blog_post/blog_post.py | 2 ++ website/doctype/web_page/web_page.py | 2 ++ 3 files changed, 5 insertions(+) diff --git a/setup/doctype/item_group/item_group.py b/setup/doctype/item_group/item_group.py index 1445f3999fc..1ff3d4a9397 100644 --- a/setup/doctype/item_group/item_group.py +++ b/setup/doctype/item_group/item_group.py @@ -81,3 +81,4 @@ class DocType(DocTypeNestedSet): if self.doc.slideshow: from website.helpers.slideshow import get_slideshow get_slideshow(self) + \ No newline at end of file diff --git a/website/doctype/blog_post/blog_post.py b/website/doctype/blog_post/blog_post.py index 05236a1ca25..62cc910860d 100644 --- a/website/doctype/blog_post/blog_post.py +++ b/website/doctype/blog_post/blog_post.py @@ -76,10 +76,12 @@ class DocType: self.doc.full_name = get_fullname(self.doc.owner) self.doc.updated = global_date_format(self.doc.published_on) self.doc.content_html = self.doc.content + if self.doc.blogger: self.doc.blogger_info = webnotes.doc("Blogger", self.doc.blogger).fields self.doc.description = self.doc.blog_intro or self.doc.content[:140] + self.doc.meta_description = self.doc.description self.doc.categories = webnotes.conn.sql_list("select name from `tabBlog Category` order by name") diff --git a/website/doctype/web_page/web_page.py b/website/doctype/web_page/web_page.py index d43bcb4e3d7..6d0cafaf6af 100644 --- a/website/doctype/web_page/web_page.py +++ b/website/doctype/web_page/web_page.py @@ -44,3 +44,5 @@ class DocType(): if self.doc.slideshow: from website.helpers.slideshow import get_slideshow get_slideshow(self) + + self.doc.meta_description = self.doc.description From ace9cbad9ecbc7947b2a2831580a001cc9f8ede7 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 22 May 2013 12:22:29 +0530 Subject: [PATCH 06/14] [support] [fix] [patch] reload support ticket and communication before the patch --- patches/may_2013/p03_update_support_ticket.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/patches/may_2013/p03_update_support_ticket.py b/patches/may_2013/p03_update_support_ticket.py index bbdb6e24ec5..7dc5854b44e 100644 --- a/patches/may_2013/p03_update_support_ticket.py +++ b/patches/may_2013/p03_update_support_ticket.py @@ -17,6 +17,8 @@ from __future__ import unicode_literals import webnotes def execute(): + webnotes.reload_doc("support", "doctype", "support_ticket") + webnotes.reload_doc("core", "doctype", "communication") for d in webnotes.conn.sql("""select name, raised_by from `tabSupport Ticket` where docstatus < 2""", as_dict=True): tic = webnotes.get_obj("Support Ticket", d.name) From 6241012f08157d2d3c58b020566699bdfdae4de1 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 22 May 2013 12:37:50 +0530 Subject: [PATCH 07/14] [website] [slideshow] clear website cache on update of a slide show --- website/doctype/website_slideshow/website_slideshow.py | 7 ++++++- website/templates/html/slideshow.html | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/website/doctype/website_slideshow/website_slideshow.py b/website/doctype/website_slideshow/website_slideshow.py index 928aa9ff9f2..86bd2a0433a 100644 --- a/website/doctype/website_slideshow/website_slideshow.py +++ b/website/doctype/website_slideshow/website_slideshow.py @@ -5,4 +5,9 @@ import webnotes class DocType: def __init__(self, d, dl): - self.doc, self.doclist = d, dl \ No newline at end of file + self.doc, self.doclist = d, dl + + def on_update(self): + # a slide show can be in use and any change in it should get reflected + from webnotes.webutils import clear_cache + clear_cache() \ No newline at end of file diff --git a/website/templates/html/slideshow.html b/website/templates/html/slideshow.html index e0e9038d9fd..b26338c5e59 100644 --- a/website/templates/html/slideshow.html +++ b/website/templates/html/slideshow.html @@ -8,7 +8,7 @@ {% if slide.heading or slide.description %} {% endif %} From 488a821534099ffde11da31c72fbde1fabaa2e66 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 22 May 2013 15:51:47 +0530 Subject: [PATCH 08/14] [website] [fix] fixes in sitemap and rss generators --- startup/website.py | 4 ++-- website/helpers/blog_feed.py | 8 +++++--- website/helpers/sitemap.py | 10 ++++++---- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/startup/website.py b/startup/website.py index be8eba6def1..5e6c3118c2e 100644 --- a/startup/website.py +++ b/startup/website.py @@ -1,5 +1,5 @@ import webnotes, conf, os -from webnotes.utils import cint, cstr +from webnotes.utils import cint, cstr, encode def get_templates_path(): return os.path.join(os.path.dirname(conf.__file__), "app", "website", "templates") @@ -72,7 +72,7 @@ def update_template_args(page_name, args): args[k] = cint(args.get(k) or 0) args.url = quote(str(get_request_site_address(full_address=True)), str("")) - args.encoded_title = quote(str(args.title or ""), str("")) + args.encoded_title = quote(encode(args.title or ""), str("")) return args \ No newline at end of file diff --git a/website/helpers/blog_feed.py b/website/helpers/blog_feed.py index 41c203e0ada..c79c5cc3bb3 100644 --- a/website/helpers/blog_feed.py +++ b/website/helpers/blog_feed.py @@ -49,9 +49,10 @@ rss_item = u""" def generate(): """generate rss feed""" - import webnotes, os + import os, urllib + import webnotes from webnotes.model.doc import Document - from website.helpers.blog import get_blog_content + from webnotes.utils import escape_html host = (os.environ.get('HTTPS') and 'https://' or 'http://') + os.environ.get('HTTP_HOST') @@ -62,7 +63,8 @@ def generate(): order by published_on desc limit 20""", as_dict=1) for blog in blog_list: - blog.link = host + '/' + blog.name + '.html' + blog.link = urllib.quote(host + '/' + blog.name + '.html') + blog.content = escape_html(blog.content or "") items += rss_item % blog diff --git a/website/helpers/sitemap.py b/website/helpers/sitemap.py index c8b6fd0a53b..3956da1a709 100644 --- a/website/helpers/sitemap.py +++ b/website/helpers/sitemap.py @@ -2,6 +2,7 @@ # License: GNU General Public License (v3). For more information see license.txt from __future__ import unicode_literals + frame_xml = """ %s """ @@ -32,10 +33,11 @@ def generate(domain): for p in pages: if count >= max_items: break - page_url = os.path.join(domain, urllib.quote(p[0])) - modified = p[1].strftime('%Y-%m-%d') - site_map += link_xml % (page_url, modified) - count += 1 + if p[0]: + page_url = os.path.join(domain, urllib.quote(p[0])) + modified = p[1].strftime('%Y-%m-%d') + site_map += link_xml % (page_url, modified) + count += 1 if count >= max_items: break From 62d0629d6119b1c5139c1bc7f750ae611db4c5a8 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 22 May 2013 16:19:10 +0530 Subject: [PATCH 09/14] [feature] reorder level checking through scheduler --- .../journal_voucher/test_journal_voucher.py | 117 +----------------- patches/may_2013/p04_reorder_level.py | 23 ++++ patches/patch_list.py | 1 + .../global_defaults/global_defaults.txt | 48 ++++--- startup/schedule_handlers.py | 4 + stock/doctype/bin/bin.py | 84 +------------ stock/doctype/item/item.py | 8 ++ stock/doctype/item/item.txt | 17 +-- stock/utils.py | 117 +++++++++++++++++- 9 files changed, 185 insertions(+), 234 deletions(-) create mode 100644 patches/may_2013/p04_reorder_level.py diff --git a/accounts/doctype/journal_voucher/test_journal_voucher.py b/accounts/doctype/journal_voucher/test_journal_voucher.py index 7cfeb595d81..feb1e2ca5a6 100644 --- a/accounts/doctype/journal_voucher/test_journal_voucher.py +++ b/accounts/doctype/journal_voucher/test_journal_voucher.py @@ -122,119 +122,4 @@ test_records = [ "parentfield": "entries", "cost_center": "_Test Cost Center - _TC" }], -] - - - - - - -# -# -# import webnotes.model -# from webnotes.utils import nowdate, flt, add_days -# from accounts.utils import get_fiscal_year, get_balance_on -# -# company = webnotes.conn.get_default("company") -# abbr = webnotes.conn.get_value("Company", company, "abbr") -# -# data = { -# "expense_account": { -# "doctype": "Account", -# "account_name": "Test Expense", -# "parent_account": "Direct Expenses - %s" % abbr, -# "company": company, -# "debit_or_credit": "Debit", -# "is_pl_account": "Yes", -# "group_or_ledger": "Ledger" -# }, -# "supplier_account": { -# "doctype": "Account", -# "account_name": "Test Supplier", -# "parent_account": "Accounts Payable - %s" % abbr, -# "company": company, -# "debit_or_credit": "Credit", -# "is_pl_account": "No", -# "group_or_ledger": "Ledger" -# }, -# "test_cost_center": { -# "doctype": "Cost Center", -# "cost_center_name": "Test Cost Center", -# "parent_cost_center": "Root - %s" % abbr, -# "company_name": company, -# "group_or_ledger": "Ledger", -# "company_abbr": abbr -# }, -# "journal_voucher": [ -# { -# "doctype": "Journal Voucher", -# "voucher_type": "Journal Entry", -# "naming_series": "JV", -# "posting_date": nowdate(), -# "remark": "Test Journal Voucher", -# "fiscal_year": get_fiscal_year(nowdate())[0], -# "company": company -# }, -# { -# "doctype": "Journal Voucher Detail", -# "parentfield": "entries", -# "account": "Test Expense - %s" % abbr, -# "debit": 5000, -# "cost_center": "Test Cost Center - %s" % abbr, -# }, -# { -# "doctype": "Journal Voucher Detail", -# "parentfield": "entries", -# "account": "Test Supplier - %s" % abbr, -# "credit": 5000, -# }, -# ] -# } -# -# def get_name(s): -# return s + " - " + abbr -# -# class TestJournalVoucher(unittest.TestCase): -# def setUp(self): -# webnotes.conn.begin() -# -# # create a dummy account -# webnotes.model.insert([data["expense_account"]]) -# webnotes.model.insert([data["supplier_account"]]) -# webnotes.model.insert([data["test_cost_center"]]) -# -# def tearDown(self): -# webnotes.conn.rollback() -# -# def test_save_journal_voucher(self): -# expense_ac_balance = get_balance_on(get_name("Test Expense"), nowdate()) -# supplier_ac_balance = get_balance_on(get_name("Test Supplier"), nowdate()) -# -# dl = webnotes.model.insert(data["journal_voucher"]) -# dl.submit() -# dl.load_from_db() -# -# # test submitted jv -# self.assertTrue(webnotes.conn.exists("Journal Voucher", dl.doclist[0].name)) -# for d in dl.doclist[1:]: -# self.assertEquals(webnotes.conn.get_value("Journal Voucher Detail", -# d.name, "parent"), dl.doclist[0].name) -# -# # test gl entry -# gle = webnotes.conn.sql("""select account, debit, credit -# from `tabGL Entry` where voucher_no = %s order by account""", -# dl.doclist[0].name) -# -# self.assertEquals((gle[0][0], flt(gle[0][1]), flt(gle[0][2])), -# ('Test Expense - %s' % abbr, 5000.0, 0.0)) -# self.assertEquals((gle[1][0], flt(gle[1][1]), flt(gle[1][2])), -# ('Test Supplier - %s' % abbr, 0.0, 5000.0)) -# -# # check balance as on today -# self.assertEqual(get_balance_on(get_name("Test Expense"), nowdate()), -# expense_ac_balance + 5000) -# self.assertEqual(get_balance_on(get_name("Test Supplier"), nowdate()), -# supplier_ac_balance + 5000) -# -# # check previous balance -# self.assertEqual(get_balance_on(get_name("Test Expense"), add_days(nowdate(), -1)), 0) \ No newline at end of file +] \ No newline at end of file diff --git a/patches/may_2013/p04_reorder_level.py b/patches/may_2013/p04_reorder_level.py new file mode 100644 index 00000000000..8f4d669bc56 --- /dev/null +++ b/patches/may_2013/p04_reorder_level.py @@ -0,0 +1,23 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import unicode_literals +import webnotes +def execute(): + webnotes.reload_doc("Setup", "DocType", "Global Defaults") + + if webnotes.conn.exists({"doctype": "Item", "email_notify": 1}): + webnotes.conn.set_value("Global Defaults", None, "reorder_email_notify", 1) \ No newline at end of file diff --git a/patches/patch_list.py b/patches/patch_list.py index f28751c8183..89f48e5ce7c 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -250,4 +250,5 @@ patch_list = [ "patches.may_2013.p01_conversion_factor_and_aii", "patches.may_2013.p02_update_valuation_rate", "patches.may_2013.p03_update_support_ticket", + "patches.may_2013.p04_reorder_level", ] \ No newline at end of file diff --git a/setup/doctype/global_defaults/global_defaults.txt b/setup/doctype/global_defaults/global_defaults.txt index 853bb577056..175ca9414b6 100644 --- a/setup/doctype/global_defaults/global_defaults.txt +++ b/setup/doctype/global_defaults/global_defaults.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-04-01 15:05:24", + "creation": "2013-05-02 17:53:24", "docstatus": 0, - "modified": "2013-05-02 15:05:21", + "modified": "2013-05-22 15:57:26", "modified_by": "Administrator", "owner": "Administrator" }, @@ -27,6 +27,8 @@ "permlevel": 0 }, { + "amend": 0, + "cancel": 0, "create": 1, "doctype": "DocPerm", "name": "__common__", @@ -170,7 +172,8 @@ "fieldname": "item_naming_by", "fieldtype": "Select", "label": "Item Naming By", - "options": "Item Code\nNaming Series" + "options": "Item Code\nNaming Series", + "read_only": 0 }, { "doctype": "DocField", @@ -212,14 +215,6 @@ "label": "Allow Negative Stock", "read_only": 0 }, - { - "doctype": "DocField", - "fieldname": "default_warehouse_type", - "fieldtype": "Link", - "label": "Default Warehouse Type", - "options": "Warehouse Type", - "read_only": 0 - }, { "doctype": "DocField", "fieldname": "auto_indent", @@ -227,6 +222,21 @@ "label": "Raise Material Request when stock reaches re-order level", "read_only": 0 }, + { + "doctype": "DocField", + "fieldname": "reorder_email_notify", + "fieldtype": "Check", + "label": "Notify by Email on creation of automatic Material Request" + }, + { + "default": "Hourly", + "doctype": "DocField", + "fieldname": "reorder_level_checking_frequency", + "fieldtype": "Select", + "hidden": 1, + "label": "Reorder Level Checking Frequency", + "options": "Hourly\nDaily" + }, { "default": "1", "doctype": "DocField", @@ -235,6 +245,14 @@ "read_only": 0, "width": "50%" }, + { + "doctype": "DocField", + "fieldname": "default_warehouse_type", + "fieldtype": "Link", + "label": "Default Warehouse Type", + "options": "Warehouse Type", + "read_only": 0 + }, { "description": "Percentage you are allowed to receive or deliver more against the quantity ordered.

For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to receive 110 units

", "doctype": "DocField", @@ -274,7 +292,8 @@ "fieldtype": "Check", "label": "Auto Inventory Accounting", "no_copy": 0, - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "description": "Accounting entry frozen up to this date, nobody can do / modify entry except authorized person", @@ -507,11 +526,6 @@ "label": "SMS Sender Name", "read_only": 0 }, - { - "amend": 0, - "cancel": 0, - "doctype": "DocPerm" - }, { "doctype": "DocPerm" } diff --git a/startup/schedule_handlers.py b/startup/schedule_handlers.py index 0799817206b..cc0d1f4fead 100644 --- a/startup/schedule_handlers.py +++ b/startup/schedule_handlers.py @@ -55,6 +55,10 @@ def execute_daily(): from setup.doctype.backup_manager.backup_manager import take_backups_daily take_backups_daily() + # check reorder level + from stock.utils import reorder_item + run_fn(reorder_item) + def execute_weekly(): from setup.doctype.backup_manager.backup_manager import take_backups_weekly take_backups_weekly() diff --git a/stock/doctype/bin/bin.py b/stock/doctype/bin/bin.py index 2d98c2634f7..61baafafa2e 100644 --- a/stock/doctype/bin/bin.py +++ b/stock/doctype/bin/bin.py @@ -77,10 +77,6 @@ class DocType: self.doc.save() - if (flt(args.get("actual_qty")) < 0 or flt(args.get("reserved_qty")) > 0) \ - and args.get("is_cancelled") == 'No' and args.get("is_amended")=='No': - self.reorder_item(args.get("voucher_type"), args.get("voucher_no"), args.get("company")) - def get_first_sle(self): sle = sql(""" select * from `tabStock Ledger Entry` @@ -90,82 +86,4 @@ class DocType: order by timestamp(posting_date, posting_time) asc, name asc limit 1 """, (self.doc.item_code, self.doc.warehouse), as_dict=1) - return sle and sle[0] or None - - def reorder_item(self,doc_type,doc_name, company): - """ Reorder item if stock reaches reorder level""" - if not hasattr(webnotes, "auto_indent"): - webnotes.auto_indent = webnotes.conn.get_value('Global Defaults', None, 'auto_indent') - - if webnotes.auto_indent: - #check if re-order is required - item_reorder = webnotes.conn.get("Item Reorder", - {"parent": self.doc.item_code, "warehouse": self.doc.warehouse}) - if item_reorder: - reorder_level = item_reorder.warehouse_reorder_level - reorder_qty = item_reorder.warehouse_reorder_qty - material_request_type = item_reorder.material_request_type or "Purchase" - else: - reorder_level, reorder_qty = webnotes.conn.get_value("Item", self.doc.item_code, - ["re_order_level", "re_order_qty"]) - material_request_type = "Purchase" - - if flt(reorder_qty) and flt(self.doc.projected_qty) < flt(reorder_level): - self.create_material_request(doc_type, doc_name, reorder_level, reorder_qty, - company, material_request_type) - - def create_material_request(self, doc_type, doc_name, reorder_level, reorder_qty, company, - material_request_type="Purchase"): - """ Create indent on reaching reorder level """ - defaults = webnotes.defaults.get_defaults() - item = webnotes.doc("Item", self.doc.item_code) - - mr = webnotes.bean([{ - "doctype": "Material Request", - "company": company or defaults.company, - "fiscal_year": defaults.fiscal_year, - "transaction_date": nowdate(), - "material_request_type": material_request_type, - "remark": _("This is an auto generated Material Request.") + \ - _("It was raised because the (actual + ordered + indented - reserved) quantity reaches re-order level when the following record was created") + \ - ": " + _(doc_type) + " " + doc_name - }, { - "doctype": "Material Request Item", - "parenttype": "Material Request", - "parentfield": "indent_details", - "item_code": self.doc.item_code, - "schedule_date": add_days(nowdate(),cint(item.lead_time_days)), - "uom": self.doc.stock_uom, - "warehouse": self.doc.warehouse, - "item_name": item.item_name, - "description": item.description, - "item_group": item.item_group, - "qty": reorder_qty, - "brand": item.brand, - }]) - mr.insert() - mr.submit() - - msgprint("""Item: %s is to be re-ordered. Material Request %s raised. - It was generated from %s: %s""" % - (self.doc.item_code, mr.doc.name, doc_type, doc_name)) - - if(item.email_notify): - self.send_email_notification(doc_type, doc_name, mr) - - def send_email_notification(self, doc_type, doc_name, bean): - """ Notify user about auto creation of indent""" - - from webnotes.utils.email_lib import sendmail - email_list=[d[0] for d in sql("""select distinct r.parent from tabUserRole r, tabProfile p - where p.name = r.parent and p.enabled = 1 and p.docstatus < 2 - and r.role in ('Purchase Manager','Material Manager') - and p.name not in ('Administrator', 'All', 'Guest')""")] - - msg="""A new Material Request has been raised for Item: %s and Warehouse: %s \ - on %s due to %s: %s. See %s: %s """ % (self.doc.item_code, self.doc.warehouse, - formatdate(), doc_type, doc_name, bean.doc.doctype, - get_url_to_form(bean.doc.doctype, bean.doc.name)) - - sendmail(email_list, subject='Auto Material Request Generation Notification', msg = msg) - + return sle and sle[0] or None \ No newline at end of file diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py index bc438a877ac..d743a980057 100644 --- a/stock/doctype/item/item.py +++ b/stock/doctype/item/item.py @@ -51,6 +51,7 @@ class DocType(DocListController): self.validate_barcode() self.check_non_asset_warehouse() self.cant_change() + self.validate_item_type_for_reorder() if self.doc.name: self.old_page_name = webnotes.conn.get_value('Item', self.doc.name, 'page_name') @@ -201,6 +202,13 @@ class DocType(DocListController): webnotes.msgprint(_("As there are existing stock transactions for this \ item, you can not change the values of 'Has Serial No', \ 'Is Stock Item' and 'Valuation Method'"), raise_exception=1) + + def validate_item_type_for_reorder(self): + if self.doc.re_order_level or len(self.doclist.get({"parentfield": "item_reorder", + "material_request_type": "Purchase"})): + if not self.doc.is_purchase_item: + webnotes.msgprint(_("""To set reorder level, item must be Purchase Item"""), + raise_exception=1) def check_if_sle_exists(self): sle = webnotes.conn.sql("""select name from `tabStock Ledger Entry` diff --git a/stock/doctype/item/item.txt b/stock/doctype/item/item.txt index c799029d95a..9e0a2fb24e7 100644 --- a/stock/doctype/item/item.txt +++ b/stock/doctype/item/item.txt @@ -2,7 +2,7 @@ { "creation": "2013-05-03 10:45:46", "docstatus": 0, - "modified": "2013-05-07 15:58:58", + "modified": "2013-05-22 15:48:27", "modified_by": "Administrator", "owner": "Administrator" }, @@ -363,21 +363,6 @@ "label": "Re-Order Qty", "read_only": 0 }, - { - "doctype": "DocField", - "fieldname": "column_break_31", - "fieldtype": "Column Break", - "read_only": 0 - }, - { - "depends_on": "eval:doc.is_stock_item==\"Yes\"", - "description": "Send an email to users of role \"Material Manager\" and \"Purchase Manager\" when re-order level is crossed.", - "doctype": "DocField", - "fieldname": "email_notify", - "fieldtype": "Check", - "label": "Notify by Email on Re-order", - "read_only": 0 - }, { "doctype": "DocField", "fieldname": "section_break_31", diff --git a/stock/utils.py b/stock/utils.py index a2541dc69e9..5e7e53bb014 100644 --- a/stock/utils.py +++ b/stock/utils.py @@ -17,7 +17,7 @@ import webnotes from webnotes import msgprint, _ import json -from webnotes.utils import flt, cstr +from webnotes.utils import flt, cstr, nowdate, add_days, cint from webnotes.defaults import get_global_default def validate_end_of_life(item_code, end_of_life=None, verbose=1): @@ -194,4 +194,117 @@ def _get_buying_amount(voucher_type, voucher_no, item_row, item_code, warehouse, buying_amount = previous_stock_value - flt(sle.stock_value) return buying_amount - return 0.0 \ No newline at end of file + return 0.0 + + +def reorder_item(): + """ Reorder item if stock reaches reorder level""" + if not hasattr(webnotes, "auto_indent"): + webnotes.auto_indent = webnotes.conn.get_value('Global Defaults', None, 'auto_indent') + + if webnotes.auto_indent: + material_requests = {} + bin_list = webnotes.conn.sql("""select item_code, warehouse, projected_qty + from tabBin where ifnull(item_code, '') != '' and ifnull(warehouse, '') != ''""", + as_dict=True) + for bin in bin_list: + #check if re-order is required + item_reorder = webnotes.conn.get("Item Reorder", + {"parent": bin.item_code, "warehouse": bin.warehouse}) + if item_reorder: + reorder_level = item_reorder.warehouse_reorder_level + reorder_qty = item_reorder.warehouse_reorder_qty + material_request_type = item_reorder.material_request_type or "Purchase" + else: + reorder_level, reorder_qty = webnotes.conn.get_value("Item", bin.item_code, + ["re_order_level", "re_order_qty"]) + material_request_type = "Purchase" + + if reorder_level and flt(bin.projected_qty) < flt(reorder_level): + if flt(reorder_level) - flt(bin.projected_qty) > flt(reorder_qty): + reorder_qty = flt(reorder_level) - flt(bin.projected_qty) + + company = webnotes.conn.get_value("Warehouse", bin.warehouse, "company") or \ + webnotes.defaults.get_defaults()["company"] or \ + webnotes.conn.sql("""select name from tabCompany limit 1""")[0][0] + + material_requests.setdefault(material_request_type, webnotes._dict()).setdefault( + company, []).append(webnotes._dict({ + "item_code": bin.item_code, + "warehouse": bin.warehouse, + "reorder_qty": reorder_qty + }) + ) + + create_material_request(material_requests) + +def create_material_request(material_requests): + """ Create indent on reaching reorder level """ + mr_list = [] + defaults = webnotes.defaults.get_defaults() + for request_type in material_requests: + for company in material_requests[request_type]: + items = material_requests[request_type][company] + if items: + mr = [{ + "doctype": "Material Request", + "company": company, + "fiscal_year": defaults.fiscal_year, + "transaction_date": nowdate(), + "material_request_type": request_type, + "remark": _("This is an auto generated Material Request.") + \ + _("""It was raised because the (actual + ordered + indented - reserved) + quantity reaches re-order level when the following record was created""") + }] + + for d in items: + item = webnotes.doc("Item", d.item_code) + mr.append({ + "doctype": "Material Request Item", + "parenttype": "Material Request", + "parentfield": "indent_details", + "item_code": d.item_code, + "schedule_date": add_days(nowdate(),cint(item.lead_time_days)), + "uom": item.stock_uom, + "warehouse": d.warehouse, + "item_name": item.item_name, + "description": item.description, + "item_group": item.item_group, + "qty": d.reorder_qty, + "brand": item.brand, + }) + + mr_bean = webnotes.bean(mr) + mr_bean.insert() + mr_bean.submit() + mr_list.append(mr_bean) + + if mr_list: + if not hasattr(webnotes, "reorder_email_notify"): + webnotes.reorder_email_notify = webnotes.conn.get_value('Global Defaults', None, + 'reorder_email_notify') + + if(webnotes.reorder_email_notify): + send_email_notification(mr_list) + +def send_email_notification(mr_list): + """ Notify user about auto creation of indent""" + + from webnotes.utils.email_lib import sendmail + email_list = webnotes.conn.sql_list("""select distinct r.parent + from tabUserRole r, tabProfile p + where p.name = r.parent and p.enabled = 1 and p.docstatus < 2 + and r.role in ('Purchase Manager','Material Manager') + and p.name not in ('Administrator', 'All', 'Guest')""") + + msg="""

Following Material Requests has been raised automatically \ + based on item reorder level:

""" + for mr in mr_list: + msg += "

" + mr.doc.name + """

+ """ + for item in mr.doclist.get({"parentfield": "indent_details"}): + msg += "" + msg += "
Item CodeWarehouseQtyUOM
" + item.item_code + "" + item.warehouse + "" + \ + cstr(item.qty) + "" + cstr(item.uom) + "
" + + sendmail(email_list, subject='Auto Material Request Generation Notification', msg = msg) \ No newline at end of file From 3f15a04a35aab81439b23c1711bfc493959b9849 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 22 May 2013 16:31:15 +0530 Subject: [PATCH 10/14] [website] [product group] show search and breadcrumbs below the item group's description --- website/templates/html/product_group.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/website/templates/html/product_group.html b/website/templates/html/product_group.html index b3c851197e5..0ad4048cdac 100644 --- a/website/templates/html/product_group.html +++ b/website/templates/html/product_group.html @@ -1,8 +1,6 @@ {% extends "app/website/templates/html/page.html" %} {% block content %} -{% include 'app/website/templates/html/product_search_box.html' %} -{% include 'app/website/templates/html/product_breadcrumbs.html' %}
{% if slideshow %} {% include "app/website/templates/html/slideshow.html" %} @@ -12,6 +10,10 @@ {% else %}

{{ name }}

{% endif %} +
+{% include 'app/website/templates/html/product_search_box.html' %} +{% include 'app/website/templates/html/product_breadcrumbs.html' %} +
{% if sub_groups %}
From 66928243c11301a87fc94f7c3115693c911c712a Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 22 May 2013 16:55:10 +0530 Subject: [PATCH 11/14] [fixes] removed communication section break from quotation --- selling/doctype/quotation/quotation.txt | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/selling/doctype/quotation/quotation.txt b/selling/doctype/quotation/quotation.txt index feda14c5917..4115be833b4 100644 --- a/selling/doctype/quotation/quotation.txt +++ b/selling/doctype/quotation/quotation.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-04-03 09:10:44", + "creation": "2013-05-22 12:10:46", "docstatus": 0, - "modified": "2013-04-03 09:58:02", + "modified": "2013-05-22 16:54:07", "modified_by": "Administrator", "owner": "Administrator" }, @@ -833,12 +833,11 @@ "width": "100px" }, { - "description": "Keep a track on communications regarding this Quotation. This will help you remember earlier communications in case the Customer comes back again", "doctype": "DocField", "fieldname": "communication_history", "fieldtype": "Section Break", - "label": "Communication History", "oldfieldtype": "Section Break", + "options": "Simple", "print_hide": 1, "read_only": 0 }, @@ -869,28 +868,23 @@ "cancel": 1, "create": 1, "doctype": "DocPerm", - "role": "Sales Manager", + "role": "Sales User", "submit": 1, "write": 1 }, + { + "doctype": "DocPerm", + "role": "Customer" + }, { "amend": 1, "cancel": 1, "create": 1, "doctype": "DocPerm", - "role": "Sales User", + "role": "Sales Manager", "submit": 1, "write": 1 }, - { - "amend": 0, - "cancel": 0, - "create": 0, - "doctype": "DocPerm", - "role": "Customer", - "submit": 0, - "write": 0 - }, { "amend": 1, "cancel": 1, From d39b30ab99cfade9335bd2455e0098f397dbe807 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 23 May 2013 11:44:18 +0530 Subject: [PATCH 12/14] [validation] invoice rate will be same as order/delivery --- .../doctype/sales_invoice/sales_invoice.py | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py index d18b967dfa4..4c71cb3342c 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.py +++ b/accounts/doctype/sales_invoice/sales_invoice.py @@ -74,9 +74,11 @@ class DocType(SellingController): self.set_aging_date() self.set_against_income_account() self.validate_c_form() + self.validate_rate_with_refdoc() self.validate_time_logs_are_submitted() self.validate_recurring_invoice() + def on_submit(self): if cint(self.doc.is_pos) == 1: if cint(self.doc.update_stock) == 1: @@ -213,8 +215,9 @@ class DocType(SellingController): if self.doc.customer: acc_head = webnotes.conn.sql("""select name from `tabAccount` where (name = %s or (master_name = %s and master_type = 'customer')) - and docstatus != 2""", - (cstr(self.doc.customer) + " - " + self.get_company_abbr(), self.doc.customer)) + and docstatus != 2 and company = %s""", + (cstr(self.doc.customer) + " - " + self.get_company_abbr(), + self.doc.customer, self.doc.company)) if acc_head and acc_head[0][0]: return acc_head[0][0] @@ -551,6 +554,19 @@ class DocType(SellingController): webnotes.conn.set(self.doc, 'c_form_no', '') + def validate_rate_with_refdoc(self): + """Validate values with reference document with previous document""" + for d in self.doclist.get({"parentfield": "entries"}): + if d.so_detail: + self.check_value("Sales Order", d.so_detail, d.export_rate, d.item_code) + if d.dn_detail: + self.check_value("Delivery Note", d.dn_detail, d.export_rate, d.item_code) + + def check_value(self, ref_dt, ref_dn, val, item_code): + ref_val = webnotes.conn.get_value(ref_dt + "Item", ref_dn, "export_rate") + if flt(ref_val) != val: + msgprint(_("Rate is not matching with ") + ref_dt + ": " + ref_dn + + _(" for item: ") + item_code, raise_exception=True) def update_current_stock(self): for d in getlist(self.doclist, 'entries'): From 5dc36f416a4df7df3cca20b249cedcc99ce4a777 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 23 May 2013 12:53:47 +0530 Subject: [PATCH 13/14] [permission] delete permission added for pos setting --- accounts/doctype/pos_setting/pos_setting.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/accounts/doctype/pos_setting/pos_setting.txt b/accounts/doctype/pos_setting/pos_setting.txt index 80cb1ecdc9c..788af9ee067 100755 --- a/accounts/doctype/pos_setting/pos_setting.txt +++ b/accounts/doctype/pos_setting/pos_setting.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-04-30 12:58:25", + "creation": "2013-05-09 13:16:11", "docstatus": 0, - "modified": "2013-05-03 14:36:24", + "modified": "2013-05-23 12:52:09", "modified_by": "Administrator", "owner": "Administrator" }, @@ -213,6 +213,14 @@ "options": "link:Print Heading" }, { + "cancel": 1, + "create": 1, + "doctype": "DocPerm", + "role": "System Manager", + "write": 1 + }, + { + "cancel": 1, "create": 1, "doctype": "DocPerm", "role": "Accounts Manager", From aabe11b689df77a09a37cb785725efde54c5e90c Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 23 May 2013 12:59:12 +0530 Subject: [PATCH 14/14] [sales order] [validate] validate item details specifically when submitting --- selling/doctype/sales_order/sales_order.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py index 6a52e5a0fa9..c8db1f919f1 100644 --- a/selling/doctype/sales_order/sales_order.py +++ b/selling/doctype/sales_order/sales_order.py @@ -217,7 +217,10 @@ class DocType(SellingController): self.validate_proj_cust() self.validate_po() #self.validate_reference_value() - self.validate_for_items() + + if self.doc.docstatus == 1: + self.validate_for_items() + sales_com_obj = get_obj(dt = 'Sales Common') sales_com_obj.check_active_sales_items(self) sales_com_obj.check_conversion_rate(self)