From 196b6b8b68df735321abea0b80abb3f0a1836f45 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 5 Jun 2013 16:12:42 +0530 Subject: [PATCH 01/16] [report] itemwise sales register --- accounts/page/accounts_home/accounts_home.js | 5 ++ .../item_wise_sales_register/__init__.py | 0 .../item_wise_sales_register.js | 39 +++++++++++ .../item_wise_sales_register.py | 67 +++++++++++++++++++ .../item_wise_sales_register.txt | 22 ++++++ 5 files changed, 133 insertions(+) create mode 100644 accounts/report/item_wise_sales_register/__init__.py create mode 100644 accounts/report/item_wise_sales_register/item_wise_sales_register.js create mode 100644 accounts/report/item_wise_sales_register/item_wise_sales_register.py create mode 100644 accounts/report/item_wise_sales_register/item_wise_sales_register.txt diff --git a/accounts/page/accounts_home/accounts_home.js b/accounts/page/accounts_home/accounts_home.js index 03009023c1..7f623d7115 100644 --- a/accounts/page/accounts_home/accounts_home.js +++ b/accounts/page/accounts_home/accounts_home.js @@ -252,6 +252,11 @@ wn.module_page["Accounts"] = [ route: "query-report/Item-wise Sales Register", doctype: "Sales Invoice" }, + { + "label":wn._("Item-wise Purchase Register"), + route: "query-report/Item-wise Purchase Register", + doctype: "Purchase Invoice" + }, ] } ] diff --git a/accounts/report/item_wise_sales_register/__init__.py b/accounts/report/item_wise_sales_register/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accounts/report/item_wise_sales_register/item_wise_sales_register.js b/accounts/report/item_wise_sales_register/item_wise_sales_register.js new file mode 100644 index 0000000000..b9ce9595fe --- /dev/null +++ b/accounts/report/item_wise_sales_register/item_wise_sales_register.js @@ -0,0 +1,39 @@ +wn.query_reports["Item-wise Sales Register"] = { + "filters": [ + { + "fieldname":"from_date", + "label": "From Date", + "fieldtype": "Date", + "default": wn.defaults.get_user_default("year_start_date"), + "width": "80" + }, + { + "fieldname":"to_date", + "label": "To Date", + "fieldtype": "Date", + "default": get_today() + }, + { + "fieldname": "item_code", + "label": "Item", + "fieldtype": "Link", + "options": "Item", + }, + { + "fieldname":"account", + "label": "Account", + "fieldtype": "Link", + "options": "Account", + "get_query": function() { + return { + "query": "accounts.utils.get_account_list", + "filters": { + "is_pl_account": "No", + "debit_or_credit": "Debit", + "master_type": "Customer" + } + } + } + } + ] +} \ No newline at end of file diff --git a/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/accounts/report/item_wise_sales_register/item_wise_sales_register.py new file mode 100644 index 0000000000..f6e26af350 --- /dev/null +++ b/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -0,0 +1,67 @@ +# 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 +from webnotes.utils import flt + +def execute(filters=None): + if not filters: filters = {} + + columns = get_columns() + item_list = get_items(filters) + + data = [] + for d in item_list: + data.append([d.item_code, d.item_name, d.item_group, d.name, d.posting_date, d.customer, + d.debit_to, d.territory, d.project_name, d.company, d.sales_order, d.delivery_note, + d.income_account, d.qty, d.basic_rate, d.amount]) + + return columns, data + + +def get_columns(): + return [ + "Item Code:Link/Item:120", "Item Name::120", "Item Group:Link/Item Group:100", + "Invoice:Link/Sales Invoice:120", "Posting Date:Date:80", "Customer:Link/Customer:120", + "Customer Account:Link/Account:120", "Territory:Link/Territory:80", + "Project:Link/Project:80", "Company:Link/Company:100", "Sales Order:Link/Sales Order:100", + "Delivery Note:Link/Delivery Note:100", "Income Account:Link/Account:140", + "Qty:Float:120", "Rate:Currency:120", "Amount:Currency:120" + ] + + +def get_conditions(filters): + conditions = "" + + if filters.get("account"): conditions += " and si.debit_to = %(account)s" + + if filters.get("item_code"): conditions += " and si_item.item_code = %(item_code)s" + + if filters.get("from_date"): conditions += " and si.posting_date>=%(from_date)s" + if filters.get("to_date"): conditions += " and si.posting_date<=%(to_date)s" + + return conditions + +def get_items(filters): + conditions = get_conditions(filters) + return webnotes.conn.sql("""select si.name, si.posting_date, si.debit_to, si.project_name, + si.customer, si.remarks, si.territory, si_item.item_code, si_item.item_name, + si_item.item_group, si_item.sales_order, si_item.delivery_note, si_item.income_account, + si_item.qty, si_item.basic_rate, si_item.amount + from `tabSales Invoice` si, `tabSales Invoice Item` si_item + where si.name = si_item.parent and si.docstatus = 1 %s + order by si.posting_date desc, si_item.item_code desc""" % conditions, filters, as_dict=1) \ No newline at end of file diff --git a/accounts/report/item_wise_sales_register/item_wise_sales_register.txt b/accounts/report/item_wise_sales_register/item_wise_sales_register.txt new file mode 100644 index 0000000000..fb0555d459 --- /dev/null +++ b/accounts/report/item_wise_sales_register/item_wise_sales_register.txt @@ -0,0 +1,22 @@ +[ + { + "creation": "2013-05-13 17:50:55", + "docstatus": 0, + "modified": "2013-05-13 17:50:55", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "add_total_row": 1, + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Sales Invoice", + "report_name": "Item-wise Sales Register", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Item-wise Sales Register" + } +] \ No newline at end of file From c36e2653f9b29de938dc943a60d908023c73d535 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 5 Jun 2013 16:13:05 +0530 Subject: [PATCH 02/16] [report] itemwise purchase register --- .../item_wise_purchase_register/__init__.py | 0 .../item_wise_purchase_register.js | 39 ++++++++++ .../item_wise_purchase_register.py | 74 +++++++++++++++++++ .../item_wise_purchase_register.txt | 22 ++++++ 4 files changed, 135 insertions(+) create mode 100644 accounts/report/item_wise_purchase_register/__init__.py create mode 100644 accounts/report/item_wise_purchase_register/item_wise_purchase_register.js create mode 100644 accounts/report/item_wise_purchase_register/item_wise_purchase_register.py create mode 100644 accounts/report/item_wise_purchase_register/item_wise_purchase_register.txt diff --git a/accounts/report/item_wise_purchase_register/__init__.py b/accounts/report/item_wise_purchase_register/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js b/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js new file mode 100644 index 0000000000..8323a1af78 --- /dev/null +++ b/accounts/report/item_wise_purchase_register/item_wise_purchase_register.js @@ -0,0 +1,39 @@ +wn.query_reports["Item-wise Purchase Register"] = { + "filters": [ + { + "fieldname":"from_date", + "label": "From Date", + "fieldtype": "Date", + "default": wn.defaults.get_user_default("year_start_date"), + "width": "80" + }, + { + "fieldname":"to_date", + "label": "To Date", + "fieldtype": "Date", + "default": get_today() + }, + { + "fieldname": "item_code", + "label": "Item", + "fieldtype": "Link", + "options": "Item", + }, + { + "fieldname":"account", + "label": "Account", + "fieldtype": "Link", + "options": "Account", + "get_query": function() { + return { + "query": "accounts.utils.get_account_list", + "filters": { + "is_pl_account": "No", + "debit_or_credit": "Credit", + "master_type": "Supplier" + } + } + } + } + ] +} \ No newline at end of file diff --git a/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py new file mode 100644 index 0000000000..ad9d79504b --- /dev/null +++ b/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py @@ -0,0 +1,74 @@ +# 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(filters=None): + if not filters: filters = {} + + columns = get_columns() + item_list = get_items(filters) + aii_account_map = get_aii_accounts() + webnotes.errprint(aii_account_map) + data = [] + for d in item_list: + expense_head = d.expense_head or aii_account_map.get(d.company) + data.append([d.item_code, d.item_name, d.item_group, d.name, d.posting_date, d.supplier, + d.credit_to, d.project_name, d.company, d.purchase_order, d.purchase_receipt, + expense_head, d.qty, d.rate, d.amount]) + + return columns, data + + +def get_columns(): + return ["Item Code:Link/Item:120", "Item Name::120", "Item Group:Link/Item Group:100", + "Invoice:Link/Purchase Invoice:120", "Posting Date:Date:80", "Supplier:Link/Customer:120", + "Supplier Account:Link/Account:120", "Project:Link/Project:80", "Company:Link/Company:100", + "Purchase Order:Link/Purchase Order:100", "Purchase Receipt:Link/Purchase Receipt:100", + "Expense Account:Link/Account:140", "Qty:Float:120", "Rate:Currency:120", + "Amount:Currency:120"] + + +def get_conditions(filters): + conditions = "" + + if filters.get("account"): conditions += " and pi.credit_to = %(account)s" + + if filters.get("item_code"): conditions += " and pi_item.item_code = %(item_code)s" + + if filters.get("from_date"): conditions += " and pi.posting_date>=%(from_date)s" + if filters.get("to_date"): conditions += " and pi.posting_date<=%(to_date)s" + + return conditions + +def get_items(filters): + conditions = get_conditions(filters) + return webnotes.conn.sql("""select pi.name, pi.posting_date, pi.credit_to, pi.company, + pi.supplier, pi.remarks, pi_item.item_code, pi_item.item_name, pi_item.item_group, + pi_item.project_name, pi_item.purchase_order, pi_item.purchase_receipt, + pi_item.expense_head, pi_item.qty, pi_item.rate, pi_item.amount + from `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pi_item + where pi.name = pi_item.parent and pi.docstatus = 1 %s + order by pi.posting_date desc, pi_item.item_code desc""" % conditions, filters, as_dict=1) + +def get_aii_accounts(): + aii_account_map = {} + for d in webnotes.conn.sql("select name, stock_received_but_not_billed from tabCompany", + as_dict=1): + aii_account_map.setdefault(d.name, d.stock_received_but_not_billed) + + return aii_account_map \ No newline at end of file diff --git a/accounts/report/item_wise_purchase_register/item_wise_purchase_register.txt b/accounts/report/item_wise_purchase_register/item_wise_purchase_register.txt new file mode 100644 index 0000000000..7ded5ff583 --- /dev/null +++ b/accounts/report/item_wise_purchase_register/item_wise_purchase_register.txt @@ -0,0 +1,22 @@ +[ + { + "creation": "2013-06-05 15:37:30", + "docstatus": 0, + "modified": "2013-06-05 15:37:30", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "add_total_row": 1, + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Purchase Invoice", + "report_name": "Item-wise Purchase Register", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Item-wise Purchase Register" + } +] \ No newline at end of file From 7b48218b6f75bf59b1980d32bea75165e00d4346 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Wed, 5 Jun 2013 18:17:28 +0530 Subject: [PATCH 03/16] [Reports][Reorder Level] and [No Sales Order from Customer] --- selling/page/selling_home/selling_home.js | 6 ++ .../__init__.py | 0 ...s_order_from_customers_(since_2_months).py | 69 +++++++++++++ ..._order_from_customers_(since_2_months).txt | 21 ++++ stock/page/stock_home/stock_home.js | 5 + stock/report/item_reorder_level/__init__.py | 0 .../item_reorder_level/item_reorder_level.js | 16 +++ .../item_reorder_level/item_reorder_level.py | 97 +++++++++++++++++++ .../item_reorder_level/item_reorder_level.txt | 21 ++++ 9 files changed, 235 insertions(+) create mode 100644 selling/report/no_sales_order_from_customers_(since_2_months)/__init__.py create mode 100644 selling/report/no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).py create mode 100644 selling/report/no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).txt create mode 100644 stock/report/item_reorder_level/__init__.py create mode 100644 stock/report/item_reorder_level/item_reorder_level.js create mode 100644 stock/report/item_reorder_level/item_reorder_level.py create mode 100644 stock/report/item_reorder_level/item_reorder_level.txt diff --git a/selling/page/selling_home/selling_home.js b/selling/page/selling_home/selling_home.js index 682978bd17..1f119e2917 100644 --- a/selling/page/selling_home/selling_home.js +++ b/selling/page/selling_home/selling_home.js @@ -149,6 +149,11 @@ wn.module_page["Selling"] = [ right: true, icon: "icon-list", items: [ + { + "label":wn._("No Sales Order from Customers (Since 2 months)"), + route: "query-report/No Sales Order from Customers (Since 2 months)", + doctype: "Sales Order" + }, { "label":wn._("Customer Addresses And Contacts"), route: "query-report/Customer Addresses And Contacts" @@ -165,6 +170,7 @@ wn.module_page["Selling"] = [ "label":wn._("Item-wise Sales History"), route: "query-report/Item-wise Sales History", }, + ] } ] diff --git a/selling/report/no_sales_order_from_customers_(since_2_months)/__init__.py b/selling/report/no_sales_order_from_customers_(since_2_months)/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/selling/report/no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).py b/selling/report/no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).py new file mode 100644 index 0000000000..43efb98d06 --- /dev/null +++ b/selling/report/no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).py @@ -0,0 +1,69 @@ +# 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 . +import webnotes + +def execute(filters=None): + + columns = get_columns() + customers = get_so_details() + + data = [] + for cust in customers: + if cust[8] >= 60: # days_since_last_order + cust.insert(7,get_last_so_amt(cust[0])) + data.append(cust) + + return columns, data + +def get_so_details(): + return webnotes.conn.sql("""select + cust.name, + cust.customer_name, + cust.territory, + cust.customer_group, + count(distinct(so.name)) as 'num_of_order', + sum(net_total) as 'total_order_value', + sum(if(so.status = "Stopped", + so.net_total * so.per_delivered/100, + so.net_total)) as 'total_order_considered', + max(so.transaction_date) as 'last_sales_order_date', + DATEDIFF(CURDATE(),max(so.transaction_date)) as 'days_since_last_order' + from `tabCustomer` cust, `tabSales Order` so + where cust.name = so.customer and so.docstatus = 1 + group by cust.name + order by 'days_since_last_order' desc """,as_list=1) + +def get_last_so_amt(customer): + return webnotes.conn.sql("""select net_total from `tabSales Order` + where customer ='%(customer)s' and docstatus = 1 and + transaction_date = (select max(transaction_date) + from `tabSales Order` + where customer = '%(customer)s') + """%{'customer':customer}) + +def get_columns(): + return [ + "Customer:Link/Customer:120", + "Customer Name:Data:120", + "Territory::120", + "Customer Group::120", + "Number of Order::120", + "Total Order Value:Currency:120", + "Total Order Considered:Currency:160", + "Last Order Amount:Currency:160", + "Last Sales Order Date:Date:160", + "Days Since Last Order::160" + ] \ No newline at end of file diff --git a/selling/report/no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).txt b/selling/report/no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).txt new file mode 100644 index 0000000000..cd7b2b7ff9 --- /dev/null +++ b/selling/report/no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).txt @@ -0,0 +1,21 @@ +[ + { + "creation": "2013-06-05 11:40:49", + "docstatus": 0, + "modified": "2013-06-05 11:40:49", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Sales Order", + "report_name": "No Sales Order from Customers (Since 2 months)", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "No Sales Order from Customers (Since 2 months)" + } +] \ No newline at end of file diff --git a/stock/page/stock_home/stock_home.js b/stock/page/stock_home/stock_home.js index 75e4ee15b0..ac3a096c50 100644 --- a/stock/page/stock_home/stock_home.js +++ b/stock/page/stock_home/stock_home.js @@ -128,6 +128,11 @@ wn.module_page["Stock"] = [ right: true, icon: "icon-table", items: [ + { + "label":wn._("Item Reorder Level"), + route: "query-report/Item Reorder Level", + doctype: "Item" + }, { "label":wn._("Stock Ledger"), page: "stock-ledger" diff --git a/stock/report/item_reorder_level/__init__.py b/stock/report/item_reorder_level/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/stock/report/item_reorder_level/item_reorder_level.js b/stock/report/item_reorder_level/item_reorder_level.js new file mode 100644 index 0000000000..30240e587d --- /dev/null +++ b/stock/report/item_reorder_level/item_reorder_level.js @@ -0,0 +1,16 @@ +wn.query_reports["Item Reorder Level"] = { + "filters": [ + { + "fieldname":"from_date", + "label": "From Date", + "fieldtype": "Date", + "default": sys_defaults.year_start_date + }, + { + "fieldname":"to_date", + "label": "To Date", + "fieldtype": "Date", + "default": get_today() + } + ] +} \ No newline at end of file diff --git a/stock/report/item_reorder_level/item_reorder_level.py b/stock/report/item_reorder_level/item_reorder_level.py new file mode 100644 index 0000000000..d59696138c --- /dev/null +++ b/stock/report/item_reorder_level/item_reorder_level.py @@ -0,0 +1,97 @@ +# 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 . + +import webnotes +from webnotes.utils import getdate, flt, cint + +def execute(filters=None): + if not filters: filters = {} + + columns = get_columns() + items = get_item_info() + consumed_item_map = get_consumed_items(filters) + delivered_item_map = get_delivered_items(filters) + + avg_daily_outgoing = 0 + diff = (getdate(filters.get("to_date")) - getdate(filters.get("from_date"))).days + if diff <= 0: + webnotes.msgprint("To Date should not be less than eual to From Date",raise_exception=1) + + data = [] + for item in items: + + total_outgoing = consumed_item_map.get(item.name, 0)+delivered_item_map.get(item.name,0) + avg_daily_outgoing = cint(total_outgoing/diff) + reorder_level = (avg_daily_outgoing * item.lead_time_days) + item.min_order_qty + + data.append([item.name, item.item_name, item.description, item.min_order_qty, item.lead_time_days, + consumed_item_map.get(item.name, 0), delivered_item_map.get(item.name,0), total_outgoing, + avg_daily_outgoing, reorder_level]) + + return columns , data + +def get_columns(): + return["Item:Link/Item:120", "Item name:Data:120", "description::160", "minimum inventory level::120", + "lead time days::120", "consumed::120", "delivered::120", "total outgoing::120", + "avg daily outgoing::120", "reorder level::120"] + +def get_item_info(): + return webnotes.conn.sql("""select name, item_name, description, min_order_qty, lead_time_days + from tabItem""",as_dict=1) + +def get_consumed_items(filters): + condition = get_condition(filters) + + cn_items = webnotes.conn.sql("""select se_item.item_code, sum(se_item.actual_qty) as 'consume_qty' + from `tabStock Entry` se, `tabStock Entry Detail` se_item + where se.name = se_item.parent and se.docstatus = 1 and ifnull(se_item.t_warehouse, '') = '' %s + group by se_item.item_code""" % (condition), as_dict=1) + + cn_items_map = {} + for item in cn_items: + cn_items_map.setdefault(item.item_code, item.consume_qty) + + return cn_items_map + +def get_delivered_items(filters): + condition = get_condition(filters) + + dn_items = webnotes.conn.sql("""select dn_item.item_code, sum(dn_item.qty) as dn_qty + from `tabDelivery Note` dn, `tabDelivery Note Item` dn_item + where dn.name = dn_item.parent and dn.docstatus = 1 %s group by dn_item.item_code""" % (condition) + , as_dict=1) + + si_items = webnotes.conn.sql("""select si_item.item_name, sum(si_item.qty) as si_qty + from `tabSales Invoice` si, `tabSales Invoice Item` si_item + where si.name = si_item.parent and si.docstatus = 1 and ifnull(si.update_stock, 0) = 1 + and ifnull(si.is_pos, 0) = 1 %s group by si_item.item_name""" % (condition), as_dict=1) + + dn_item_map = {} + for item in dn_items: + dn_item_map.setdefault(item.item_code, item.dn_qty) + + for item in si_items: + dn_item_map.setdefault(item.item_code, item.si_qty) + + return dn_item_map + +def get_condition(filters): + conditions = "" + if filters.get("from_date") and filters.get("to_date"): + conditions += " and posting_date between '%s' and '%s'" % (filters["from_date"],filters["to_date"]) + else: + webnotes.msgprint("Please set date in from date field",raise_exception=1) + return conditions \ No newline at end of file diff --git a/stock/report/item_reorder_level/item_reorder_level.txt b/stock/report/item_reorder_level/item_reorder_level.txt new file mode 100644 index 0000000000..93c6dfb185 --- /dev/null +++ b/stock/report/item_reorder_level/item_reorder_level.txt @@ -0,0 +1,21 @@ +[ + { + "creation": "2013-06-05 15:34:51", + "docstatus": 0, + "modified": "2013-06-05 15:50:30", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Item", + "report_name": "Item Reorder Level", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Item Reorder Level" + } +] \ No newline at end of file From e3e15a94c3bdf8a11905355c2499187ef906d2a4 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Thu, 6 Jun 2013 11:35:49 +0530 Subject: [PATCH 04/16] [system console] [security fix] removed system console --- patches/patch_list.py | 1 + 1 file changed, 1 insertion(+) diff --git a/patches/patch_list.py b/patches/patch_list.py index 6a396725dd..d8b84da8f8 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -253,4 +253,5 @@ patch_list = [ "patches.may_2013.p04_reorder_level", "patches.may_2013.p05_update_cancelled_gl_entries", "patches.june_2013.p01_update_bom_exploded_items", + "execute:webnotes.delete_doc('DocType', 'System Console')", ] \ No newline at end of file From 6164b89e9588b1047c3687e10458bc656bef09f6 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 6 Jun 2013 17:18:38 +0530 Subject: [PATCH 05/16] [report] listing on home page --- accounts/page/accounts_home/accounts_home.js | 15 +++++---------- .../item_wise_sales_register.py | 2 +- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/accounts/page/accounts_home/accounts_home.js b/accounts/page/accounts_home/accounts_home.js index 7f623d7115..b920bfdbab 100644 --- a/accounts/page/accounts_home/accounts_home.js +++ b/accounts/page/accounts_home/accounts_home.js @@ -127,16 +127,6 @@ wn.module_page["Accounts"] = [ right: true, icon: "icon-table", items: [ - { - "label":wn._("Customer Account Head"), - route: "query-report/Customer Account Head", - doctype: "Account" - }, - { - "label":wn._("Supplier Account Head"), - route: "query-report/Supplier Account Head", - doctype: "Account" - }, { "label":wn._("General Ledger"), page: "general-ledger" @@ -247,6 +237,11 @@ wn.module_page["Accounts"] = [ route: "query-report/Customer Account Head", doctype: "Account" }, + { + "label":wn._("Supplier Account Head"), + route: "query-report/Supplier Account Head", + doctype: "Account" + }, { "label":wn._("Item-wise Sales Register"), route: "query-report/Item-wise Sales Register", diff --git a/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/accounts/report/item_wise_sales_register/item_wise_sales_register.py index f6e26af350..f3ed2a1242 100644 --- a/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -59,7 +59,7 @@ def get_conditions(filters): def get_items(filters): conditions = get_conditions(filters) return webnotes.conn.sql("""select si.name, si.posting_date, si.debit_to, si.project_name, - si.customer, si.remarks, si.territory, si_item.item_code, si_item.item_name, + si.customer, si.remarks, si.territory, si.company, si_item.item_code, si_item.item_name, si_item.item_group, si_item.sales_order, si_item.delivery_note, si_item.income_account, si_item.qty, si_item.basic_rate, si_item.amount from `tabSales Invoice` si, `tabSales Invoice Item` si_item From 1efc8b373446edc0ff2a04a7d328a34ff2ad3f3c Mon Sep 17 00:00:00 2001 From: Saurabh Date: Thu, 6 Jun 2013 19:31:14 +0530 Subject: [PATCH 06/16] [Reprots][No Sales Order From Customer] and [Item Reorder Level] --- selling/page/selling_home/selling_home.js | 10 ++-- .../__init__.py | 0 .../no_sales_order_from_customers.py} | 15 ++--- .../no_sales_order_from_customers.txt} | 8 +-- stock/page/stock_home/stock_home.js | 10 ++-- .../item_reorder_level/item_reorder_level.py | 57 +++++++++++-------- 6 files changed, 52 insertions(+), 48 deletions(-) rename selling/report/{no_sales_order_from_customers_(since_2_months) => no_sales_order_from_customers}/__init__.py (100%) rename selling/report/{no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).py => no_sales_order_from_customers/no_sales_order_from_customers.py} (84%) rename selling/report/{no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).txt => no_sales_order_from_customers/no_sales_order_from_customers.txt} (57%) diff --git a/selling/page/selling_home/selling_home.js b/selling/page/selling_home/selling_home.js index 1f119e2917..603bd3a48f 100644 --- a/selling/page/selling_home/selling_home.js +++ b/selling/page/selling_home/selling_home.js @@ -149,11 +149,6 @@ wn.module_page["Selling"] = [ right: true, icon: "icon-list", items: [ - { - "label":wn._("No Sales Order from Customers (Since 2 months)"), - route: "query-report/No Sales Order from Customers (Since 2 months)", - doctype: "Sales Order" - }, { "label":wn._("Customer Addresses And Contacts"), route: "query-report/Customer Addresses And Contacts" @@ -170,6 +165,11 @@ wn.module_page["Selling"] = [ "label":wn._("Item-wise Sales History"), route: "query-report/Item-wise Sales History", }, + { + "label":wn._("No Sales Order from Customers (Since 2 months)"), + route: "query-report/No Sales Order from Customers", + doctype: "Sales Order" + }, ] } diff --git a/selling/report/no_sales_order_from_customers_(since_2_months)/__init__.py b/selling/report/no_sales_order_from_customers/__init__.py similarity index 100% rename from selling/report/no_sales_order_from_customers_(since_2_months)/__init__.py rename to selling/report/no_sales_order_from_customers/__init__.py diff --git a/selling/report/no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).py b/selling/report/no_sales_order_from_customers/no_sales_order_from_customers.py similarity index 84% rename from selling/report/no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).py rename to selling/report/no_sales_order_from_customers/no_sales_order_from_customers.py index 43efb98d06..789e1684e9 100644 --- a/selling/report/no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).py +++ b/selling/report/no_sales_order_from_customers/no_sales_order_from_customers.py @@ -16,7 +16,6 @@ import webnotes def execute(filters=None): - columns = get_columns() customers = get_so_details() @@ -25,7 +24,6 @@ def execute(filters=None): if cust[8] >= 60: # days_since_last_order cust.insert(7,get_last_so_amt(cust[0])) data.append(cust) - return columns, data def get_so_details(): @@ -40,19 +38,18 @@ def get_so_details(): so.net_total * so.per_delivered/100, so.net_total)) as 'total_order_considered', max(so.transaction_date) as 'last_sales_order_date', - DATEDIFF(CURDATE(),max(so.transaction_date)) as 'days_since_last_order' + DATEDIFF(CURDATE(), max(so.transaction_date)) as 'days_since_last_order' from `tabCustomer` cust, `tabSales Order` so where cust.name = so.customer and so.docstatus = 1 group by cust.name order by 'days_since_last_order' desc """,as_list=1) def get_last_so_amt(customer): - return webnotes.conn.sql("""select net_total from `tabSales Order` - where customer ='%(customer)s' and docstatus = 1 and - transaction_date = (select max(transaction_date) - from `tabSales Order` - where customer = '%(customer)s') - """%{'customer':customer}) + res = webnotes.conn.sql("""select net_total from `tabSales Order` + where customer ='%(customer)s' and docstatus = 1 order by transaction_date desc + limit 1""" % {'customer':customer}) + + return res and res[0][0] or 0 def get_columns(): return [ diff --git a/selling/report/no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).txt b/selling/report/no_sales_order_from_customers/no_sales_order_from_customers.txt similarity index 57% rename from selling/report/no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).txt rename to selling/report/no_sales_order_from_customers/no_sales_order_from_customers.txt index cd7b2b7ff9..32b38ae815 100644 --- a/selling/report/no_sales_order_from_customers_(since_2_months)/no_sales_order_from_customers_(since_2_months).txt +++ b/selling/report/no_sales_order_from_customers/no_sales_order_from_customers.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-06-05 11:40:49", + "creation": "2013-06-06 19:15:50", "docstatus": 0, - "modified": "2013-06-05 11:40:49", + "modified": "2013-06-06 19:15:51", "modified_by": "Administrator", "owner": "Administrator" }, @@ -11,11 +11,11 @@ "is_standard": "Yes", "name": "__common__", "ref_doctype": "Sales Order", - "report_name": "No Sales Order from Customers (Since 2 months)", + "report_name": "No Sales Order from Customers", "report_type": "Script Report" }, { "doctype": "Report", - "name": "No Sales Order from Customers (Since 2 months)" + "name": "No Sales Order from Customers" } ] \ No newline at end of file diff --git a/stock/page/stock_home/stock_home.js b/stock/page/stock_home/stock_home.js index ac3a096c50..ab3d3253bb 100644 --- a/stock/page/stock_home/stock_home.js +++ b/stock/page/stock_home/stock_home.js @@ -128,11 +128,6 @@ wn.module_page["Stock"] = [ right: true, icon: "icon-table", items: [ - { - "label":wn._("Item Reorder Level"), - route: "query-report/Item Reorder Level", - doctype: "Item" - }, { "label":wn._("Stock Ledger"), page: "stock-ledger" @@ -210,6 +205,11 @@ wn.module_page["Stock"] = [ "label":wn._("Requested Items To Be Transferred"), route: "query-report/Requested Items To Be Transferred", }, + { + "label":wn._("Item Reorder Level"), + route: "query-report/Item Reorder Level", + doctype: "Item" + }, ] } ] diff --git a/stock/report/item_reorder_level/item_reorder_level.py b/stock/report/item_reorder_level/item_reorder_level.py index d59696138c..10ee182701 100644 --- a/stock/report/item_reorder_level/item_reorder_level.py +++ b/stock/report/item_reorder_level/item_reorder_level.py @@ -15,27 +15,30 @@ # along with this program. If not, see . import webnotes -from webnotes.utils import getdate, flt, cint +from webnotes.utils import getdate, flt def execute(filters=None): if not filters: filters = {} + float_preceision = webnotes.conn.get_default("float_preceision") + + condition =get_condition(filters) + + avg_daily_outgoing = 0 + diff = ((getdate(filters.get("to_date")) - getdate(filters.get("from_date"))).days)+1 + if diff <= 0: + webnotes.msgprint("To Date should not be less than eual to From Date",raise_exception=1) columns = get_columns() items = get_item_info() - consumed_item_map = get_consumed_items(filters) - delivered_item_map = get_delivered_items(filters) - - avg_daily_outgoing = 0 - diff = (getdate(filters.get("to_date")) - getdate(filters.get("from_date"))).days - if diff <= 0: - webnotes.msgprint("To Date should not be less than eual to From Date",raise_exception=1) + consumed_item_map = get_consumed_items(condition) + delivered_item_map = get_delivered_items(condition) data = [] for item in items: total_outgoing = consumed_item_map.get(item.name, 0)+delivered_item_map.get(item.name,0) - avg_daily_outgoing = cint(total_outgoing/diff) - reorder_level = (avg_daily_outgoing * item.lead_time_days) + item.min_order_qty + avg_daily_outgoing = flt(total_outgoing/diff, float_preceision) + reorder_level = (avg_daily_outgoing * flt(item.lead_time_days)) + flt(item.min_order_qty) data.append([item.name, item.item_name, item.description, item.min_order_qty, item.lead_time_days, consumed_item_map.get(item.name, 0), delivered_item_map.get(item.name,0), total_outgoing, @@ -44,20 +47,24 @@ def execute(filters=None): return columns , data def get_columns(): - return["Item:Link/Item:120", "Item name:Data:120", "description::160", "minimum inventory level::120", - "lead time days::120", "consumed::120", "delivered::120", "total outgoing::120", - "avg daily outgoing::120", "reorder level::120"] + return[ + "Item:Link/Item:120", "Item name:Data:120", "Description::160", + "Minimum Inventory Level:Float:160", "Lead Time Days:Float:120", "Consumed:Float:120", + "Delivered:Float:120", "Total Outgoing:Float:120", "Avg Daily Outgoing:Float:160", + "Reorder Level:Float:120" + ] def get_item_info(): - return webnotes.conn.sql("""select name, item_name, description, min_order_qty, lead_time_days - from tabItem""",as_dict=1) + return webnotes.conn.sql("""select name, item_name, description, min_order_qty, + lead_time_days from tabItem""", as_dict=1) -def get_consumed_items(filters): - condition = get_condition(filters) +def get_consumed_items(condition): - cn_items = webnotes.conn.sql("""select se_item.item_code, sum(se_item.actual_qty) as 'consume_qty' + cn_items = webnotes.conn.sql("""select se_item.item_code, + sum(se_item.actual_qty) as 'consume_qty' from `tabStock Entry` se, `tabStock Entry Detail` se_item - where se.name = se_item.parent and se.docstatus = 1 and ifnull(se_item.t_warehouse, '') = '' %s + where se.name = se_item.parent and se.docstatus = 1 + and ifnull(se_item.t_warehouse, '') = '' %s group by se_item.item_code""" % (condition), as_dict=1) cn_items_map = {} @@ -66,18 +73,18 @@ def get_consumed_items(filters): return cn_items_map -def get_delivered_items(filters): - condition = get_condition(filters) +def get_delivered_items(condition): dn_items = webnotes.conn.sql("""select dn_item.item_code, sum(dn_item.qty) as dn_qty from `tabDelivery Note` dn, `tabDelivery Note Item` dn_item - where dn.name = dn_item.parent and dn.docstatus = 1 %s group by dn_item.item_code""" % (condition) - , as_dict=1) + where dn.name = dn_item.parent and dn.docstatus = 1 %s + group by dn_item.item_code""" % (condition), as_dict=1) si_items = webnotes.conn.sql("""select si_item.item_name, sum(si_item.qty) as si_qty from `tabSales Invoice` si, `tabSales Invoice Item` si_item - where si.name = si_item.parent and si.docstatus = 1 and ifnull(si.update_stock, 0) = 1 - and ifnull(si.is_pos, 0) = 1 %s group by si_item.item_name""" % (condition), as_dict=1) + where si.name = si_item.parent and si.docstatus = 1 and + ifnull(si.update_stock, 0) = 1 and ifnull(si.is_pos, 0) = 1 %s + group by si_item.item_name""" % (condition), as_dict=1) dn_item_map = {} for item in dn_items: From 5b1e899250637b0813c9f0822b24a62249b7fb08 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Fri, 7 Jun 2013 13:34:16 +0530 Subject: [PATCH 07/16] [Reports] [Customers Not Buying Sinse Long Time] and [Itemwise Recommended Reorder level] --- selling/page/selling_home/selling_home.js | 4 ++-- .../__init__.py | 0 .../customers_not_buying_since_long_time.js | 10 ++++++++++ .../customers_not_buying_since_long_time.py} | 11 ++++++++++- .../customers_not_buying_since_long_time.txt} | 8 ++++---- stock/page/stock_home/stock_home.js | 4 ++-- .../__init__.py | 0 .../itemwise_recommended_reorder_level.js} | 2 +- .../itemwise_recommended_reorder_level.py} | 2 +- .../itemwise_recommended_reorder_level.txt} | 8 ++++---- 10 files changed, 34 insertions(+), 15 deletions(-) rename selling/report/{no_sales_order_from_customers => customers_not_buying_since_long_time}/__init__.py (100%) create mode 100644 selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.js rename selling/report/{no_sales_order_from_customers/no_sales_order_from_customers.py => customers_not_buying_since_long_time/customers_not_buying_since_long_time.py} (85%) rename selling/report/{no_sales_order_from_customers/no_sales_order_from_customers.txt => customers_not_buying_since_long_time/customers_not_buying_since_long_time.txt} (59%) rename stock/report/{item_reorder_level => itemwise_recommended_reorder_level}/__init__.py (100%) rename stock/report/{item_reorder_level/item_reorder_level.js => itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.js} (81%) rename stock/report/{item_reorder_level/item_reorder_level.py => itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py} (98%) rename stock/report/{item_reorder_level/item_reorder_level.txt => itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.txt} (59%) diff --git a/selling/page/selling_home/selling_home.js b/selling/page/selling_home/selling_home.js index 603bd3a48f..9c18fda681 100644 --- a/selling/page/selling_home/selling_home.js +++ b/selling/page/selling_home/selling_home.js @@ -166,8 +166,8 @@ wn.module_page["Selling"] = [ route: "query-report/Item-wise Sales History", }, { - "label":wn._("No Sales Order from Customers (Since 2 months)"), - route: "query-report/No Sales Order from Customers", + "label":wn._("Customers Not Buying Since Long Time"), + route: "query-report/Customers Not Buying Since Long Time", doctype: "Sales Order" }, diff --git a/selling/report/no_sales_order_from_customers/__init__.py b/selling/report/customers_not_buying_since_long_time/__init__.py similarity index 100% rename from selling/report/no_sales_order_from_customers/__init__.py rename to selling/report/customers_not_buying_since_long_time/__init__.py diff --git a/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.js b/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.js new file mode 100644 index 0000000000..65d63484a5 --- /dev/null +++ b/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.js @@ -0,0 +1,10 @@ +wn.query_reports["Customers Not Buying Since Long Time"] = { + "filters": [ + { + "fieldname":"days_since_last_order", + "label": "Days Since Last Order", + "fieldtype": "Int", + "default": 60 + } + ] +} \ No newline at end of file diff --git a/selling/report/no_sales_order_from_customers/no_sales_order_from_customers.py b/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.py similarity index 85% rename from selling/report/no_sales_order_from_customers/no_sales_order_from_customers.py rename to selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.py index 789e1684e9..d13315c151 100644 --- a/selling/report/no_sales_order_from_customers/no_sales_order_from_customers.py +++ b/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.py @@ -13,15 +13,24 @@ # # 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 +from webnotes.utils import getdate, cint def execute(filters=None): + if not filters: filters ={} + + days_since_last_order = filters.get("days_since_last_order") + if not days_since_last_order or days_since_last_order <= 0: + webnotes.msgprint("Please mention legal value in days since last order field",raise_exception=1) + columns = get_columns() customers = get_so_details() data = [] for cust in customers: - if cust[8] >= 60: # days_since_last_order + if cust[8] >= days_since_last_order: cust.insert(7,get_last_so_amt(cust[0])) data.append(cust) return columns, data diff --git a/selling/report/no_sales_order_from_customers/no_sales_order_from_customers.txt b/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.txt similarity index 59% rename from selling/report/no_sales_order_from_customers/no_sales_order_from_customers.txt rename to selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.txt index 32b38ae815..4d94377aa9 100644 --- a/selling/report/no_sales_order_from_customers/no_sales_order_from_customers.txt +++ b/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-06-06 19:15:50", + "creation": "2013-06-07 12:27:07", "docstatus": 0, - "modified": "2013-06-06 19:15:51", + "modified": "2013-06-07 12:27:07", "modified_by": "Administrator", "owner": "Administrator" }, @@ -11,11 +11,11 @@ "is_standard": "Yes", "name": "__common__", "ref_doctype": "Sales Order", - "report_name": "No Sales Order from Customers", + "report_name": "Customers Not Buying Since Long Time ", "report_type": "Script Report" }, { "doctype": "Report", - "name": "No Sales Order from Customers" + "name": "Customers Not Buying Since Long Time" } ] \ No newline at end of file diff --git a/stock/page/stock_home/stock_home.js b/stock/page/stock_home/stock_home.js index ab3d3253bb..7e67cab3da 100644 --- a/stock/page/stock_home/stock_home.js +++ b/stock/page/stock_home/stock_home.js @@ -206,8 +206,8 @@ wn.module_page["Stock"] = [ route: "query-report/Requested Items To Be Transferred", }, { - "label":wn._("Item Reorder Level"), - route: "query-report/Item Reorder Level", + "label":wn._("Itemwise Recommended Reorder Level"), + route: "query-report/Itemwise Recommended Reorder Level", doctype: "Item" }, ] diff --git a/stock/report/item_reorder_level/__init__.py b/stock/report/itemwise_recommended_reorder_level/__init__.py similarity index 100% rename from stock/report/item_reorder_level/__init__.py rename to stock/report/itemwise_recommended_reorder_level/__init__.py diff --git a/stock/report/item_reorder_level/item_reorder_level.js b/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.js similarity index 81% rename from stock/report/item_reorder_level/item_reorder_level.js rename to stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.js index 30240e587d..b8aa378828 100644 --- a/stock/report/item_reorder_level/item_reorder_level.js +++ b/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.js @@ -1,4 +1,4 @@ -wn.query_reports["Item Reorder Level"] = { +wn.query_reports["Itemwise Recommended Reorder Level"] = { "filters": [ { "fieldname":"from_date", diff --git a/stock/report/item_reorder_level/item_reorder_level.py b/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py similarity index 98% rename from stock/report/item_reorder_level/item_reorder_level.py rename to stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py index 10ee182701..588132f961 100644 --- a/stock/report/item_reorder_level/item_reorder_level.py +++ b/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py @@ -61,7 +61,7 @@ def get_item_info(): def get_consumed_items(condition): cn_items = webnotes.conn.sql("""select se_item.item_code, - sum(se_item.actual_qty) as 'consume_qty' + sum(se_item.actual_qty) as 'consume_qty' from `tabStock Entry` se, `tabStock Entry Detail` se_item where se.name = se_item.parent and se.docstatus = 1 and ifnull(se_item.t_warehouse, '') = '' %s diff --git a/stock/report/item_reorder_level/item_reorder_level.txt b/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.txt similarity index 59% rename from stock/report/item_reorder_level/item_reorder_level.txt rename to stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.txt index 93c6dfb185..2763f21dfe 100644 --- a/stock/report/item_reorder_level/item_reorder_level.txt +++ b/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-06-05 15:34:51", + "creation": "2013-06-07 12:47:22", "docstatus": 0, - "modified": "2013-06-05 15:50:30", + "modified": "2013-06-07 13:03:54", "modified_by": "Administrator", "owner": "Administrator" }, @@ -11,11 +11,11 @@ "is_standard": "Yes", "name": "__common__", "ref_doctype": "Item", - "report_name": "Item Reorder Level", + "report_name": "Itemwise Recommended Reorder Level", "report_type": "Script Report" }, { "doctype": "Report", - "name": "Item Reorder Level" + "name": "Itemwise Recommended Reorder Level" } ] \ No newline at end of file From d9bf6424470b542439c7eef443ef9694cf3f89a6 Mon Sep 17 00:00:00 2001 From: Saurabh Date: Fri, 7 Jun 2013 15:28:43 +0530 Subject: [PATCH 08/16] [Report][Changes made in Customers Not Buying Since Long Time.py] --- .../customers_not_buying_since_long_time.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.py b/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.py index d13315c151..08809a7619 100644 --- a/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.py +++ b/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.py @@ -22,8 +22,8 @@ def execute(filters=None): if not filters: filters ={} days_since_last_order = filters.get("days_since_last_order") - if not days_since_last_order or days_since_last_order <= 0: - webnotes.msgprint("Please mention legal value in days since last order field",raise_exception=1) + if cint(days_since_last_order) <= 0: + webnotes.msgprint("Please mention positive value in 'Days Since Last Order' field",raise_exception=1) columns = get_columns() customers = get_so_details() From 4bb0eee41117cf6ea17b7e79428bf7cf58c90011 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 7 Jun 2013 17:06:39 +0530 Subject: [PATCH 09/16] [fixes] outstanding for jv --- accounts/doctype/gl_entry/gl_entry.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/accounts/doctype/gl_entry/gl_entry.py b/accounts/doctype/gl_entry/gl_entry.py index 112e449f97..a2ef25a777 100644 --- a/accounts/doctype/gl_entry/gl_entry.py +++ b/accounts/doctype/gl_entry/gl_entry.py @@ -160,13 +160,13 @@ class DocType: def update_outstanding_amt(self): # get final outstanding amt bal = flt(sql("""select sum(debit) - sum(credit) from `tabGL Entry` - where against_voucher=%s and against_voucher_type=%s - and ifnull(is_cancelled,'No') = 'No'""", - (self.doc.against_voucher, self.doc.against_voucher_type))[0][0] or 0.0) - + where against_voucher=%s and against_voucher_type=%s and account = %s + and ifnull(is_cancelled,'No') = 'No'""", (self.doc.against_voucher, + self.doc.against_voucher_type, self.doc.account))[0][0] or 0.0) + if self.doc.against_voucher_type == 'Purchase Invoice': bal = -bal - + elif self.doc.against_voucher_type == "Journal Voucher": against_voucher_amount = flt(webnotes.conn.sql("""select sum(debit) - sum(credit) from `tabGL Entry` where voucher_type = 'Journal Voucher' and voucher_no = %s From b2dc1aeca99c26a577ace74802288520e141b932 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 10 Jun 2013 12:34:31 +0530 Subject: [PATCH 10/16] [lead] [next contact] [fix] create event --- selling/doctype/lead/lead.py | 59 ++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/selling/doctype/lead/lead.py b/selling/doctype/lead/lead.py index 571cdfd516..d80f84362b 100644 --- a/selling/doctype/lead/lead.py +++ b/selling/doctype/lead/lead.py @@ -17,8 +17,7 @@ from __future__ import unicode_literals import webnotes from webnotes import _ -from webnotes.utils import cstr, validate_email_add -from webnotes.model.doc import Document, addchild +from webnotes.utils import cstr, validate_email_add, cint from webnotes import session, msgprint sql = webnotes.conn.sql @@ -54,11 +53,17 @@ class DocType(SellingController): if not validate_email_add(self.doc.email_id): msgprint('Please enter valid email id.') raise Exception + + self._prev = webnotes._dict({ + "contact_date": webnotes.conn.get_value("Lead", self.doc.name, "contact_date") if \ + (not cint(self.doc.fields.get("__islocal"))) else None, + "contact_by": webnotes.conn.get_value("Lead", self.doc.name, "contact_by") if \ + (not cint(self.doc.fields.get("__islocal"))) else None, + }) def on_update(self): - if self.doc.contact_date: - self.add_calendar_event() + self.add_calendar_event() self.check_email_id_is_unique() @@ -73,25 +78,33 @@ class DocType(SellingController): ", ".join(items), raise_exception=True) def add_calendar_event(self): - # delete any earlier event by this lead - sql("delete from tabEvent where ref_type='Lead' and ref_name=%s", self.doc.name) - - # create new event - ev = Document('Event') - ev.owner = self.doc.lead_owner - ev.description = ('Contact ' + cstr(self.doc.lead_name)) + \ - (self.doc.contact_by and ('. By : ' + cstr(self.doc.contact_by)) or '') + \ - (self.doc.remark and ('.To Discuss : ' + cstr(self.doc.remark)) or '') - ev.event_date = self.doc.contact_date - ev.event_hour = '10:00' - ev.event_type = 'Private' - ev.ref_type = 'Lead' - ev.ref_name = self.doc.name - ev.save(1) - - event_user = addchild(ev, 'event_individuals', 'Event User') - event_user.person = self.doc.contact_by - event_user.save() + if self.doc.contact_by != cstr(self._prev.contact_by) or \ + self.doc.contact_date != cstr(self._prev.contact_date): + # delete any earlier event by this lead + for name in webnotes.conn.sql_list("""select name from `tabEvent` + where ref_type="Lead" and ref_name=%s""", self.doc.name): + webnotes.delete_doc("Event", name) + + if self.doc.contact_date: + webnotes.bean([ + { + "doctype": "Event", + "owner": self.doc.lead_owner or self.doc.owner, + "subject": ('Contact ' + cstr(self.doc.lead_name)), + "description": ('Contact ' + cstr(self.doc.lead_name)) + \ + (self.doc.contact_by and ('. By : ' + cstr(self.doc.contact_by)) or '') + \ + (self.doc.remark and ('.To Discuss : ' + cstr(self.doc.remark)) or ''), + "starts_on": self.doc.contact_date + " 10:00:00", + "event_type": "Private", + "ref_type": "Lead", + "ref_name": self.doc.name + }, + { + "doctype": "Event User", + "parentfield": "event_individuals", + "person": self.doc.contact_by + } + ]).insert() def get_sender(self, comm): return webnotes.conn.get_value('Sales Email Settings',None,'email_id') From e53a81dceacbd20375276c068c2f05666ca8d72c Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 10 Jun 2013 15:15:40 +0530 Subject: [PATCH 11/16] [event] [lead, opportunity, project] [fix] create events --- .../p04_fix_event_for_lead_oppty_project.py | 21 ++++++ patches/patch_list.py | 1 + projects/doctype/project/project.py | 70 ++++++++----------- selling/doctype/lead/lead.py | 58 +++++---------- selling/doctype/opportunity/opportunity.py | 65 ++++++++--------- .../maintenance_schedule.py | 39 ++++++----- utilities/transaction_base.py | 36 +++++++++- 7 files changed, 157 insertions(+), 133 deletions(-) create mode 100644 patches/june_2013/p04_fix_event_for_lead_oppty_project.py diff --git a/patches/june_2013/p04_fix_event_for_lead_oppty_project.py b/patches/june_2013/p04_fix_event_for_lead_oppty_project.py new file mode 100644 index 0000000000..a6449c528a --- /dev/null +++ b/patches/june_2013/p04_fix_event_for_lead_oppty_project.py @@ -0,0 +1,21 @@ +import webnotes + +def execute(): + # delete orphaned Event User + webnotes.conn.sql("""delete from `tabEvent User` + where not exists(select name from `tabEvent` where `tabEvent`.name = `tabEvent User`.parent)""") + + for dt in ["Lead", "Opportunity", "Project"]: + for ref_name in webnotes.conn.sql_list("""select ref_name + from `tabEvent` where ref_type=%s and ifnull(starts_on, '')='' """, dt): + if webnotes.conn.exists(dt, ref_name): + controller = webnotes.get_obj(dt, ref_name) + if dt == "Project": + controller.add_calendar_event() + else: + controller.delete_events() + controller._add_calendar_event() + else: + # remove events where ref doc doesn't exist + webnotes.delete_doc("Event", webnotes.conn.sql_list("""select name from `tabEvent` + where ref_type=%s and ref_name=%s""", (dt, ref_name))) \ No newline at end of file diff --git a/patches/patch_list.py b/patches/patch_list.py index d8b84da8f8..6b88955a10 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -254,4 +254,5 @@ patch_list = [ "patches.may_2013.p05_update_cancelled_gl_entries", "patches.june_2013.p01_update_bom_exploded_items", "execute:webnotes.delete_doc('DocType', 'System Console')", + "patches.june_2013.p04_fix_event_for_lead_oppty_project", ] \ No newline at end of file diff --git a/projects/doctype/project/project.py b/projects/doctype/project/project.py index 1de551c753..b519224ab9 100644 --- a/projects/doctype/project/project.py +++ b/projects/doctype/project/project.py @@ -18,24 +18,17 @@ from __future__ import unicode_literals import webnotes from webnotes.utils import flt, getdate -from webnotes.model import db_exists -from webnotes.model.doc import Document -from webnotes.model.bean import copy_doclist from webnotes import msgprint -sql = webnotes.conn.sql - - - class DocType: - def __init__(self, doc, doclist=[]): + def __init__(self, doc, doclist=None): self.doc = doc self.doclist = doclist # Get Customer Details along with its primary contact details # ============================================================== def get_customer_details(self): - details =sql("select address, territory, customer_group,customer_name from `tabCustomer` where name=%s and docstatus!=2",(self.doc.customer),as_dict=1) + details =webnotes.conn.sql("select address, territory, customer_group,customer_name from `tabCustomer` where name=%s and docstatus!=2",(self.doc.customer),as_dict=1) if details: ret = { 'customer_address' : details and details[0]['address'] or '', @@ -44,7 +37,7 @@ class DocType: 'customer_name' : details and details[0]['customer_name'] or '' } #get primary contact details(this is done separately coz. , if join query used & no primary contact thn it would not be able to fetch customer details) - contact_det = sql("select contact_name, phone, email_id from `tabContact` where customer_name='%s' and is_customer=1 and is_primary_contact=1 and docstatus!=2" %(self.doc.customer), as_dict = 1) + contact_det = webnotes.conn.sql("select contact_name, phone, email_id from `tabContact` where customer_name='%s' and is_customer=1 and is_primary_contact=1 and docstatus!=2" %(self.doc.customer), as_dict = 1) ret['contact_person'] = contact_det and contact_det[0]['contact_name'] or '' ret['contact_no'] = contact_det and contact_det[0]['phone'] or '' ret['email_id'] = contact_det and contact_det[0]['email_id'] or '' @@ -52,21 +45,7 @@ class DocType: else: msgprint("Customer : %s does not exist in system." % (self.doc.customer)) raise Exception - - # Get customer's contact person details - # ============================================================== - def get_contact_details(self): - contact = sql("select contact_no, email_id from `tabContact` where contact_name = '%s' and customer_name = '%s' and docstatus != 2" %(self.doc,contact_person,self.doc.customer), as_dict=1) - if contact: - ret = { - 'contact_no' : contact and contact[0]['contact_no'] or '', - 'email_id' : contact and contact[0]['email_id'] or '' - } - return ret - else: - msgprint("Contact Person : %s does not exist in the system." % (self.doc,contact_person)) - raise Exception - + #calculate gross profit #============================================= def get_gross_profit(self): @@ -86,20 +65,29 @@ class DocType: raise Exception def on_update(self): - # update milestones - webnotes.conn.sql("""delete from tabEvent where ref_type='Project' and ref_name=%s""", - self.doc.name) - for d in self.doclist: - if d.doctype=='Project Milestone' and d.docstatus!=2: - self.add_calendar_event(d.milestone, d.milestone_date) + self.add_calendar_event() - def add_calendar_event(self, milestone, date): - """ Add calendar event for task in calendar of Allocated person""" - event = Document('Event') - event.description = milestone + ' for ' + self.doc.name - event.event_date = date - event.event_hour = '10:00' - event.event_type = 'Public' - event.ref_type = 'Project' - event.ref_name = self.doc.name - event.save(1) + def add_calendar_event(self): + # delete any earlier event for this project + self.delete_events() + + # add events + for milestone in self.doclist.get({"parentfield": "project_milestones"}): + description = milestone.milestone + " for " + self.doc.name + webnotes.bean({ + "doctype": "Event", + "owner": self.doc.owner, + "subject": description, + "description": description, + "starts_on": milestone.milestone_date + " 10:00:00", + "event_type": "Private", + "ref_type": self.doc.doctype, + "ref_name": self.doc.name + }).insert() + + def on_trash(self): + self.delete_events() + + def delete_events(self): + webnotes.delete_doc("Event", webnotes.conn.sql_list("""select name from `tabEvent` + where ref_type=%s and ref_name=%s""", (self.doc.doctype, self.doc.name))) \ No newline at end of file diff --git a/selling/doctype/lead/lead.py b/selling/doctype/lead/lead.py index d80f84362b..0e27261a26 100644 --- a/selling/doctype/lead/lead.py +++ b/selling/doctype/lead/lead.py @@ -29,6 +29,13 @@ class DocType(SellingController): self.doc = doc self.doclist = doclist + self._prev = webnotes._dict({ + "contact_date": webnotes.conn.get_value("Lead", self.doc.name, "contact_date") if \ + (not cint(self.doc.fields.get("__islocal"))) else None, + "contact_by": webnotes.conn.get_value("Lead", self.doc.name, "contact_by") if \ + (not cint(self.doc.fields.get("__islocal"))) else None, + }) + def onload(self): self.add_communication_list() @@ -53,19 +60,19 @@ class DocType(SellingController): if not validate_email_add(self.doc.email_id): msgprint('Please enter valid email id.') raise Exception - - self._prev = webnotes._dict({ - "contact_date": webnotes.conn.get_value("Lead", self.doc.name, "contact_date") if \ - (not cint(self.doc.fields.get("__islocal"))) else None, - "contact_by": webnotes.conn.get_value("Lead", self.doc.name, "contact_by") if \ - (not cint(self.doc.fields.get("__islocal"))) else None, - }) - def on_update(self): - self.add_calendar_event() - self.check_email_id_is_unique() + self.add_calendar_event() + + def add_calendar_event(self, opts=None): + super(DocType, self).add_calendar_event({ + "owner": self.doc.lead_owner, + "subject": ('Contact ' + cstr(self.doc.lead_name)), + "description": ('Contact ' + cstr(self.doc.lead_name)) + \ + (self.doc.contact_by and ('. By : ' + cstr(self.doc.contact_by)) or '') + \ + (self.doc.remark and ('.To Discuss : ' + cstr(self.doc.remark)) or '') + }) def check_email_id_is_unique(self): if self.doc.email_id: @@ -76,35 +83,6 @@ class DocType(SellingController): items = [e[0] for e in email_list if e[0]!=self.doc.name] webnotes.msgprint(_("""Email Id must be unique, already exists for: """) + \ ", ".join(items), raise_exception=True) - - def add_calendar_event(self): - if self.doc.contact_by != cstr(self._prev.contact_by) or \ - self.doc.contact_date != cstr(self._prev.contact_date): - # delete any earlier event by this lead - for name in webnotes.conn.sql_list("""select name from `tabEvent` - where ref_type="Lead" and ref_name=%s""", self.doc.name): - webnotes.delete_doc("Event", name) - - if self.doc.contact_date: - webnotes.bean([ - { - "doctype": "Event", - "owner": self.doc.lead_owner or self.doc.owner, - "subject": ('Contact ' + cstr(self.doc.lead_name)), - "description": ('Contact ' + cstr(self.doc.lead_name)) + \ - (self.doc.contact_by and ('. By : ' + cstr(self.doc.contact_by)) or '') + \ - (self.doc.remark and ('.To Discuss : ' + cstr(self.doc.remark)) or ''), - "starts_on": self.doc.contact_date + " 10:00:00", - "event_type": "Private", - "ref_type": "Lead", - "ref_name": self.doc.name - }, - { - "doctype": "Event User", - "parentfield": "event_individuals", - "person": self.doc.contact_by - } - ]).insert() def get_sender(self, comm): return webnotes.conn.get_value('Sales Email Settings',None,'email_id') @@ -113,3 +91,5 @@ class DocType(SellingController): webnotes.conn.sql("""update tabCommunication set lead=null where lead=%s""", self.doc.name) webnotes.conn.sql("""update `tabSupport Ticket` set lead='' where lead=%s""", self.doc.name) + + self.delete_events() \ No newline at end of file diff --git a/selling/doctype/opportunity/opportunity.py b/selling/doctype/opportunity/opportunity.py index 75a7cd270d..0540ac9881 100644 --- a/selling/doctype/opportunity/opportunity.py +++ b/selling/doctype/opportunity/opportunity.py @@ -17,9 +17,7 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import add_days, cstr, getdate -from webnotes.model import db_exists -from webnotes.model.doc import Document, addchild +from webnotes.utils import add_days, cstr, getdate, cint from webnotes.model.bean import getlist from webnotes import msgprint @@ -34,6 +32,13 @@ class DocType(TransactionBase): self.fname = 'enq_details' self.tname = 'Opportunity Item' + self._prev = webnotes._dict({ + "contact_date": webnotes.conn.get_value("Opportunity", self.doc.name, "contact_date") if \ + (not cint(self.doc.fields.get("__islocal"))) else None, + "contact_by": webnotes.conn.get_value("Opportunity", self.doc.name, "contact_by") if \ + (not cint(self.doc.fields.get("__islocal"))) else None, + }) + def onload(self): self.add_communication_list() @@ -84,48 +89,34 @@ class DocType(TransactionBase): def on_update(self): # Add to calendar if self.doc.contact_date and self.doc.contact_date_ref != self.doc.contact_date: - if self.doc.contact_by: - self.add_calendar_event() webnotes.conn.set(self.doc, 'contact_date_ref',self.doc.contact_date) - webnotes.conn.set(self.doc, 'status', 'Draft') - def add_calendar_event(self): - desc='' - user_lst =[] + self.add_calendar_event() + + def add_calendar_event(self, opts=None): + if not opts: + opts = webnotes._dict() + + opts.description = "" + if self.doc.customer: if self.doc.contact_person: - desc = 'Contact '+cstr(self.doc.contact_person) + opts.description = 'Contact '+cstr(self.doc.contact_person) else: - desc = 'Contact customer '+cstr(self.doc.customer) + opts.description = 'Contact customer '+cstr(self.doc.customer) elif self.doc.lead: if self.doc.contact_display: - desc = 'Contact '+cstr(self.doc.contact_display) + opts.description = 'Contact '+cstr(self.doc.contact_display) else: - desc = 'Contact lead '+cstr(self.doc.lead) - desc = desc+ '. By : ' + cstr(self.doc.contact_by) + opts.description = 'Contact lead '+cstr(self.doc.lead) + + opts.subject = opts.description + opts.description += '. By : ' + cstr(self.doc.contact_by) if self.doc.to_discuss: - desc = desc+' To Discuss : ' + cstr(self.doc.to_discuss) + opts.description += ' To Discuss : ' + cstr(self.doc.to_discuss) - ev = Document('Event') - ev.description = desc - ev.event_date = self.doc.contact_date - ev.event_hour = '10:00' - ev.event_type = 'Private' - ev.ref_type = 'Opportunity' - ev.ref_name = self.doc.name - ev.save(1) - - user_lst.append(self.doc.owner) - - chk = sql("select t1.name from `tabProfile` t1, `tabSales Person` t2 where t2.email_id = t1.name and t2.name=%s",self.doc.contact_by) - if chk: - user_lst.append(chk[0][0]) - - for d in user_lst: - ch = addchild(ev, 'event_individuals', 'Event User') - ch.person = d - ch.save(1) + super(DocType, self).add_calendar_event(opts) def set_last_contact_date(self): if self.doc.contact_date_ref and self.doc.contact_date_ref != self.doc.contact_date: @@ -159,6 +150,9 @@ class DocType(TransactionBase): self.set_last_contact_date() self.validate_item_details() self.validate_lead_cust() + + if not self.doc.status: + self.doc.status = "Draft" def on_submit(self): webnotes.conn.set(self.doc, 'status', 'Submitted') @@ -180,3 +174,6 @@ class DocType(TransactionBase): webnotes.conn.set(self.doc, 'status', 'Opportunity Lost') webnotes.conn.set(self.doc, 'order_lost_reason', arg) return 'true' + + def on_trash(self): + self.delete_events() \ No newline at end of file diff --git a/support/doctype/maintenance_schedule/maintenance_schedule.py b/support/doctype/maintenance_schedule/maintenance_schedule.py index 60962b1d52..06c5a47aff 100644 --- a/support/doctype/maintenance_schedule/maintenance_schedule.py +++ b/support/doctype/maintenance_schedule/maintenance_schedule.py @@ -18,7 +18,7 @@ from __future__ import unicode_literals import webnotes from webnotes.utils import add_days, cstr, getdate -from webnotes.model.doc import Document, addchild +from webnotes.model.doc import addchild from webnotes.model.bean import getlist from webnotes.model.code import get_obj from webnotes import msgprint @@ -100,23 +100,21 @@ class DocType(TransactionBase): for key in scheduled_date: if email_map[d.incharge_name]: - self.add_calender_event(key["scheduled_date"],email_map[d.incharge_name],d.item_code) + description = "Reference: %s, Item Code: %s and Customer: %s" % \ + (self.doc.name, d.item_code, self.doc.customer) + webnotes.bean({ + "doctype": "Event", + "owner": email_map[d.incharge_name] or self.doc.owner, + "subject": description, + "description": description, + "starts_on": key["scheduled_date"] + " 10:00:00", + "event_type": "Private", + "ref_type": self.doc.doctype, + "ref_name": self.doc.name + }).insert() + webnotes.conn.set(self.doc, 'status', 'Submitted') - - def add_calender_event(self,scheduled_date,incharge_email,item_code): - """ Add calendar event for Maintenece Schedule in calendar of Allocated person""" - event = Document('Event') - event.owner = incharge_email - event.description = "Reference:%s, Item Code:%s and Customer: %s" %(self.doc.name, item_code, self.doc.customer) - event.event_date = scheduled_date - event.event_hour = '10:00' - event.event_type = 'Private' - event.ref_type = 'Maintenance Schedule' - event.ref_name = self.doc.name - event.save(1) - - #get schedule dates #---------------------- def create_schedule_list(self, start_date, end_date, no_of_visit): @@ -329,8 +327,13 @@ class DocType(TransactionBase): if d.serial_no: self.update_amc_date(d.serial_no, '') webnotes.conn.set(self.doc, 'status', 'Cancelled') - sql("delete from `tabEvent` where ref_type='Maintenance Schedule' and ref_name='%s' " %(self.doc.name)) + self.delete_events() + def on_trash(self): - sql("delete from `tabEvent` where ref_type='Maintenance Schedule' and ref_name='%s' " %(self.doc.name)) + self.delete_events() + + def delete_events(self): + webnotes.delete_doc("Event", webnotes.conn.sql_list("""select name from `tabEvent` + where ref_type=%s and ref_name=%s""", (self.doc.doctype, self.doc.name))) diff --git a/utilities/transaction_base.py b/utilities/transaction_base.py index 5d7d1a84b1..4c70eba2d7 100644 --- a/utilities/transaction_base.py +++ b/utilities/transaction_base.py @@ -268,4 +268,38 @@ class TransactionBase(DocListController): def validate_posting_time(self): if not self.doc.posting_time: self.doc.posting_time = now_datetime().strftime('%H:%M:%S') - \ No newline at end of file + + def add_calendar_event(self, opts): + if self.doc.contact_by != cstr(self._prev.contact_by) or \ + self.doc.contact_date != cstr(self._prev.contact_date): + + self.delete_events() + self._add_calendar_event(opts) + + def delete_events(self): + webnotes.delete_doc("Event", webnotes.conn.sql_list("""select name from `tabEvent` + where ref_type=%s and ref_name=%s""", (self.doc.doctype, self.doc.name))) + + def _add_calendar_event(self, opts): + opts = webnotes._dict(opts) + + if self.doc.contact_date: + event_doclist = [{ + "doctype": "Event", + "owner": opts.owner or self.doc.owner, + "subject": opts.subject, + "description": opts.description, + "starts_on": self.doc.contact_date + " 10:00:00", + "event_type": "Private", + "ref_type": self.doc.doctype, + "ref_name": self.doc.name + }] + + if webnotes.conn.exists("Profile", self.doc.contact_by): + event_doclist.append({ + "doctype": "Event User", + "parentfield": "event_individuals", + "person": self.doc.contact_by + }) + + webnotes.bean(event_doclist).insert() From dec9a165ac2c31c51a4bacd4eb763e4790e502c1 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 10 Jun 2013 15:26:54 +0530 Subject: [PATCH 12/16] [patch] [fix] events for project, lead, oppty --- patches/june_2013/p04_fix_event_for_lead_oppty_project.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/patches/june_2013/p04_fix_event_for_lead_oppty_project.py b/patches/june_2013/p04_fix_event_for_lead_oppty_project.py index a6449c528a..6929eedcdd 100644 --- a/patches/june_2013/p04_fix_event_for_lead_oppty_project.py +++ b/patches/june_2013/p04_fix_event_for_lead_oppty_project.py @@ -9,12 +9,7 @@ def execute(): for ref_name in webnotes.conn.sql_list("""select ref_name from `tabEvent` where ref_type=%s and ifnull(starts_on, '')='' """, dt): if webnotes.conn.exists(dt, ref_name): - controller = webnotes.get_obj(dt, ref_name) - if dt == "Project": - controller.add_calendar_event() - else: - controller.delete_events() - controller._add_calendar_event() + webnotes.get_obj(dt, ref_name).add_calendar_event() else: # remove events where ref doc doesn't exist webnotes.delete_doc("Event", webnotes.conn.sql_list("""select name from `tabEvent` From 670199b9c62180044b387a8b9a205986f19e53c3 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 10 Jun 2013 15:38:01 +0530 Subject: [PATCH 13/16] [patch] [fix] event for project, oppty, lead --- patches/june_2013/p04_fix_event_for_lead_oppty_project.py | 5 ++++- selling/doctype/lead/lead.py | 4 ++-- selling/doctype/opportunity/opportunity.py | 4 ++-- utilities/transaction_base.py | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/patches/june_2013/p04_fix_event_for_lead_oppty_project.py b/patches/june_2013/p04_fix_event_for_lead_oppty_project.py index 6929eedcdd..3f66d8bfbb 100644 --- a/patches/june_2013/p04_fix_event_for_lead_oppty_project.py +++ b/patches/june_2013/p04_fix_event_for_lead_oppty_project.py @@ -9,7 +9,10 @@ def execute(): for ref_name in webnotes.conn.sql_list("""select ref_name from `tabEvent` where ref_type=%s and ifnull(starts_on, '')='' """, dt): if webnotes.conn.exists(dt, ref_name): - webnotes.get_obj(dt, ref_name).add_calendar_event() + if dt in ["Lead", "Opportunity"]: + webnotes.get_obj(dt, ref_name).add_calendar_event(force=True) + else: + webnotes.get_obj(dt, ref_name).add_calendar_event() else: # remove events where ref doc doesn't exist webnotes.delete_doc("Event", webnotes.conn.sql_list("""select name from `tabEvent` diff --git a/selling/doctype/lead/lead.py b/selling/doctype/lead/lead.py index 0e27261a26..a54343a907 100644 --- a/selling/doctype/lead/lead.py +++ b/selling/doctype/lead/lead.py @@ -65,14 +65,14 @@ class DocType(SellingController): self.check_email_id_is_unique() self.add_calendar_event() - def add_calendar_event(self, opts=None): + def add_calendar_event(self, opts=None, force=False): super(DocType, self).add_calendar_event({ "owner": self.doc.lead_owner, "subject": ('Contact ' + cstr(self.doc.lead_name)), "description": ('Contact ' + cstr(self.doc.lead_name)) + \ (self.doc.contact_by and ('. By : ' + cstr(self.doc.contact_by)) or '') + \ (self.doc.remark and ('.To Discuss : ' + cstr(self.doc.remark)) or '') - }) + }, force) def check_email_id_is_unique(self): if self.doc.email_id: diff --git a/selling/doctype/opportunity/opportunity.py b/selling/doctype/opportunity/opportunity.py index 0540ac9881..9fb061b228 100644 --- a/selling/doctype/opportunity/opportunity.py +++ b/selling/doctype/opportunity/opportunity.py @@ -93,7 +93,7 @@ class DocType(TransactionBase): self.add_calendar_event() - def add_calendar_event(self, opts=None): + def add_calendar_event(self, opts=None, force=False): if not opts: opts = webnotes._dict() @@ -116,7 +116,7 @@ class DocType(TransactionBase): if self.doc.to_discuss: opts.description += ' To Discuss : ' + cstr(self.doc.to_discuss) - super(DocType, self).add_calendar_event(opts) + super(DocType, self).add_calendar_event(opts, force) def set_last_contact_date(self): if self.doc.contact_date_ref and self.doc.contact_date_ref != self.doc.contact_date: diff --git a/utilities/transaction_base.py b/utilities/transaction_base.py index 4c70eba2d7..f9af912737 100644 --- a/utilities/transaction_base.py +++ b/utilities/transaction_base.py @@ -269,9 +269,9 @@ class TransactionBase(DocListController): if not self.doc.posting_time: self.doc.posting_time = now_datetime().strftime('%H:%M:%S') - def add_calendar_event(self, opts): + def add_calendar_event(self, opts, force=False): if self.doc.contact_by != cstr(self._prev.contact_by) or \ - self.doc.contact_date != cstr(self._prev.contact_date): + self.doc.contact_date != cstr(self._prev.contact_date) or force: self.delete_events() self._add_calendar_event(opts) From f09a9f68e4a7834649e9df9b41f03778b38a72bd Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 10 Jun 2013 15:57:52 +0530 Subject: [PATCH 14/16] [project] [event] fix in creation of event --- projects/doctype/project/project.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/projects/doctype/project/project.py b/projects/doctype/project/project.py index b519224ab9..94b6787312 100644 --- a/projects/doctype/project/project.py +++ b/projects/doctype/project/project.py @@ -73,17 +73,18 @@ class DocType: # add events for milestone in self.doclist.get({"parentfield": "project_milestones"}): - description = milestone.milestone + " for " + self.doc.name - webnotes.bean({ - "doctype": "Event", - "owner": self.doc.owner, - "subject": description, - "description": description, - "starts_on": milestone.milestone_date + " 10:00:00", - "event_type": "Private", - "ref_type": self.doc.doctype, - "ref_name": self.doc.name - }).insert() + if milestone.milestone_date: + description = (milestone.milestone or "Milestone") + " for " + self.doc.name + webnotes.bean({ + "doctype": "Event", + "owner": self.doc.owner, + "subject": description, + "description": description, + "starts_on": milestone.milestone_date + " 10:00:00", + "event_type": "Private", + "ref_type": self.doc.doctype, + "ref_name": self.doc.name + }).insert() def on_trash(self): self.delete_events() From 0175fbd47026daa45333829637285a0e74bfcadb Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 10 Jun 2013 16:27:29 +0530 Subject: [PATCH 15/16] [buying] [purchase taxes] get cost center from taxes master --- buying/doctype/purchase_common/purchase_common.py | 1 + 1 file changed, 1 insertion(+) diff --git a/buying/doctype/purchase_common/purchase_common.py b/buying/doctype/purchase_common/purchase_common.py index d5b563b3c5..2b6ca27acc 100644 --- a/buying/doctype/purchase_common/purchase_common.py +++ b/buying/doctype/purchase_common/purchase_common.py @@ -432,6 +432,7 @@ class DocType(BuyingController): d.account_head = other['account_head'] d.rate = flt(other['rate']) d.tax_amount = flt(other['tax_amount']) + d.cost_center = other["cost_center"] d.idx = idx idx += 1 return obj.doclist From 89e2ac4f477ee6f5c1de170e253188212437df2c Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 10 Jun 2013 17:58:33 +0530 Subject: [PATCH 16/16] [voucher import tool] [fix] validate account columns only for voucher import of type Multiple Accounts --- .../voucher_import_tool.py | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/accounts/page/voucher_import_tool/voucher_import_tool.py b/accounts/page/voucher_import_tool/voucher_import_tool.py index 7634e5bf84..a3790a8fe1 100644 --- a/accounts/page/voucher_import_tool/voucher_import_tool.py +++ b/accounts/page/voucher_import_tool/voucher_import_tool.py @@ -59,7 +59,7 @@ def upload(): if not company_abbr: webnotes.msgprint(_("Company is missing or entered incorrect value"), raise_exception=1) - data, start_idx = get_data(rows, company_abbr) + data, start_idx = get_data(rows, company_abbr, rows[0][0]) except Exception, e: err_msg = webnotes.message_log and "
".join(webnotes.message_log) or cstr(e) messages.append("""

