Merge branch 'develop'
diff --git a/erpnext/__version__.py b/erpnext/__version__.py
index 18ebfcc..e571e3d 100644
--- a/erpnext/__version__.py
+++ b/erpnext/__version__.py
@@ -1,2 +1,2 @@
from __future__ import unicode_literals
-__version__ = '5.0.23'
+__version__ = '5.0.24'
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 2516ded..8820c87 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import cint, formatdate, flt
+from frappe.utils import cint, formatdate, flt, getdate
from frappe import msgprint, _, throw
from erpnext.setup.utils import get_company_currency
import frappe.defaults
@@ -389,7 +389,7 @@
def validate_supplier_invoice(self):
if self.bill_date:
- if self.bill_date > self.posting_date:
+ if getdate(self.bill_date) > getdate(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")):
diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
index bdfdf0e..19703be 100644
--- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
+++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py
@@ -171,7 +171,7 @@
def get_gl_entries(self, party_type):
if not hasattr(self, "gl_entries"):
conditions, values = self.prepare_conditions(party_type)
- self.gl_entries = frappe.db.sql("""select posting_date, account, party_type, party, debit, credit,
+ self.gl_entries = frappe.db.sql("""select name, posting_date, account, party_type, party, debit, credit,
voucher_type, voucher_no, against_voucher_type, against_voucher from `tabGL Entry`
where docstatus < 2 and party_type=%s {0} order by posting_date, party"""
.format(conditions), values, as_dict=True)
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 1e9e5c8..cd55d2f 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -5,7 +5,7 @@
app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
app_icon = "icon-th"
app_color = "#e74c3c"
-app_version = "5.0.23"
+app_version = "5.0.24"
error_report_email = "support@erpnext.com"
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.py b/erpnext/hr/doctype/salary_structure/salary_structure.py
index 8580f2e..69f341b 100644
--- a/erpnext/hr/doctype/salary_structure/salary_structure.py
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.py
@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import cstr, flt
+from frappe.utils import cstr, flt, getdate
from frappe.model.naming import make_autoname
from frappe import _
from frappe.model.mapper import get_mapped_doc
@@ -14,6 +14,13 @@
class SalaryStructure(Document):
def autoname(self):
self.name = make_autoname(self.employee + '/.SST' + '/.#####')
+
+ def validate(self):
+ self.check_existing()
+ self.validate_amount()
+ self.validate_employee()
+ self.validate_joining_date()
+ set_employee_name(self)
def get_employee_details(self):
ret = {}
@@ -77,14 +84,11 @@
old_employee = frappe.db.get_value("Salary Structure", self.name, "employee")
if old_employee and self.employee != old_employee:
frappe.throw(_("Employee can not be changed"))
-
-
- def validate(self):
- self.check_existing()
- self.validate_amount()
- self.validate_employee()
- set_employee_name(self)
-
+
+ def validate_joining_date(self):
+ joining_date = getdate(frappe.db.get_value("Employee", self.employee, "date_of_joining"))
+ if getdate(self.from_date) < joining_date:
+ frappe.throw(_("From Date in Salary Structure cannot be lesser than Employee Joining Date."))
@frappe.whitelist()
def make_salary_slip(source_name, target_doc=None):
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.py b/erpnext/manufacturing/doctype/production_order/production_order.py
index 6de0d7b..ca5f6d9 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/production_order.py
@@ -217,12 +217,14 @@
for i, d in enumerate(self.operations):
self.set_operation_start_end_time(i, d)
+ if not d.workstation:
+ continue
+
time_log = make_time_log(self.name, d.operation, d.planned_start_time, d.planned_end_time,
flt(self.qty) - flt(d.completed_qty), self.project_name, d.workstation, operation_id=d.name)
- if d.workstation:
- # validate operating hours if workstation [not mandatory] is specified
- self.check_operation_fits_in_working_hours(d)
+ # validate operating hours if workstation [not mandatory] is specified
+ self.check_operation_fits_in_working_hours(d)
original_start_time = time_log.from_time
while True:
diff --git a/erpnext/projects/doctype/project/project.json b/erpnext/projects/doctype/project/project.json
index 2aca991..486d861 100644
--- a/erpnext/projects/doctype/project/project.json
+++ b/erpnext/projects/doctype/project/project.json
@@ -163,6 +163,7 @@
"fieldtype": "Percent",
"in_list_view": 0,
"label": "% Tasks Completed",
+ "no_copy": 1,
"permlevel": 0,
"read_only": 1
},
@@ -356,7 +357,7 @@
"icon": "icon-puzzle-piece",
"idx": 1,
"max_attachments": 4,
- "modified": "2015-04-27 07:37:44.239930",
+ "modified": "2015-06-12 09:00:54.080220",
"modified_by": "Administrator",
"module": "Projects",
"name": "Project",
diff --git a/erpnext/projects/doctype/time_log/time_log.py b/erpnext/projects/doctype/time_log/time_log.py
index a0fa23b..aa5647e 100644
--- a/erpnext/projects/doctype/time_log/time_log.py
+++ b/erpnext/projects/doctype/time_log/time_log.py
@@ -128,7 +128,7 @@
def update_production_order(self):
"""Updates `start_date`, `end_date`, `status` for operation in Production Order."""
-
+
if self.production_order and self.for_manufacturing:
if not self.operation_id:
frappe.throw(_("Operation ID not set"))
@@ -208,22 +208,23 @@
self.production_order = None
self.operation = None
self.quantity = None
-
+
def update_cost(self):
rate = get_activity_cost(self.employee, self.activity_type)
if rate:
self.costing_rate = rate.get('costing_rate')
- self.billing_rate = rate.get('billing_rate')
+ self.billing_rate = rate.get('billing_rate')
self.costing_amount = self.costing_rate * self.hours
if self.billable:
self.billing_amount = self.billing_rate * self.hours
else:
self.billing_amount = 0
-
+
def validate_task(self):
- if self.project and not self.task:
+ # if a time log is being created against a project without production order
+ if (self.project and not self.production_order) and not self.task:
frappe.throw(_("Task is Mandatory if Time Log is against a project"))
-
+
def update_task(self):
if self.task and frappe.db.exists("Task", self.task):
task = frappe.get_doc("Task", self.task)
@@ -266,7 +267,7 @@
d.title += " for Project: " + d.project
return data
-
+
@frappe.whitelist()
def get_activity_cost(employee=None, activity_type=None):
rate = frappe.db.sql("""select costing_rate, billing_rate from `tabActivity Cost` where employee= %s
diff --git a/setup.py b/setup.py
index 16213d1..103dd77 100644
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,6 @@
from setuptools import setup, find_packages
-version = "5.0.23"
+version = "5.0.24"
with open("requirements.txt", "r") as f:
install_requires = f.readlines()