From 5c7557914b38698ffb2bfe3df4747dac52738c62 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 11 Jun 2015 16:50:28 +0530 Subject: [PATCH 1/8] Removed BOM No from mandatory from Stock Entry against Production Order --- erpnext/stock/doctype/stock_entry/stock_entry.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index da86432388..d823e7ebbd 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -185,9 +185,6 @@ class StockEntry(StockController): def validate_production_order(self): if self.purpose in ("Manufacture", "Material Transfer for Manufacture"): - if not self.bom_no: - frappe.throw(_("BOM No is mandatory")) - # check if production order is entered if not self.production_order: frappe.throw(_("Production order number is mandatory for stock entry purpose manufacture")) From 804b4acb9be21ab7e6ea574c22f1f2b868afc4d2 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 11 Jun 2015 16:56:36 +0530 Subject: [PATCH 2/8] [fix] Issue fixed in C-Form related to field renaming --- erpnext/accounts/doctype/c_form/c_form.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/c_form/c_form.py b/erpnext/accounts/doctype/c_form/c_form.py index 90647547fd..c14990ae73 100644 --- a/erpnext/accounts/doctype/c_form/c_form.py +++ b/erpnext/accounts/doctype/c_form/c_form.py @@ -54,7 +54,7 @@ class CForm(Document): frappe.throw(_("Please enter atleast 1 invoice in the table")) def set_total_invoiced_amount(self): - total = sum([flt(d.base_grand_total) for d in self.get('invoices')]) + total = sum([flt(d.grand_total) for d in self.get('invoices')]) frappe.db.set(self, 'total_invoiced_amount', total) def get_invoice_details(self, invoice_no): From fc595064e0bbce55adb13d1e5f96b180b415d3e6 Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Wed, 10 Jun 2015 17:57:27 +0530 Subject: [PATCH 3/8] validation added to prevent Delivery Date in Porduction Order to be lesser than Planned Start Date --- .../doctype/production_order/production_order.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py index 529c2a4b4b..6de0d7b46d 100644 --- a/erpnext/manufacturing/doctype/production_order/production_order.py +++ b/erpnext/manufacturing/doctype/production_order/production_order.py @@ -309,10 +309,9 @@ class ProductionOrder(Document): self.actual_end_date = None def validate_delivery_date(self): - if self.docstatus==1: - if self.planned_end_date and self.expected_delivery_date \ - and getdate(self.expected_delivery_date) < getdate(self.planned_end_date): - frappe.msgprint(_("Production might not be able to finish by the Expected Delivery Date.")) + if self.planned_start_date and self.expected_delivery_date \ + and getdate(self.expected_delivery_date) < getdate(self.planned_start_date): + frappe.throw(_("Expected Delivery Date must be greater than Planned Start Date.")) def delete_time_logs(self): for time_log in frappe.get_all("Time Log", ["name"], {"production_order": self.name}): From 1792ff3be72f654719279815633cc550b1b608c4 Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Thu, 11 Jun 2015 15:47:48 +0530 Subject: [PATCH 4/8] Validation added in Purchase Invoice to check if Supplier Invoice Date is greater than Posting Date Check Supplier Invoice Number Uniqueness setting added to Accounts Settings Validation added in Purchase Invoice to check Supplier Invoice Number Uniqueness if Check Supplier Invoice Number Uniqueness is enabled in Accounts Settings --- .../doctype/accounts_settings/accounts_settings.json | 9 ++++++++- .../doctype/purchase_invoice/purchase_invoice.py | 11 +++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index 9ef011b943..231c8ab874 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -4,6 +4,13 @@ "docstatus": 0, "doctype": "DocType", "fields": [ + { + "fieldname": "check_supplier_invoice_uniqueness", + "fieldtype": "Check", + "label": "Check Supplier Invoice Number Uniqueness", + "permlevel": 0, + "precision": "" + }, { "default": "1", "description": "If enabled, the system will post accounting entries for inventory automatically.", @@ -43,7 +50,7 @@ "icon": "icon-cog", "idx": 1, "issingle": 1, - "modified": "2015-02-05 05:11:34.163902", + "modified": "2015-06-11 06:06:34.047890", "modified_by": "Administrator", "module": "Accounts", "name": "Accounts Settings", diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index c0ebf686cb..2516ded589 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -39,6 +39,7 @@ class PurchaseInvoice(BuyingController): self.po_required() self.pr_required() + self.validate_supplier_invoice() self.check_active_purchase_items() self.check_conversion_rate() self.validate_credit_to_acc() @@ -385,6 +386,16 @@ class PurchaseInvoice(BuyingController): project.update_purchase_costing() project.save() project_list.append(d.project_name) + + def validate_supplier_invoice(self): + if self.bill_date: + if self.bill_date > self.posting_date: + frappe.throw("Supplier Invoice Date cannot be greater than Posting Date") + if self.bill_no: + if cint(frappe.db.get_single_value("Accounts Settings", "check_supplier_invoice_uniqueness")): + pi = frappe.db.exists("Purchase Invoice", {"bill_no": self.bill_no, "fiscal_year": self.fiscal_year}) + if pi: + frappe.throw("Supplier Invoice No exists in Purchase Invoice {0}".format(pi)) @frappe.whitelist() def get_expense_account(doctype, txt, searchfield, start, page_len, filters): From 1f048b24265aa271d34921a23aed113f36a93d0d Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Thu, 11 Jun 2015 16:24:31 +0530 Subject: [PATCH 5/8] Fixes in Activity Cost --- .../projects/doctype/activity_cost/activity_cost.js | 1 + .../projects/doctype/activity_cost/activity_cost.json | 11 ++++++----- .../projects/doctype/activity_cost/activity_cost.py | 2 ++ 3 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 erpnext/projects/doctype/activity_cost/activity_cost.js diff --git a/erpnext/projects/doctype/activity_cost/activity_cost.js b/erpnext/projects/doctype/activity_cost/activity_cost.js new file mode 100644 index 0000000000..ba10153e5c --- /dev/null +++ b/erpnext/projects/doctype/activity_cost/activity_cost.js @@ -0,0 +1 @@ +cur_frm.add_fetch('employee', 'employee_name', 'employee_name'); \ No newline at end of file diff --git a/erpnext/projects/doctype/activity_cost/activity_cost.json b/erpnext/projects/doctype/activity_cost/activity_cost.json index 7f7720acbb..bdc147e5fb 100644 --- a/erpnext/projects/doctype/activity_cost/activity_cost.json +++ b/erpnext/projects/doctype/activity_cost/activity_cost.json @@ -2,7 +2,7 @@ "allow_copy": 0, "allow_import": 1, "allow_rename": 1, - "autoname": "Activity Cost - .#", + "autoname": "AC-.#####", "creation": "2015-03-23 02:00:21.861546", "custom": 0, "docstatus": 0, @@ -31,11 +31,12 @@ }, { "fieldname": "employee_name", - "fieldtype": "Read Only", + "fieldtype": "Data", "label": "Employee Name", - "options": "employee.employee_name", + "options": "", "permlevel": 0, - "precision": "" + "precision": "", + "read_only": 1 }, { "fieldname": "column_break_2", @@ -135,7 +136,7 @@ "is_submittable": 0, "issingle": 0, "istable": 0, - "modified": "2015-04-14 02:08:33.690406", + "modified": "2015-06-11 06:50:47.999788", "modified_by": "Administrator", "module": "Projects", "name": "Activity Cost", diff --git a/erpnext/projects/doctype/activity_cost/activity_cost.py b/erpnext/projects/doctype/activity_cost/activity_cost.py index 121e6508f8..8cd04f564a 100644 --- a/erpnext/projects/doctype/activity_cost/activity_cost.py +++ b/erpnext/projects/doctype/activity_cost/activity_cost.py @@ -15,6 +15,8 @@ class ActivityCost(Document): self.check_unique() def set_title(self): + if not self.employee_name: + self.employee_name = frappe.db.get_value("Employee", self.employee, "employee_name") self.title = _("{0} for {1}").format(self.employee_name, self.activity_type) def check_unique(self): From 587bd144d554cca8e4b789f69fd2c00295933b30 Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Thu, 11 Jun 2015 18:36:35 +0530 Subject: [PATCH 6/8] Added Customers Not Buying Since Long Time against Sales Invoice --- .../customers_not_buying_since_long_time.js | 7 ++++ .../customers_not_buying_since_long_time.py | 42 ++++++++++++------- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/erpnext/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.js b/erpnext/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.js index e975e9f1a2..6d00b829ee 100644 --- a/erpnext/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.js +++ b/erpnext/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.js @@ -8,6 +8,13 @@ frappe.query_reports["Customers Not Buying Since Long Time"] = { "label": __("Days Since Last Order"), "fieldtype": "Int", "default": 60 + }, + { + "fieldname":"doctype", + "label": __("Doctype"), + "fieldtype": "Select", + "default": "Sales Order", + "options": "Sales Order\nSales Invoice" } ] } \ No newline at end of file diff --git a/erpnext/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.py b/erpnext/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.py index de4c655be9..86186aa8fd 100644 --- a/erpnext/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.py +++ b/erpnext/selling/report/customers_not_buying_since_long_time/customers_not_buying_since_long_time.py @@ -10,41 +10,51 @@ def execute(filters=None): if not filters: filters ={} days_since_last_order = filters.get("days_since_last_order") + doctype = filters.get("doctype") + if cint(days_since_last_order) <= 0: frappe.throw(_("'Days Since Last Order' must be greater than or equal to zero")) columns = get_columns() - customers = get_so_details() + customers = get_sales_details(doctype) data = [] for cust in customers: if cint(cust[8]) >= cint(days_since_last_order): - cust.insert(7,get_last_so_amt(cust[0])) + cust.insert(7,get_last_sales_amt(cust[0], doctype)) data.append(cust) return columns, data -def get_so_details(): +def get_sales_details(doctype): + cond = """sum(so.base_net_total) as 'total_order_considered', + max(so.posting_date) as 'last_order_date', + DATEDIFF(CURDATE(), max(so.posting_date)) as 'days_since_last_order' """ + if doctype == "Sales Order": + cond = """sum(if(so.status = "Stopped", + so.base_net_total * so.per_delivered/100, + so.base_net_total)) as 'total_order_considered', + max(so.transaction_date) as 'last_order_date', + DATEDIFF(CURDATE(), max(so.transaction_date)) as 'days_since_last_order'""" + return frappe.db.sql("""select cust.name, cust.customer_name, cust.territory, cust.customer_group, count(distinct(so.name)) as 'num_of_order', - sum(base_net_total) as 'total_order_value', - sum(if(so.status = "Stopped", - so.base_net_total * so.per_delivered/100, - so.base_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 + sum(base_net_total) as 'total_order_value', {0} + from `tabCustomer` cust, `tab{1}` so where cust.name = so.customer and so.docstatus = 1 group by cust.name - order by 'days_since_last_order' desc """,as_list=1) + order by 'days_since_last_order' desc """.format(cond, doctype), as_list=1) -def get_last_so_amt(customer): - res = frappe.db.sql("""select base_net_total from `tabSales Order` - where customer = %s and docstatus = 1 order by transaction_date desc - limit 1""", customer) +def get_last_sales_amt(customer, doctype): + cond = "posting_date" + if doctype =="Sales Order": + cond = "transaction_date" + res = frappe.db.sql("""select base_net_total from `tab{0}` + where customer = %s and docstatus = 1 order by {1} desc + limit 1""".format(doctype, cond), customer) return res and res[0][0] or 0 @@ -58,6 +68,6 @@ def get_columns(): _("Total Order Value") + ":Currency:120", _("Total Order Considered") + ":Currency:160", _("Last Order Amount") + ":Currency:160", - _("Last Sales Order Date") + ":Date:160", + _("Last Order Date") + ":Date:160", _("Days Since Last Order") + "::160" ] From 89592c51804b110462a73d5e6f851449062dfda3 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 12 Jun 2015 17:37:28 +0530 Subject: [PATCH 7/8] Load tasks in project for printing purpose --- erpnext/projects/doctype/project/project.py | 30 ++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py index 37a8b1b967..05e40388bf 100644 --- a/erpnext/projects/doctype/project/project.py +++ b/erpnext/projects/doctype/project/project.py @@ -13,19 +13,25 @@ class Project(Document): def get_feed(self): return '{0}: {1}'.format(_(self.status), self.project_name) - def __setup__(self): + def onload(self): """Load project tasks for quick view""" - self.tasks = [] - for task in frappe.get_all("Task", "*", {"project": self.name}, order_by="exp_start_date asc"): - self.append("tasks", { - "title": task.subject, - "status": task.status, - "start_date": task.exp_start_date, - "end_date": task.exp_end_date, - "description": task.description, - "task_id": task.name - }) - + if not self.get("tasks"): + for task in self.get_tasks(): + self.append("tasks", { + "title": task.subject, + "status": task.status, + "start_date": task.exp_start_date, + "end_date": task.exp_end_date, + "description": task.description, + "task_id": task.name + }) + + def __setup__(self): + self.onload() + + def get_tasks(self): + return frappe.get_all("Task", "*", {"project": self.name}, order_by="exp_start_date asc") + def validate(self): self.validate_dates() self.sync_tasks() From e37dd77923302fef14c4b4270ee0718b79026217 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 12 Jun 2015 18:36:21 +0600 Subject: [PATCH 8/8] bumped to version 5.0.22 --- erpnext/__version__.py | 2 +- erpnext/hooks.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/__version__.py b/erpnext/__version__.py index af58b16bb6..c06779871a 100644 --- a/erpnext/__version__.py +++ b/erpnext/__version__.py @@ -1,2 +1,2 @@ from __future__ import unicode_literals -__version__ = '5.0.21' +__version__ = '5.0.22' diff --git a/erpnext/hooks.py b/erpnext/hooks.py index 1684645ea1..1f0b547041 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -5,7 +5,7 @@ app_publisher = "Frappe Technologies Pvt. Ltd. and Contributors" app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations" app_icon = "icon-th" app_color = "#e74c3c" -app_version = "5.0.21" +app_version = "5.0.22" error_report_email = "support@erpnext.com" diff --git a/setup.py b/setup.py index 9fe6e2f2c4..2a8f024827 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -version = "5.0.21" +version = "5.0.22" with open("requirements.txt", "r") as f: install_requires = f.readlines()