mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-26 00:14:50 +00:00
Merge branch 'develop'
This commit is contained in:
@@ -1,2 +1,2 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
__version__ = '5.0.19'
|
__version__ = '5.0.20'
|
||||||
|
|||||||
@@ -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_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
|
||||||
app_icon = "icon-th"
|
app_icon = "icon-th"
|
||||||
app_color = "#e74c3c"
|
app_color = "#e74c3c"
|
||||||
app_version = "5.0.19"
|
app_version = "5.0.20"
|
||||||
|
|
||||||
error_report_email = "support@erpnext.com"
|
error_report_email = "support@erpnext.com"
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,11 @@ class Task(Document):
|
|||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_dates()
|
self.validate_dates()
|
||||||
|
|
||||||
|
if self.status!=self.get_db_value("status") and self.status == "Closed":
|
||||||
|
from frappe.desk.form.assign_to import clear
|
||||||
|
clear(self.doctype, self.name)
|
||||||
|
|
||||||
def validate_dates(self):
|
def validate_dates(self):
|
||||||
if self.exp_start_date and self.exp_end_date and getdate(self.exp_start_date) > getdate(self.exp_end_date):
|
if self.exp_start_date and self.exp_end_date and getdate(self.exp_start_date) > getdate(self.exp_end_date):
|
||||||
frappe.throw(_("'Expected Start Date' can not be greater than 'Expected End Date'"))
|
frappe.throw(_("'Expected Start Date' can not be greater than 'Expected End Date'"))
|
||||||
@@ -41,17 +45,17 @@ class Task(Document):
|
|||||||
self.reschedule_dependent_tasks()
|
self.reschedule_dependent_tasks()
|
||||||
self.update_percentage()
|
self.update_percentage()
|
||||||
self.update_project()
|
self.update_project()
|
||||||
|
|
||||||
def update_percentage(self):
|
def update_percentage(self):
|
||||||
"""update percent complete in project"""
|
"""update percent complete in project"""
|
||||||
if self.project and not self.flags.from_project:
|
if self.project and not self.flags.from_project:
|
||||||
project = frappe.get_doc("Project", self.project)
|
project = frappe.get_doc("Project", self.project)
|
||||||
project.run_method("update_percent_complete")
|
project.run_method("update_percent_complete")
|
||||||
|
|
||||||
def update_total_expense_claim(self):
|
def update_total_expense_claim(self):
|
||||||
self.total_expense_claim = frappe.db.sql("""select sum(total_sanctioned_amount) from `tabExpense Claim`
|
self.total_expense_claim = frappe.db.sql("""select sum(total_sanctioned_amount) from `tabExpense Claim`
|
||||||
where project = %s and task = %s and approval_status = "Approved" and docstatus=1""",(self.project, self.name))
|
where project = %s and task = %s and approval_status = "Approved" and docstatus=1""",(self.project, self.name))
|
||||||
|
|
||||||
def update_time_and_costing(self):
|
def update_time_and_costing(self):
|
||||||
tl = frappe.db.sql("""select min(from_time) as start_date, max(to_time) as end_date,
|
tl = frappe.db.sql("""select min(from_time) as start_date, max(to_time) as end_date,
|
||||||
sum(billing_amount) as total_billing_amount, sum(costing_amount) as total_costing_amount,
|
sum(billing_amount) as total_billing_amount, sum(costing_amount) as total_costing_amount,
|
||||||
@@ -64,14 +68,14 @@ class Task(Document):
|
|||||||
self.actual_time= tl.time
|
self.actual_time= tl.time
|
||||||
self.act_start_date= tl.start_date
|
self.act_start_date= tl.start_date
|
||||||
self.act_end_date= tl.end_date
|
self.act_end_date= tl.end_date
|
||||||
|
|
||||||
def update_project(self):
|
def update_project(self):
|
||||||
if self.project and frappe.db.exists("Project", self.project):
|
if self.project and frappe.db.exists("Project", self.project):
|
||||||
project = frappe.get_doc("Project", self.project)
|
project = frappe.get_doc("Project", self.project)
|
||||||
project.flags.dont_sync_tasks = True
|
project.flags.dont_sync_tasks = True
|
||||||
project.update_costing()
|
project.update_costing()
|
||||||
project.save()
|
project.save()
|
||||||
|
|
||||||
def check_recursion(self):
|
def check_recursion(self):
|
||||||
if self.flags.ignore_recursion_check: return
|
if self.flags.ignore_recursion_check: return
|
||||||
check_list = [['task', 'parent'], ['parent', 'task']]
|
check_list = [['task', 'parent'], ['parent', 'task']]
|
||||||
@@ -88,7 +92,7 @@ class Task(Document):
|
|||||||
task_list.append(b[0])
|
task_list.append(b[0])
|
||||||
if count == 15:
|
if count == 15:
|
||||||
break
|
break
|
||||||
|
|
||||||
def reschedule_dependent_tasks(self):
|
def reschedule_dependent_tasks(self):
|
||||||
end_date = self.exp_end_date or self.act_end_date
|
end_date = self.exp_end_date or self.act_end_date
|
||||||
if end_date:
|
if end_date:
|
||||||
|
|||||||
@@ -11,19 +11,19 @@ from erpnext.projects.doctype.task.task import CircularReferenceError
|
|||||||
|
|
||||||
class TestTask(unittest.TestCase):
|
class TestTask(unittest.TestCase):
|
||||||
def test_circular_reference(self):
|
def test_circular_reference(self):
|
||||||
|
|
||||||
task1 = frappe.new_doc('Task')
|
task1 = frappe.new_doc('Task')
|
||||||
task1.update({
|
task1.update({
|
||||||
"status": "Open",
|
"status": "Open",
|
||||||
"subject": "_Test Task 1",
|
"subject": "_Test Task 1",
|
||||||
"exp_start_date": "2015-1-1",
|
"exp_start_date": "2015-1-1",
|
||||||
"exp_end_date": "2015-1-10"
|
"exp_end_date": "2015-1-10"
|
||||||
})
|
})
|
||||||
task1.save()
|
task1.save()
|
||||||
|
|
||||||
task2 = frappe.new_doc('Task')
|
task2 = frappe.new_doc('Task')
|
||||||
task2.update({
|
task2.update({
|
||||||
"status": "Open",
|
"status": "Open",
|
||||||
"subject": "_Test Task 2",
|
"subject": "_Test Task 2",
|
||||||
"exp_start_date": "2015-1-11",
|
"exp_start_date": "2015-1-11",
|
||||||
"exp_end_date": "2015-1-15",
|
"exp_end_date": "2015-1-15",
|
||||||
@@ -34,10 +34,10 @@ class TestTask(unittest.TestCase):
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
task2.save()
|
task2.save()
|
||||||
|
|
||||||
task3 = frappe.new_doc('Task')
|
task3 = frappe.new_doc('Task')
|
||||||
task3.update({
|
task3.update({
|
||||||
"status": "Open",
|
"status": "Open",
|
||||||
"subject": "_Test Task 2",
|
"subject": "_Test Task 2",
|
||||||
"exp_start_date": "2015-1-11",
|
"exp_start_date": "2015-1-11",
|
||||||
"exp_end_date": "2015-1-15",
|
"exp_end_date": "2015-1-15",
|
||||||
@@ -53,13 +53,13 @@ class TestTask(unittest.TestCase):
|
|||||||
"task": task3.name
|
"task": task3.name
|
||||||
})
|
})
|
||||||
self.assertRaises(CircularReferenceError, task1.save)
|
self.assertRaises(CircularReferenceError, task1.save)
|
||||||
|
|
||||||
task1.set("depends_on", [])
|
task1.set("depends_on", [])
|
||||||
task1.save()
|
task1.save()
|
||||||
|
|
||||||
task4 = frappe.new_doc('Task')
|
task4 = frappe.new_doc('Task')
|
||||||
task4.update({
|
task4.update({
|
||||||
"status": "Open",
|
"status": "Open",
|
||||||
"subject": "_Test Task 1",
|
"subject": "_Test Task 1",
|
||||||
"exp_start_date": "2015-1-1",
|
"exp_start_date": "2015-1-1",
|
||||||
"exp_end_date": "2015-1-15",
|
"exp_end_date": "2015-1-15",
|
||||||
@@ -74,20 +74,20 @@ class TestTask(unittest.TestCase):
|
|||||||
task3.append("depends_on", {
|
task3.append("depends_on", {
|
||||||
"task": task4.name
|
"task": task4.name
|
||||||
})
|
})
|
||||||
|
|
||||||
def test_reschedule_dependent_task(self):
|
def test_reschedule_dependent_task(self):
|
||||||
task1 = frappe.new_doc('Task')
|
task1 = frappe.new_doc('Task')
|
||||||
task1.update({
|
task1.update({
|
||||||
"status": "Open",
|
"status": "Open",
|
||||||
"subject": "_Test Task 1",
|
"subject": "_Test Task 1",
|
||||||
"exp_start_date": "2015-1-1",
|
"exp_start_date": "2015-1-1",
|
||||||
"exp_end_date": "2015-1-10"
|
"exp_end_date": "2015-1-10"
|
||||||
})
|
})
|
||||||
task1.save()
|
task1.save()
|
||||||
|
|
||||||
task2 = frappe.new_doc('Task')
|
task2 = frappe.new_doc('Task')
|
||||||
task2.update({
|
task2.update({
|
||||||
"status": "Open",
|
"status": "Open",
|
||||||
"subject": "_Test Task 2",
|
"subject": "_Test Task 2",
|
||||||
"exp_start_date": "2015-1-11",
|
"exp_start_date": "2015-1-11",
|
||||||
"exp_end_date": "2015-1-15",
|
"exp_end_date": "2015-1-15",
|
||||||
@@ -98,10 +98,10 @@ class TestTask(unittest.TestCase):
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
task2.save()
|
task2.save()
|
||||||
|
|
||||||
task3 = frappe.new_doc('Task')
|
task3 = frappe.new_doc('Task')
|
||||||
task3.update({
|
task3.update({
|
||||||
"status": "Open",
|
"status": "Open",
|
||||||
"subject": "_Test Task 3",
|
"subject": "_Test Task 3",
|
||||||
"exp_start_date": "2015-1-16",
|
"exp_start_date": "2015-1-16",
|
||||||
"exp_end_date": "2015-1-18",
|
"exp_end_date": "2015-1-18",
|
||||||
@@ -112,18 +112,18 @@ class TestTask(unittest.TestCase):
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
task3.save()
|
task3.save()
|
||||||
|
|
||||||
task1.update({
|
task1.update({
|
||||||
"exp_end_date": "2015-1-20"
|
"exp_end_date": "2015-1-20"
|
||||||
})
|
})
|
||||||
task1.save()
|
task1.save()
|
||||||
|
|
||||||
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_start_date"), getdate('2015-1-21'))
|
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_start_date"), getdate('2015-1-21'))
|
||||||
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_end_date"), getdate('2015-1-25'))
|
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_end_date"), getdate('2015-1-25'))
|
||||||
|
|
||||||
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_start_date"), getdate('2015-1-26'))
|
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_start_date"), getdate('2015-1-26'))
|
||||||
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_end_date"), getdate('2015-1-28'))
|
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_end_date"), getdate('2015-1-28'))
|
||||||
|
|
||||||
time_log = frappe.new_doc('Time Log')
|
time_log = frappe.new_doc('Time Log')
|
||||||
time_log.update({
|
time_log.update({
|
||||||
"from_time": "2015-1-1",
|
"from_time": "2015-1-1",
|
||||||
@@ -131,18 +131,49 @@ class TestTask(unittest.TestCase):
|
|||||||
"task": task1.name
|
"task": task1.name
|
||||||
})
|
})
|
||||||
time_log.submit()
|
time_log.submit()
|
||||||
|
|
||||||
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_start_date"), getdate('2015-1-21'))
|
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_start_date"), getdate('2015-1-21'))
|
||||||
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_end_date"), getdate('2015-1-25'))
|
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_end_date"), getdate('2015-1-25'))
|
||||||
|
|
||||||
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_start_date"), getdate('2015-1-26'))
|
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_start_date"), getdate('2015-1-26'))
|
||||||
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_end_date"), getdate('2015-1-28'))
|
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_end_date"), getdate('2015-1-28'))
|
||||||
|
|
||||||
time_log.cancel()
|
time_log.cancel()
|
||||||
|
|
||||||
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_start_date"), getdate('2015-1-21'))
|
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_start_date"), getdate('2015-1-21'))
|
||||||
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_end_date"), getdate('2015-1-25'))
|
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_end_date"), getdate('2015-1-25'))
|
||||||
|
|
||||||
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_start_date"), getdate('2015-1-26'))
|
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_start_date"), getdate('2015-1-26'))
|
||||||
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_end_date"), getdate('2015-1-28'))
|
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_end_date"), getdate('2015-1-28'))
|
||||||
|
|
||||||
|
|
||||||
|
def test_close_assignment(self):
|
||||||
|
task = frappe.new_doc("Task")
|
||||||
|
task.subject = "Test Close Assignment"
|
||||||
|
task.insert()
|
||||||
|
|
||||||
|
def assign():
|
||||||
|
from frappe.desk.form import assign_to
|
||||||
|
assign_to.add({
|
||||||
|
"assign_to": "test@example.com",
|
||||||
|
"doctype": task.doctype,
|
||||||
|
"name": task.name,
|
||||||
|
"description": "Close this task"
|
||||||
|
})
|
||||||
|
|
||||||
|
def get_owner_and_status():
|
||||||
|
return frappe.db.get_value("ToDo", filters={"reference_type": task.doctype, "reference_name": task.name,
|
||||||
|
"description": "Close this task"}, fieldname=("owner", "status"), as_dict=True)
|
||||||
|
|
||||||
|
assign()
|
||||||
|
todo = get_owner_and_status()
|
||||||
|
self.assertEquals(todo.owner, "test@example.com")
|
||||||
|
self.assertEquals(todo.status, "Open")
|
||||||
|
|
||||||
|
# assignment should be
|
||||||
|
task.load_from_db()
|
||||||
|
task.status = "Closed"
|
||||||
|
task.save()
|
||||||
|
todo = get_owner_and_status()
|
||||||
|
self.assertEquals(todo.owner, "test@example.com")
|
||||||
|
self.assertEquals(todo.status, "Closed")
|
||||||
|
|||||||
@@ -105,6 +105,15 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
barcode: function(doc, cdt, cdn) {
|
||||||
|
var d = locals[cdt][cdn];
|
||||||
|
if(d.barcode=="" || d.barcode==null) {
|
||||||
|
// barcode cleared, remove item
|
||||||
|
d.item_code = "";
|
||||||
|
}
|
||||||
|
this.item_code(doc, cdt, cdn);
|
||||||
|
},
|
||||||
|
|
||||||
item_code: function(doc, cdt, cdn) {
|
item_code: function(doc, cdt, cdn) {
|
||||||
var me = this;
|
var me = this;
|
||||||
var item = frappe.get_doc(cdt, cdn);
|
var item = frappe.get_doc(cdt, cdn);
|
||||||
|
|||||||
@@ -81,7 +81,8 @@ erpnext.feature_setup.feature_dict = {
|
|||||||
'Item': {'fields': ['barcode']},
|
'Item': {'fields': ['barcode']},
|
||||||
'Delivery Note': {'items': ['barcode']},
|
'Delivery Note': {'items': ['barcode']},
|
||||||
'Sales Invoice': {'items': ['barcode']},
|
'Sales Invoice': {'items': ['barcode']},
|
||||||
'Stock Entry': {'items': ['barcode']}
|
'Stock Entry': {'items': ['barcode']},
|
||||||
|
'Purchase Receipt': {'items': ['barcode']}
|
||||||
},
|
},
|
||||||
'fs_item_group_in_details': {
|
'fs_item_group_in_details': {
|
||||||
'Delivery Note': {'items':['item_group']},
|
'Delivery Note': {'items':['item_group']},
|
||||||
|
|||||||
@@ -124,15 +124,6 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
|||||||
this.apply_pricing_rule();
|
this.apply_pricing_rule();
|
||||||
},
|
},
|
||||||
|
|
||||||
barcode: function(doc, cdt, cdn) {
|
|
||||||
var d = locals[cdt][cdn];
|
|
||||||
if(d.barcode=="" || d.barcode==null) {
|
|
||||||
// barcode cleared, remove item
|
|
||||||
d.item_code = "";
|
|
||||||
}
|
|
||||||
this.item_code(doc, cdt, cdn);
|
|
||||||
},
|
|
||||||
|
|
||||||
selling_price_list: function() {
|
selling_price_list: function() {
|
||||||
this.apply_price_list();
|
this.apply_price_list();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -221,7 +221,7 @@
|
|||||||
"icon": "icon-ticket",
|
"icon": "icon-ticket",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2015-05-27 15:36:06.818491",
|
"modified": "2015-06-09 05:47:05.934432",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Material Request",
|
"name": "Material Request",
|
||||||
|
|||||||
@@ -6,7 +6,13 @@ frappe.listview_settings['Material Request'] = {
|
|||||||
} else if(doc.docstatus==1 && flt(doc.per_ordered) < 100) {
|
} else if(doc.docstatus==1 && flt(doc.per_ordered) < 100) {
|
||||||
return [__("Pending"), "orange", "per_ordered,<,100"];
|
return [__("Pending"), "orange", "per_ordered,<,100"];
|
||||||
} else if(doc.docstatus==1 && flt(doc.per_ordered) == 100) {
|
} else if(doc.docstatus==1 && flt(doc.per_ordered) == 100) {
|
||||||
return [__("Ordered"), "green", "per_ordered,=,100"];
|
if (doc.material_request_type == "Purchase") {
|
||||||
|
return [__("Ordered"), "green", "per_ordered,=,100"];
|
||||||
|
} else if (doc.material_request_type == "Material Transfer") {
|
||||||
|
return [__("Transfered"), "green", "per_ordered,=,100"];
|
||||||
|
} else if (doc.material_request_type == "Material Issue") {
|
||||||
|
return [__("Issued"), "green", "per_ordered,=,100"];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -4,6 +4,19 @@
|
|||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"fields": [
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "barcode",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Barcode",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "section_break_2",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "item_code",
|
"fieldname": "item_code",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
@@ -642,7 +655,7 @@
|
|||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2015-06-02 14:19:13.528248",
|
"modified": "2015-06-08 08:21:18.024324",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Purchase Receipt Item",
|
"name": "Purchase Receipt Item",
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -1,6 +1,6 @@
|
|||||||
from setuptools import setup, find_packages
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
version = "5.0.19"
|
version = "5.0.20"
|
||||||
|
|
||||||
with open("requirements.txt", "r") as f:
|
with open("requirements.txt", "r") as f:
|
||||||
install_requires = f.readlines()
|
install_requires = f.readlines()
|
||||||
|
|||||||
Reference in New Issue
Block a user