Merge pull request #3725 from neilLasrado/test
Fixed test cases related to Time Logs
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 6d54f0a..2e64f99 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -5,10 +5,8 @@
import frappe
import unittest, copy
from frappe.utils import nowdate, add_days, flt
-from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
-from erpnext.projects.doctype.time_log_batch.test_time_log_batch import *
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction
-
+from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
class TestSalesInvoice(unittest.TestCase):
def make(self):
@@ -402,32 +400,6 @@
jv.cancel()
self.assertEquals(frappe.db.get_value("Sales Invoice", w.name, "outstanding_amount"), 561.8)
- def test_time_log_batch(self):
- delete_time_log_and_batch()
- time_log = create_time_log()
- tlb = create_time_log_batch(time_log)
-
- tlb = frappe.get_doc("Time Log Batch", tlb.name)
- tlb.submit()
-
- si = frappe.get_doc(frappe.copy_doc(test_records[0]))
- si.get("items")[0].time_log_batch = tlb.name
- si.insert()
- si.submit()
-
- self.assertEquals(frappe.db.get_value("Time Log Batch", tlb.name, "status"), "Billed")
-
- self.assertEquals(frappe.db.get_value("Time Log", time_log, "status"), "Billed")
-
- si.cancel()
-
- self.assertEquals(frappe.db.get_value("Time Log Batch", tlb.name, "status"), "Submitted")
-
- self.assertEquals(frappe.db.get_value("Time Log", time_log, "status"), "Batched for Billing")
-
- frappe.delete_doc("Sales Invoice", si.name)
- delete_time_log_and_batch()
-
def test_sales_invoice_gl_entry_without_aii(self):
set_perpetual_inventory(0)
si = frappe.copy_doc(test_records[1])
diff --git a/erpnext/manufacturing/doctype/production_order/test_production_order.py b/erpnext/manufacturing/doctype/production_order/test_production_order.py
index ddcc8c7..4d65337 100644
--- a/erpnext/manufacturing/doctype/production_order/test_production_order.py
+++ b/erpnext/manufacturing/doctype/production_order/test_production_order.py
@@ -5,10 +5,10 @@
from __future__ import unicode_literals
import unittest
import frappe
-from frappe.utils import flt, get_datetime, time_diff_in_hours
+from frappe.utils import flt, time_diff_in_hours, now, add_days
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
from erpnext.manufacturing.doctype.production_order.production_order \
- import make_stock_entry, make_time_log, ProductionNotApplicableError,ItemHasVariantError
+ import make_stock_entry, ProductionNotApplicableError,ItemHasVariantError
from erpnext.stock.doctype.stock_entry import test_stock_entry
from erpnext.projects.doctype.time_log.time_log import OverProductionLoggedError
@@ -68,8 +68,9 @@
self.assertRaises(StockOverProductionError, s.submit)
def test_make_time_log(self):
+ from erpnext.projects.doctype.time_log.test_time_log import make_time_log_test_record
prod_order = make_prod_order_test_record(item="_Test FG Item 2",
- planned_start_date="2014-11-25 00:00:00", qty=1, do_not_save=True)
+ planned_start_date=now(), qty=1, do_not_save=True)
prod_order.set_production_order_operations()
prod_order.insert()
@@ -79,17 +80,13 @@
d.completed_qty = flt(d.completed_qty)
- time_log = make_time_log(prod_order.name, d.operation, \
- d.planned_start_time, d.planned_end_time, prod_order.qty - d.completed_qty,
- operation_id=d.name)
+ time_log = make_time_log_test_record(hours=1, production_order= prod_order.name, operation= d.operation,
+ completed_qty= prod_order.qty - d.completed_qty, operation_id=d.name, for_manufacturing=1, simulate=True)
self.assertEqual(prod_order.name, time_log.production_order)
self.assertEqual((prod_order.qty - d.completed_qty), time_log.completed_qty)
self.assertEqual(time_diff_in_hours(d.planned_end_time, d.planned_start_time),time_log.hours)
-
- time_log.save()
- time_log.submit()
-
+
manufacturing_settings = frappe.get_doc({
"doctype": "Manufacturing Settings",
"allow_production_on_holidays": 0
@@ -101,11 +98,6 @@
self.assertEqual(prod_order.operations[0].status, "Completed")
self.assertEqual(prod_order.operations[0].completed_qty, prod_order.qty)
- self.assertEqual(get_datetime(prod_order.operations[0].actual_start_time),
- get_datetime(time_log.from_time))
- self.assertEqual(get_datetime(prod_order.operations[0].actual_end_time),
- get_datetime(time_log.to_time))
-
self.assertEqual(prod_order.operations[0].actual_operation_time, 60)
self.assertEqual(prod_order.operations[0].actual_operating_cost, 100)
@@ -118,18 +110,14 @@
self.assertEqual(flt(prod_order.operations[0].actual_operation_time), 0)
self.assertEqual(flt(prod_order.operations[0].actual_operating_cost), 0)
- time_log2 = frappe.copy_doc(time_log)
- time_log2.update({
- "completed_qty": 10,
- "from_time": "2014-11-26 00:00:00",
- "to_time": "2014-11-26 00:00:00",
- "docstatus": 0
- })
+ time_log2 = make_time_log_test_record(from_time= add_days(time_log.to_time, 1) ,production_order= prod_order.name, operation= d.operation,
+ completed_qty= 5, operation_id=d.name, for_manufacturing=1, do_not_save=True)
+
self.assertRaises(OverProductionLoggedError, time_log2.save)
def test_planned_operating_cost(self):
prod_order = make_prod_order_test_record(item="_Test FG Item 2",
- planned_start_date="2014-11-25 00:00:00", qty=1, do_not_save=True)
+ planned_start_date=now(), qty=1, do_not_save=True)
prod_order.set_production_order_operations()
cost = prod_order.planned_operating_cost
prod_order.qty = 2
diff --git a/erpnext/projects/doctype/activity_cost/test_activity_cost.py b/erpnext/projects/doctype/activity_cost/test_activity_cost.py
index 5afd97f..58c3f21 100644
--- a/erpnext/projects/doctype/activity_cost/test_activity_cost.py
+++ b/erpnext/projects/doctype/activity_cost/test_activity_cost.py
@@ -15,10 +15,11 @@
activity_cost1.update({
"employee": "_T-Employee-0001",
"employee_name": "_Test Employee",
- "activity_type": "_Test Activity Type",
+ "activity_type": "_Test Activity Type 1",
"billing_rate": 100,
"costing_rate": 50
})
activity_cost1.insert()
activity_cost2 = frappe.copy_doc(activity_cost1)
self.assertRaises(DuplicationError, activity_cost2.insert )
+ frappe.db.sql("delete from `tabActivity Cost`")
\ No newline at end of file
diff --git a/erpnext/projects/doctype/time_log/test_records.json b/erpnext/projects/doctype/time_log/test_records.json
index 568c012..0637a08 100644
--- a/erpnext/projects/doctype/time_log/test_records.json
+++ b/erpnext/projects/doctype/time_log/test_records.json
@@ -1,10 +1 @@
-[
- {
- "activity_type": "_Test Activity Type",
- "docstatus": 1,
- "doctype": "Time Log",
- "from_time": "2013-01-01 10:00:00.000000",
- "note": "_Test Note",
- "to_time": "2013-01-01 11:00:00.000000"
- }
-]
+[]
\ No newline at end of file
diff --git a/erpnext/projects/doctype/time_log/test_time_log.py b/erpnext/projects/doctype/time_log/test_time_log.py
index 9b43b0d..9bdf588 100644
--- a/erpnext/projects/doctype/time_log/test_time_log.py
+++ b/erpnext/projects/doctype/time_log/test_time_log.py
@@ -5,63 +5,44 @@
import frappe
import unittest
-from erpnext.projects.doctype.time_log.time_log import OverlapError
-from erpnext.projects.doctype.time_log.time_log import NotSubmittedError
-from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError
-from erpnext.manufacturing.doctype.workstation.workstation import NotInWorkingHoursError
+import datetime
+from frappe.utils import now_datetime, now
+from erpnext.projects.doctype.time_log.time_log import OverlapError, NotSubmittedError, NegativeHoursError
+from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError, NotInWorkingHoursError
from erpnext.manufacturing.doctype.production_order.test_production_order import make_prod_order_test_record
class TestTimeLog(unittest.TestCase):
def test_duplication(self):
- frappe.db.sql("delete from `tabTime Log`")
+ tl1 = make_time_log_test_record(user= "test@example.com", employee= "_T-Employee-0002", simulate= True)
- tl1 = frappe.get_doc(frappe.copy_doc(test_records[0]))
- tl1.user = "test@example.com"
- tl1.insert()
-
- tl2 = frappe.get_doc(frappe.copy_doc(test_records[0]))
- tl2.user = "test@example.com"
+ tl2 = make_time_log_test_record(user= "test@example.com", employee= "_T-Employee-0002",
+ from_time= tl1.from_time, to_time= tl1.to_time, do_not_save= 1)
self.assertRaises(OverlapError, tl2.insert)
- frappe.db.sql("delete from `tabTime Log`")
-
def test_production_order_status(self):
- prod_order = make_prod_order_test_record(item="_Test FG Item 2", qty=1, do_not_submit=True)
+ prod_order = make_prod_order_test_record(item= "_Test FG Item 2", qty= 1, do_not_submit= True)
prod_order.set_production_order_operations()
prod_order.save()
- time_log = frappe.get_doc({
- "doctype": "Time Log",
- "for_manufacturing": 1,
- "production_order": prod_order.name,
- "qty": 1,
- "from_time": "2014-12-26 00:00:00",
- "to_time": "2014-12-26 00:00:00"
- })
+ time_log = make_time_log_test_record(for_manufacturing= 1, production_order= prod_order.name, qty= 1,
+ employee= "_T-Employee-0003", do_not_save= True, simulate=1)
self.assertRaises(NotSubmittedError, time_log.save)
def test_time_log_on_holiday(self):
- prod_order = make_prod_order_test_record(item="_Test FG Item 2", qty=1,
- planned_start_date="2014-11-25 00:00:00", do_not_save=True)
+ prod_order = make_prod_order_test_record(item= "_Test FG Item 2", qty= 1,
+ planned_start_date= now(), do_not_save= True)
prod_order.set_production_order_operations()
prod_order.save()
prod_order.submit()
- time_log = frappe.get_doc({
- "doctype": "Time Log",
- "for_manufacturing": 1,
- "production_order": prod_order.name,
- "operation": prod_order.operations[0].operation,
- "operation_id": prod_order.operations[0].name,
- "qty": 1,
- "activity_type": "_Test Activity Type",
- "from_time": "2013-02-01 10:00:00",
- "to_time": "2013-02-01 20:00:00",
- "workstation": "_Test Workstation 1"
- })
+ time_log = make_time_log_test_record(from_time= "2013-02-01 10:00:00", to_time= "2013-02-01 20:00:00",
+ for_manufacturing= 1, production_order= prod_order.name, qty= 1,
+ operation= prod_order.operations[0].operation, operation_id= prod_order.operations[0].name,
+ workstation= "_Test Workstation 1", do_not_save= True)
+
self.assertRaises(WorkstationHolidayError , time_log.save)
time_log.update({
@@ -76,28 +57,23 @@
time_log.cancel()
def test_negative_hours(self):
- frappe.db.sql("delete from `tabTime Log`")
- test_time_log = frappe.new_doc("Time Log")
- test_time_log.activity_type = "Communication"
- test_time_log.from_time = "2013-01-01 11:00:00.000000"
- test_time_log.to_time = "2013-01-01 10:00:00.000000"
- self.assertRaises(frappe.ValidationError, test_time_log.save)
- frappe.db.sql("delete from `tabTime Log`")
-
+ time_log = make_time_log_test_record(to_time= now_datetime() + datetime.timedelta(minutes=-1),
+ employee="_T-Employee-0006",do_not_save= True)
+ self.assertRaises(NegativeHoursError, time_log.save)
+
def test_total_activity_cost_for_project(self):
frappe.db.sql("""delete from `tabTask` where project = "_Test Project 1" """)
frappe.db.sql("""delete from `tabProject` where name = "_Test Project 1" """)
- frappe.db.sql("""delete from `tabActivity Cost` where employee = "_T-Employee-0001" and activity_type = "_Test Activity Type" """)
- activity_cost = frappe.new_doc('Activity Cost')
- activity_cost.update({
- "employee": "_T-Employee-0001",
- "employee_name": "_Test Employee",
- "activity_type": "_Test Activity Type",
- "billing_rate": 100,
- "costing_rate": 50
- })
- activity_cost.insert()
+ if not frappe.db.exists('Activity Cost', {"activity_type": "_Test Activity Type"}):
+ activity_cost = frappe.get_doc({
+ "doctype": "Activity Cost",
+ "employee": "",
+ "activity_type": "_Test Activity Type",
+ "billing_rate": 100,
+ "costing_rate": 50
+ })
+ activity_cost.insert()
frappe.get_doc({
"project_name": "_Test Project 1",
@@ -108,40 +84,16 @@
task_name = frappe.db.get_value("Task",{"project": "_Test Project 1"})
- time_log = frappe.get_doc({
- "activity_type": "_Test Activity Type",
- "docstatus": 1,
- "doctype": "Time Log",
- "from_time": "2013-02-02 09:00:00.000000",
- "to_time": "2013-02-02 11:00:00.000000",
- "employee": "_T-Employee-0001",
- "project": "_Test Project 1",
- "task": task_name,
- "billable": 1
- })
- time_log.save()
+ time_log = make_time_log_test_record(employee="_T-Employee-0002", hours=2, task= task_name)
self.assertEqual(time_log.costing_rate, 50)
self.assertEqual(time_log.costing_amount, 100)
self.assertEqual(time_log.billing_rate, 100)
self.assertEqual(time_log.billing_amount, 200)
- time_log.submit()
self.assertEqual(frappe.db.get_value("Task", task_name, "total_billing_amount"), 200)
self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_billing_amount"), 200)
- time_log2 = frappe.get_doc({
- "activity_type": "_Test Activity Type",
- "docstatus": 1,
- "doctype": "Time Log",
- "from_time": "2013-02-03 09:00:00.000000",
- "to_time": "2013-02-03 11:00:00.000000",
- "employee": "_T-Employee-0001",
- "project": "_Test Project 1",
- "task": task_name,
- "billable": 1
- })
- time_log2.save()
-
+ time_log2 = make_time_log_test_record(employee="_T-Employee-0003", hours=2, task= task_name)
self.assertEqual(frappe.db.get_value("Task", task_name, "total_billing_amount"), 400)
self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_billing_amount"), 400)
@@ -149,6 +101,44 @@
self.assertEqual(frappe.db.get_value("Task", task_name, "total_billing_amount"), 200)
self.assertEqual(frappe.db.get_value("Project", "_Test Project 1", "total_billing_amount"), 200)
+ time_log.cancel()
-test_records = frappe.get_test_records('Time Log')
test_ignore = ["Time Log Batch", "Sales Invoice"]
+
+def make_time_log_test_record(**args):
+ args = frappe._dict(args)
+
+ time_log = frappe.new_doc("Time Log")
+
+ time_log.from_time = args.from_time or now_datetime()
+ time_log.hours = args.hours or 1
+ time_log.to_time = args.to_time or time_log.from_time + datetime.timedelta(hours= time_log.hours)
+
+ time_log.project = args.project
+ time_log.task = args.task
+ time_log.for_manufacturing = args.for_manufacturing
+ time_log.production_order = args.production_order
+ time_log.operation = args.operation
+ time_log.operation_id = args.operation_id
+ time_log.workstation = args.workstation
+ time_log.completed_qty = args.completed_qty
+ time_log.activity_type = args.activity_type or "_Test Activity Type"
+ time_log.billable = args.billable or 1
+ time_log.employee = args.employee
+ time_log.user = args.user
+
+ if not args.do_not_save:
+ if args.simulate:
+ while True:
+ try:
+ time_log.save()
+ break
+ except OverlapError:
+ time_log.from_time = time_log.from_time + datetime.timedelta(minutes=10)
+ time_log.to_time = time_log.from_time + datetime.timedelta(hours= time_log.hours)
+ else:
+ time_log.save()
+ if not args.do_not_submit:
+ time_log.submit()
+
+ return time_log
\ No newline at end of file
diff --git a/erpnext/projects/doctype/time_log/time_log.py b/erpnext/projects/doctype/time_log/time_log.py
index 136362b..0f50e9c 100644
--- a/erpnext/projects/doctype/time_log/time_log.py
+++ b/erpnext/projects/doctype/time_log/time_log.py
@@ -10,6 +10,7 @@
class OverlapError(frappe.ValidationError): pass
class OverProductionLoggedError(frappe.ValidationError): pass
class NotSubmittedError(frappe.ValidationError): pass
+class NegativeHoursError(frappe.ValidationError): pass
from frappe.model.document import Document
@@ -101,8 +102,8 @@
return existing[0] if existing else None
def validate_timings(self):
- if self.to_time and self.from_time and get_datetime(self.to_time) < get_datetime(self.from_time):
- frappe.throw(_("From Time cannot be greater than To Time"))
+ if self.to_time and self.from_time and get_datetime(self.to_time) <= get_datetime(self.from_time):
+ frappe.throw(_("To Time must be greater than From Time"), NegativeHoursError)
def calculate_total_hours(self):
if self.to_time and self.from_time:
diff --git a/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py b/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py
index faa0a60..9f3591d 100644
--- a/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py
+++ b/erpnext/projects/doctype/time_log_batch/test_time_log_batch.py
@@ -3,43 +3,19 @@
from __future__ import unicode_literals
import frappe, unittest
+from erpnext.projects.doctype.time_log.test_time_log import make_time_log_test_record
class TimeLogBatchTest(unittest.TestCase):
def test_time_log_status(self):
- delete_time_log_and_batch()
- time_log = create_time_log()
+ time_log = make_time_log_test_record(simulate=True)
- self.assertEquals(frappe.db.get_value("Time Log", time_log, "status"), "Submitted")
+ self.assertEquals(frappe.db.get_value("Time Log", time_log.name, "status"), "Submitted")
- tlb = create_time_log_batch(time_log)
+ tlb = create_time_log_batch(time_log.name)
- self.assertEquals(frappe.db.get_value("Time Log", time_log, "status"), "Batched for Billing")
+ self.assertEquals(frappe.db.get_value("Time Log", time_log.name, "status"), "Batched for Billing")
tlb.cancel()
- self.assertEquals(frappe.db.get_value("Time Log", time_log, "status"), "Submitted")
-
- delete_time_log_and_batch()
-
-def delete_time_log_and_batch():
- for name in frappe.db.sql_list("select name from `tabTime Log Batch` where docstatus=1"):
- frappe.get_doc("Time Log Batch", name).cancel()
- frappe.delete_doc("Time Log Batch", name)
-
- for name in frappe.db.sql_list("select name from `tabTime Log` where docstatus=1"):
- frappe.get_doc("Time Log", name).cancel()
- frappe.delete_doc("Time Log", name)
-
-def create_time_log():
- from erpnext.projects.doctype.time_log.test_time_log import test_records as time_log_records
- time_log = frappe.copy_doc(time_log_records[0])
- time_log.update({
- "from_time": "2013-01-02 10:00:00.000000",
- "to_time": "2013-01-02 11:00:00.000000",
- "docstatus": 0,
- "for_manufacturing": 0
- })
- time_log.insert()
- time_log.submit()
- return time_log.name
+ self.assertEquals(frappe.db.get_value("Time Log", time_log.name, "status"), "Submitted")
def create_time_log_batch(time_log):
tlb = frappe.get_doc({