%s

""" % (err_msg or "No message")) @@ -213,10 +213,11 @@ def get_common_values(rows): return common_values -def get_data(rows, company_abbr): +def get_data(rows, company_abbr, import_type): start_row = 0 data = [] start_row_idx = 0 + accounts = None for i in xrange(len(rows)): r = rows[i] if r[0]: @@ -257,17 +258,19 @@ def get_data(rows, company_abbr): columns = [c.replace(" ", "_").lower() for c in rows[i+1] if not c.endswith(" - " + company_abbr)] - accounts = [c for c in rows[i+1] if c.endswith(" - " + company_abbr)] + + if import_type == "Voucher Import: Multiple Accounts": + accounts = [c for c in rows[i+1] if c.endswith(" - " + company_abbr)] - if not accounts: - webnotes.msgprint(_("""No Account found in csv file, - May be company abbreviation is not correct"""), raise_exception=1) + if not accounts: + webnotes.msgprint(_("""No Account found in csv file, + May be company abbreviation is not correct"""), raise_exception=1) - if accounts and (len(columns) != rows[i+1].index(accounts[0])): - webnotes.msgprint(_("""All account columns should be after \ - standard columns and on the right. - If you entered it properly, next probable reason \ - could be wrong account name. - Please rectify it in the file and try again."""), raise_exception=1) + if accounts and (len(columns) != rows[i+1].index(accounts[0])): + webnotes.msgprint(_("""All account columns should be after \ + standard columns and on the right. + If you entered it properly, next probable reason \ + could be wrong account name. + Please rectify it in the file and try again."""), raise_exception=1) return data, start_row_idx \ No newline at end of file