Browse Source

Rename Time Sheet doctype

develop
Rohit Waghchaure 8 years ago
parent
commit
e94d18b4cd
  1. 6
      erpnext/accounts/doctype/sales_invoice/sales_invoice.py
  2. 4
      erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.json
  3. 10
      erpnext/config/projects.py
  4. 2
      erpnext/hr/doctype/employee/employee_links.py
  5. 14
      erpnext/hr/doctype/salary_slip/salary_slip.py
  6. 4
      erpnext/hr/doctype/salary_slip_timesheet/salary_slip_timesheet.json
  7. 6
      erpnext/manufacturing/doctype/production_order/production_order.js
  8. 69
      erpnext/manufacturing/doctype/production_order/production_order.py
  9. 4
      erpnext/manufacturing/doctype/production_order/test_production_order.py
  10. 1
      erpnext/patches.txt
  11. 2
      erpnext/patches/v7_0/convert_timelogbatch_to_timesheet.py
  12. 2
      erpnext/patches/v7_0/move_timelogbatch_from_salesinvoiceitem_to_salesinvoicetimesheet.py
  13. 13
      erpnext/patches/v7_0/rename_time_sheet_doctype.py
  14. 8
      erpnext/patches/v7_0/set_naming_series_for_timesheet.py
  15. 6
      erpnext/projects/doctype/project/project.py
  16. 2
      erpnext/projects/doctype/project/project_links.py
  17. 2
      erpnext/projects/doctype/task/task.py
  18. 0
      erpnext/projects/doctype/timesheet/__init__.py
  19. 68
      erpnext/projects/doctype/timesheet/test_timesheet.py
  20. 12
      erpnext/projects/doctype/timesheet/timesheet.js
  21. 8
      erpnext/projects/doctype/timesheet/timesheet.json
  22. 24
      erpnext/projects/doctype/timesheet/timesheet.py
  23. 2
      erpnext/projects/doctype/timesheet/timesheet_list.js
  24. 0
      erpnext/projects/doctype/timesheet_detail/__init__.py
  25. 4
      erpnext/projects/doctype/timesheet_detail/timesheet_detail.json
  26. 2
      erpnext/projects/doctype/timesheet_detail/timesheet_detail.py
  27. 6
      erpnext/projects/report/daily_time_sheet_summary/daily_time_sheet_summary.py
  28. 0
      erpnext/projects/report/daily_timesheet_summary/__init__.py
  29. 19
      erpnext/projects/report/daily_timesheet_summary/daily_timesheet_summary.js
  30. 18
      erpnext/projects/report/daily_timesheet_summary/daily_timesheet_summary.json
  31. 34
      erpnext/projects/report/daily_timesheet_summary/daily_timesheet_summary.py
  32. 2
      erpnext/setup/doctype/company/delete_company_transactions.py
  33. 2
      erpnext/setup/setup_wizard/domainify.py
  34. 2
      erpnext/startup/notifications.py

6
erpnext/accounts/doctype/sales_invoice/sales_invoice.py

@ -238,7 +238,7 @@ class SalesInvoice(SellingController):
def update_time_sheet(self, sales_invoice):
for d in self.timesheets:
if d.time_sheet:
timesheet = frappe.get_doc("Time Sheet", d.time_sheet)
timesheet = frappe.get_doc("Timesheet", d.time_sheet)
timesheet.sales_invoice = sales_invoice
timesheet.flags.ignore_validate_update_after_submit = True
timesheet.set_status()
@ -247,9 +247,9 @@ class SalesInvoice(SellingController):
def validate_time_sheets_are_submitted(self):
for data in self.timesheets:
if data.time_sheet:
status = frappe.db.get_value("Time Sheet", data.time_sheet, "status")
status = frappe.db.get_value("Timesheet", data.time_sheet, "status")
if status not in ['Submitted', 'Payslip']:
frappe.throw(_("Time Sheet {0} is already completed or cancelled").format(data.time_sheet))
frappe.throw(_("Timesheet {0} is already completed or cancelled").format(data.time_sheet))
def set_pos_fields(self, for_validate=False):
"""Set retail related fields from POS Profiles"""

4
erpnext/accounts/doctype/sales_invoice_timesheet/sales_invoice_timesheet.json

@ -23,7 +23,7 @@
"label": "Time Sheet",
"length": 0,
"no_copy": 0,
"options": "Time Sheet",
"options": "Timesheet",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -71,7 +71,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-06-15 23:56:06.131202",
"modified": "2016-07-06 18:35:46.072695",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Timesheet",

10
erpnext/config/projects.py

@ -31,13 +31,13 @@ def get_data():
"items": [
{
"type": "doctype",
"name": "Time Sheet",
"description": _("Time Sheet for tasks."),
"name": "Timesheet",
"description": _("Timesheet for tasks."),
},
{
"type": "doctype",
"name": "Activity Type",
"description": _("Types of activities for Time Sheets"),
"description": _("Types of activities for Time Logs"),
},
{
"type": "doctype",
@ -53,8 +53,8 @@ def get_data():
{
"type": "report",
"is_query_report": True,
"name": "Daily Time Sheet Summary",
"doctype": "Time Sheet"
"name": "Daily Timesheet Summary",
"doctype": "Timesheet"
},
{
"type": "report",

2
erpnext/hr/doctype/employee/employee_links.py

@ -9,7 +9,7 @@ links = {
},
{
'label': _('Payroll'),
'items': ['Salary Structure', 'Salary Slip', 'Time Sheet']
'items': ['Salary Structure', 'Salary Slip', 'Timesheet']
},
{
'label': _('Expense'),

14
erpnext/hr/doctype/salary_slip/salary_slip.py

@ -64,7 +64,7 @@ class SalarySlip(TransactionBase):
if self.salary_slip_based_on_timesheet and not self.get('timesheets'):
self.set("timesheets", [])
timesheets = frappe.db.sql(""" select * from `tabTime Sheet` where employee = %(employee)s and (status = 'Submitted' or
timesheets = frappe.db.sql(""" select * from `tabTimesheet` where employee = %(employee)s and (status = 'Submitted' or
status = 'Billed')""", {'employee': self.employee}, as_dict=1)
for data in timesheets:
@ -220,16 +220,16 @@ class SalarySlip(TransactionBase):
frappe.throw(_("Salary Slip of employee {0} already created for this period").format(self.employee))
else:
for data in self.timesheets:
if frappe.db.get_value('Time Sheet', data.time_sheet, 'status') == 'Payrolled':
if frappe.db.get_value('Timesheet', data.time_sheet, 'status') == 'Payrolled':
frappe.throw(_("Salary Slip of employee {0} already created for time sheet {1}").format(self.employee, data.time_sheet))
def calculate_earning_total(self):
self.gross_pay = flt(self.arrear_amount) + flt(self.leave_encashment_amount)
for d in self.get("earnings"):
if cint(d.depends_on_lwp) == 1:
if cint(d.depends_on_lwp) == 1 and not self.salary_slip_based_on_timesheet:
d.amount = rounded((flt(d.default_amount) * flt(self.payment_days)
/ cint(self.total_days_in_month)), self.precision("amount", "earnings"))
elif not self.payment_days:
elif not self.payment_days and not self.salary_slip_based_on_timesheet:
d.amount = 0
elif not d.amount:
d.amount = d.default_amount
@ -238,10 +238,10 @@ class SalarySlip(TransactionBase):
def calculate_ded_total(self):
self.total_deduction = 0
for d in self.get('deductions'):
if cint(d.depends_on_lwp) == 1:
if cint(d.depends_on_lwp) == 1 and not self.salary_slip_based_on_timesheet:
d.amount = rounded((flt(d.amount) * flt(self.payment_days)
/ cint(self.total_days_in_month)), self.precision("amount", "deductions"))
elif not self.payment_days:
elif not self.payment_days and not self.salary_slip_based_on_timesheet:
d.amount = 0
elif not d.amount:
d.amount = d.default_amount
@ -277,7 +277,7 @@ class SalarySlip(TransactionBase):
def update_status(self, salary_slip=None):
for data in self.timesheets:
if data.time_sheet:
timesheet = frappe.get_doc('Time Sheet', data.time_sheet)
timesheet = frappe.get_doc('Timesheet', data.time_sheet)
timesheet.salary_slip = salary_slip
timesheet.flags.ignore_validate_update_after_submit = True
timesheet.set_status()

4
erpnext/hr/doctype/salary_slip_timesheet/salary_slip_timesheet.json

@ -23,7 +23,7 @@
"label": "Time Sheet",
"length": 0,
"no_copy": 0,
"options": "Time Sheet",
"options": "Timesheet",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -71,7 +71,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-06-15 17:59:57.876373",
"modified": "2016-07-06 18:35:46.156411",
"modified_by": "Administrator",
"module": "HR",
"name": "Salary Slip Timesheet",

6
erpnext/manufacturing/doctype/production_order/production_order.js

@ -41,7 +41,7 @@ frappe.ui.form.on("Production Order", {
if(frm.doc.docstatus == 1){
frm.add_custom_button(__('Make Timesheet'), function(){
frappe.model.open_mapped_doc({
method: "erpnext.manufacturing.doctype.production_order.production_order.make_timesheet",
method: "erpnext.manufacturing.doctype.production_order.production_order.make_new_timesheet",
frm: cur_frm
})
})
@ -125,9 +125,9 @@ erpnext.production_order = {
// opertions
if ((doc.operations || []).length) {
frm.add_custom_button(__('Time Sheet'), function() {
frm.add_custom_button(__('Timesheet'), function() {
frappe.route_options = {"production_order": frm.doc.name};
frappe.set_route("List", "Time Sheet");
frappe.set_route("List", "Timesheet");
}, __("View"));
}

69
erpnext/manufacturing/doctype/production_order/production_order.py

@ -13,7 +13,7 @@ from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
from dateutil.relativedelta import relativedelta
from erpnext.stock.doctype.item.item import validate_end_of_life
from erpnext.manufacturing.doctype.workstation.workstation import WorkstationHolidayError, NotInWorkingHoursError
from erpnext.projects.doctype.time_sheet.time_sheet import OverlapError
from erpnext.projects.doctype.timesheet.timesheet import OverlapError
from erpnext.stock.doctype.stock_entry.stock_entry import get_additional_costs
from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings import get_mins_between_operations
from erpnext.stock.stock_balance import get_planned_qty, update_bin_qty
@ -162,10 +162,6 @@ class ProductionOrder(Document):
self.set_required_items()
self.make_time_logs()
def before_cancel(self):
for data in self.operations:
data.time_sheet = None
def on_submit(self):
if not self.wip_warehouse:
frappe.throw(_("Work-in-Progress Warehouse is required before Submit"))
@ -181,7 +177,7 @@ class ProductionOrder(Document):
frappe.db.set(self,'status', 'Cancelled')
self.clear_required_items()
self.delete_time_sheet()
self.delete_timesheet()
self.update_completed_qty_in_material_request()
self.update_planned_qty()
@ -248,10 +244,10 @@ class ProductionOrder(Document):
if not self.operations:
return
time_sheets = []
timesheets = []
plan_days = frappe.db.get_single_value("Manufacturing Settings", "capacity_planning_for_days") or 30
time_sheet = make_time_sheet(self.name)
timesheet = make_timesheet(self.name)
workstation_list = []
last_workstation_idx = {}
@ -261,18 +257,18 @@ class ProductionOrder(Document):
self.set_start_end_time_for_workstation(d, workstation_list, last_workstation_idx.get(d.workstation))
args = self.get_operations_data(d)
add_timesheet_detail(time_sheet, args)
add_timesheet_detail(timesheet, args)
original_start_time = d.planned_start_time
# validate operating hours if workstation [not mandatory] is specified
self.check_operation_fits_in_working_hours(d)
try:
time_sheet.validate_time_logs()
timesheet.validate_time_logs()
except OverlapError:
if frappe.message_log: frappe.message_log.pop()
time_sheet.move_to_next_non_overlapping_slot(d.idx)
timesheet.move_to_next_non_overlapping_slot(d.idx)
from_time, to_time = self.get_start_end_time(time_sheet, d.name)
from_time, to_time = self.get_start_end_time(timesheet, d.name)
if date_diff(from_time, original_start_time) > plan_days:
frappe.throw(_("Unable to find Time Slot in the next {0} days for Operation {1}").format(plan_days, d.operation))
@ -282,17 +278,17 @@ class ProductionOrder(Document):
d.planned_end_time = to_time
d.db_update()
if time_sheet and open_new:
return time_sheet
if timesheet and open_new:
return timesheet
if time_sheet:
time_sheet.save()
time_sheets.append(time_sheet.name)
if timesheet:
timesheet.save()
timesheets.append(timesheet.name)
self.planned_end_date = self.operations[-1].planned_end_time
if time_sheets:
if timesheets:
frappe.local.message_log = []
frappe.msgprint(_("Time Sheet created:") + "\n" + "\n".join(time_sheets))
frappe.msgprint(_("Timesheet created:") + "\n" + "\n".join(timesheets))
def get_operations_data(self, data):
return {
@ -322,8 +318,8 @@ class ProductionOrder(Document):
if data.planned_start_time == data.planned_end_time:
frappe.throw(_("Capacity Planning Error"))
def get_start_end_time(self, time_sheet, operation_id):
for data in time_sheet.time_logs:
def get_start_end_time(self, timesheet, operation_id):
for data in timesheet.time_logs:
if data.operation_id == operation_id:
return data.from_time, data.to_time
@ -354,9 +350,9 @@ class ProductionOrder(Document):
self.actual_start_date = None
self.actual_end_date = None
def delete_time_sheet(self):
for time_sheet in frappe.get_all("Time Sheet", ["name"], {"production_order": self.name}):
frappe.delete_doc("Time Sheet", time_sheet.name)
def delete_timesheet(self):
for timesheet in frappe.get_all("Timesheet", ["name"], {"production_order": self.name}):
frappe.delete_doc("Timesheet", timesheet.name)
def validate_production_item(self):
if frappe.db.get_value("Item", self.production_item, "has_variants"):
@ -508,22 +504,22 @@ def get_events(start, end, filters=None):
return data
@frappe.whitelist()
def make_time_sheet(production_order):
time_sheet = frappe.new_doc("Time Sheet")
time_sheet.employee = ""
time_sheet.production_order = production_order
return time_sheet
def make_timesheet(production_order):
timesheet = frappe.new_doc("Timesheet")
timesheet.employee = ""
timesheet.production_order = production_order
return timesheet
@frappe.whitelist()
def add_timesheet_detail(time_sheet, args):
if isinstance(time_sheet, unicode):
time_sheet = frappe.get_doc('Time Sheet', time_sheet)
def add_timesheet_detail(timesheet, args):
if isinstance(timesheet, unicode):
timesheet = frappe.get_doc('Timesheet', timesheet)
if isinstance(args, unicode):
args = json.loads(args)
time_sheet.append('time_logs', args)
return time_sheet
timesheet.append('time_logs', args)
return timesheet
@frappe.whitelist()
def get_default_warehouse():
@ -534,8 +530,11 @@ def get_default_warehouse():
return {"wip_warehouse": wip_warehouse, "fg_warehouse": fg_warehouse}
@frappe.whitelist()
def make_timesheet(source_name, target_doc=None):
def make_new_timesheet(source_name, target_doc=None):
po = frappe.get_doc('Production Order', source_name)
ts = po.make_time_logs(open_new=True)
if not ts.get('time_logs'):
frappe.throw(_("Already completed"))
return ts

4
erpnext/manufacturing/doctype/production_order/test_production_order.py

@ -83,8 +83,8 @@ class TestProductionOrder(unittest.TestCase):
d = prod_order.operations[0]
d.completed_qty = flt(d.completed_qty)
name = frappe.db.get_value('Time Sheet', {'production_order': prod_order.name}, 'name')
time_sheet_doc = frappe.get_doc('Time Sheet', name)
name = frappe.db.get_value('Timesheet', {'production_order': prod_order.name}, 'name')
time_sheet_doc = frappe.get_doc('Timesheet', name)
time_sheet_doc.submit()

1
erpnext/patches.txt

@ -288,3 +288,4 @@ erpnext.patches.v7_0.update_prevdoc_values_for_supplier_quotation_item
erpnext.patches.v7_0.rename_advance_table_fields
erpnext.patches.v7_0.rename_salary_components
erpnext.patches.v7_0.rename_prevdoc_fields
erpnext.patches.v7_0.rename_time_sheet_doctype

2
erpnext/patches/v7_0/convert_timelogbatch_to_timesheet.py

@ -5,7 +5,7 @@ from erpnext.manufacturing.doctype.production_order.production_order import add_
def execute():
for tlb in frappe.get_all('Time Log Batch', fields=["*"],
filters = [["docstatus", "<", "2"]]):
time_sheet = frappe.new_doc('Time Sheet')
time_sheet = frappe.new_doc('Timesheet')
time_sheet.employee= ""
time_sheet.company = frappe.db.get_single_value('Global Defaults', 'default_company')
time_sheet.sales_invoice = tlb.sales_invoice

2
erpnext/patches/v7_0/move_timelogbatch_from_salesinvoiceitem_to_salesinvoicetimesheet.py

@ -1,7 +1,7 @@
import frappe
def execute():
for time_sheet in frappe.db.sql(""" select sales_invoice, name, total_billing_amount from `tabTime Sheet`
for time_sheet in frappe.db.sql(""" select sales_invoice, name, total_billing_amount from `tabTimesheet`
where sales_invoice is not null and docstatus < 2""", as_dict=True):
si_doc = frappe.get_doc('Sales Invoice', time_sheet.sales_invoice)
ts = si_doc.append('timesheets',{})

13
erpnext/patches/v7_0/rename_time_sheet_doctype.py

@ -0,0 +1,13 @@
import frappe
def execute():
if frappe.db.table_exists("Time Sheet"):
frappe.rename_doc("DocType", "Time Sheet", "Timesheet")
frappe.rename_doc("DocType", "Time Sheet Detail", "Timesheet Detail")
for doctype in ['Time Sheet', 'Time Sheet Detail']:
frappe.delete_doc('DocType', doctype)
report = "Daily Time Sheet Summary"
if frappe.db.exists("Report", report):
frappe.delete_doc('Report', report)

8
erpnext/patches/v7_0/set_naming_series_for_timesheet.py

@ -7,9 +7,9 @@ import frappe
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
def execute():
frappe.reload_doc('projects', 'doctype','time_sheet')
frappe.reload_doc('projects', 'doctype', 'time_sheet_detail')
frappe.reload_doc('projects', 'doctype', 'timesheet')
frappe.reload_doc('projects', 'doctype', 'timesheet_detail')
frappe.reload_doc('accounts', 'doctype', 'sales_invoice_timesheet')
make_property_setter('Time Sheet', "naming_series", "options", 'TS-', "Text")
make_property_setter('Time Sheet', "naming_series", "default", 'TS-', "Text")
make_property_setter('Timesheet', "naming_series", "options", 'TS-', "Text")
make_property_setter('Timesheet', "naming_series", "default", 'TS-', "Text")

6
erpnext/projects/doctype/project/project.py

@ -19,7 +19,7 @@ class Project(Document):
self.load_tasks()
self.set_onload('activity_summary', frappe.db.sql('''select activity_type, sum(hours) as total_hours
from `tabTime Sheet Detail` where project=%s group by activity_type order by total_hours desc''', self.name, as_dict=True))
from `tabTimesheet Detail` where project=%s group by activity_type order by total_hours desc''', self.name, as_dict=True))
def __setup__(self):
self.onload()
@ -105,7 +105,7 @@ class Project(Document):
min(from_time) as start_date,
max(to_time) as end_date,
sum(hours) as time
from `tabTime Sheet Detail` where project = %s and docstatus = 1""", self.name, as_dict=1)[0]
from `tabTimesheet Detail` where project = %s and docstatus = 1""", self.name, as_dict=1)[0]
from_expense_claim = frappe.db.sql("""select
sum(total_sanctioned_amount) as total_sanctioned_amount
@ -154,7 +154,7 @@ class Project(Document):
def get_timeline_data(doctype, name):
'''Return timeline for attendance'''
return dict(frappe.db.sql('''select unix_timestamp(from_time), count(*)
from `tabTime Sheet Detail` where project=%s
from `tabTimesheet Detail` where project=%s
and from_time > date_sub(curdate(), interval 1 year)
and docstatus < 2
group by date(from_time)''', name))

2
erpnext/projects/doctype/project/project_links.py

@ -5,7 +5,7 @@ links = {
'transactions': [
{
'label': _('Project'),
'items': ['Task', 'Time Sheet', 'Expense Claim', 'Issue']
'items': ['Task', 'Timesheet', 'Expense Claim', 'Issue']
},
{
'label': _('Material'),

2
erpnext/projects/doctype/task/task.py

@ -58,7 +58,7 @@ class Task(Document):
def update_time_and_costing(self):
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(hours) as time from `tabTime Sheet Detail` where task = %s and docstatus=1"""
sum(hours) as time from `tabTimesheet Detail` where task = %s and docstatus=1"""
,self.name, as_dict=1)[0]
if self.status == "Open":
self.status = "Working"

0
erpnext/projects/doctype/time_sheet/__init__.py → erpnext/projects/doctype/timesheet/__init__.py

68
erpnext/projects/doctype/time_sheet/test_time_sheet.py → erpnext/projects/doctype/timesheet/test_timesheet.py

@ -7,40 +7,40 @@ import frappe
import unittest
import datetime
from frappe.utils import now_datetime, nowdate
from erpnext.projects.doctype.time_sheet.time_sheet import OverlapError
from erpnext.projects.doctype.time_sheet.time_sheet import make_salary_slip, make_sales_invoice
from erpnext.projects.doctype.timesheet.timesheet import OverlapError
from erpnext.projects.doctype.timesheet.timesheet import make_salary_slip, make_sales_invoice
class TestTimeSheet(unittest.TestCase):
def test_time_sheet_billing_amount(self):
class TestTimesheet(unittest.TestCase):
def test_timesheet_billing_amount(self):
salary_structure = make_salary_structure("_T-Employee-0001")
time_sheet = make_time_sheet("_T-Employee-0001", True)
timesheet = make_timesheet("_T-Employee-0001", True)
self.assertEquals(time_sheet.total_hours, 2)
self.assertEquals(time_sheet.time_logs[0].billing_rate, 50)
self.assertEquals(time_sheet.time_logs[0].billing_amount, 100)
self.assertEquals(timesheet.total_hours, 2)
self.assertEquals(timesheet.time_logs[0].billing_rate, 50)
self.assertEquals(timesheet.time_logs[0].billing_amount, 100)
def test_salary_slip_from_timesheet(self):
salary_structure = make_salary_structure("_T-Employee-0001")
time_sheet = make_time_sheet("_T-Employee-0001", simulate = True)
salary_slip = make_salary_slip(time_sheet.name)
timesheet = make_timesheet("_T-Employee-0001", simulate = True)
salary_slip = make_salary_slip(timesheet.name)
salary_slip.submit()
self.assertEquals(salary_slip.total_working_hours, 2)
self.assertEquals(salary_slip.hour_rate, 50)
self.assertEquals(salary_slip.net_pay, 150)
self.assertEquals(salary_slip.timesheets[0].time_sheet, time_sheet.name)
self.assertEquals(salary_slip.timesheets[0].time_sheet, timesheet.name)
self.assertEquals(salary_slip.timesheets[0].working_hours, 2)
time_sheet = frappe.get_doc('Time Sheet', time_sheet.name)
self.assertEquals(time_sheet.status, 'Payslip')
timesheet = frappe.get_doc('Timesheet', timesheet.name)
self.assertEquals(timesheet.status, 'Payslip')
salary_slip.cancel()
time_sheet = frappe.get_doc('Time Sheet', time_sheet.name)
self.assertEquals(time_sheet.status, 'Submitted')
timesheet = frappe.get_doc('Timesheet', timesheet.name)
self.assertEquals(timesheet.status, 'Submitted')
def test_sales_invoice_from_timesheet(self):
time_sheet = make_time_sheet("_T-Employee-0001", simulate = True, billable = 1)
sales_invoice = make_sales_invoice(time_sheet.name)
timesheet = make_timesheet("_T-Employee-0001", simulate = True, billable = 1)
sales_invoice = make_sales_invoice(timesheet.name)
sales_invoice.customer = "_Test Customer"
sales_invoice.due_date = nowdate()
@ -51,9 +51,9 @@ class TestTimeSheet(unittest.TestCase):
sales_invoice.submit()
time_sheet = frappe.get_doc('Time Sheet', time_sheet.name)
timesheet = frappe.get_doc('Timesheet', timesheet.name)
self.assertEquals(sales_invoice.total_billing_amount, 100)
self.assertEquals(time_sheet.status, 'Billed')
self.assertEquals(timesheet.status, 'Billed')
def make_salary_structure(employee):
name = frappe.db.get_value('Salary Structure', {'employee': employee, 'salary_slip_based_on_timesheet': 1}, 'name')
@ -86,32 +86,32 @@ def make_salary_structure(employee):
return salary_structure
def make_time_sheet(employee, simulate=False, billable = 0):
def make_timesheet(employee, simulate=False, billable = 0):
update_activity_type("_Test Activity Type")
time_sheet = frappe.new_doc("Time Sheet")
time_sheet.employee = employee
time_sheet_detail = time_sheet.append('time_logs', {})
time_sheet_detail.billable = billable
time_sheet_detail.activity_type = "_Test Activity Type"
time_sheet_detail.from_time = now_datetime()
time_sheet_detail.hours = 2
time_sheet_detail.to_time = time_sheet_detail.from_time + datetime.timedelta(hours= time_sheet_detail.hours)
for data in time_sheet.get('time_logs'):
timesheet = frappe.new_doc("Timesheet")
timesheet.employee = employee
timesheet_detail = timesheet.append('time_logs', {})
timesheet_detail.billable = billable
timesheet_detail.activity_type = "_Test Activity Type"
timesheet_detail.from_time = now_datetime()
timesheet_detail.hours = 2
timesheet_detail.to_time = timesheet_detail.from_time + datetime.timedelta(hours= timesheet_detail.hours)
for data in timesheet.get('time_logs'):
if simulate:
while True:
try:
time_sheet.save()
timesheet.save()
break
except OverlapError:
data.from_time = data.from_time + datetime.timedelta(minutes=10)
data.to_time = data.from_time + datetime.timedelta(hours= data.hours)
else:
time_sheet.save()
timesheet.save()
time_sheet.submit()
timesheet.submit()
return time_sheet
return timesheet
def update_activity_type(activity_type):
activity_type = frappe.get_doc('Activity Type',activity_type)

12
erpnext/projects/doctype/time_sheet/time_sheet.js → erpnext/projects/doctype/timesheet/timesheet.js

@ -1,7 +1,7 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
frappe.ui.form.on("Time Sheet", {
frappe.ui.form.on("Timesheet", {
setup: function(frm) {
frm.get_field('time_logs').grid.editable_fields = [
{fieldname: 'activity_type', columns: 2},
@ -12,7 +12,7 @@ frappe.ui.form.on("Time Sheet", {
frm.fields_dict.employee.get_query = function() {
return {
query:"erpnext.projects.doctype.time_sheet.time_sheet.get_employee_list"
query:"erpnext.projects.doctype.timesheet.timesheet.get_employee_list"
}
}
@ -50,20 +50,20 @@ frappe.ui.form.on("Time Sheet", {
make_invoice: function(frm) {
frappe.model.open_mapped_doc({
method: "erpnext.projects.doctype.time_sheet.time_sheet.make_sales_invoice",
method: "erpnext.projects.doctype.timesheet.timesheet.make_sales_invoice",
frm: frm
});
},
make_salary_slip: function(frm) {
frappe.model.open_mapped_doc({
method: "erpnext.projects.doctype.time_sheet.time_sheet.make_salary_slip",
method: "erpnext.projects.doctype.timesheet.timesheet.make_salary_slip",
frm: frm
});
},
})
frappe.ui.form.on("Time Sheet Detail", {
frappe.ui.form.on("Timesheet Detail", {
time_logs_remove: function(frm) {
calculate_time_and_amount(frm);
},
@ -107,7 +107,7 @@ frappe.ui.form.on("Time Sheet Detail", {
child = locals[cdt][cdn];
if(frm.doc.employee || frm.doc.production_order){
frappe.call({
method: "erpnext.projects.doctype.time_sheet.time_sheet.get_activity_cost",
method: "erpnext.projects.doctype.timesheet.timesheet.get_activity_cost",
args: {
employee: frm.doc.employee,
activity_type: child.activity_type

8
erpnext/projects/doctype/time_sheet/time_sheet.json → erpnext/projects/doctype/timesheet/timesheet.json

@ -436,7 +436,7 @@
"label": "Time Sheets",
"length": 0,
"no_copy": 0,
"options": "Time Sheet Detail",
"options": "Timesheet Detail",
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
@ -563,7 +563,7 @@
"label": "Amended From",
"length": 0,
"no_copy": 1,
"options": "Time Sheet",
"options": "Timesheet",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
@ -586,10 +586,10 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-06-29 15:16:31.668367",
"modified": "2016-07-06 18:36:21.103681",
"modified_by": "Administrator",
"module": "Projects",
"name": "Time Sheet",
"name": "Timesheet",
"owner": "Administrator",
"permissions": [
{

24
erpnext/projects/doctype/time_sheet/time_sheet.py → erpnext/projects/doctype/timesheet/timesheet.py

@ -1,6 +1,5 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
# -*- coding: utf-8 -*-
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
@ -15,8 +14,7 @@ from erpnext.manufacturing.doctype.manufacturing_settings.manufacturing_settings
class OverlapError(frappe.ValidationError): pass
class OverProductionLoggedError(frappe.ValidationError): pass
class TimeSheet(Document):
class Timesheet(Document):
def validate(self):
self.set_status()
self.total_hours = 0.0
@ -117,7 +115,7 @@ class TimeSheet(Document):
"""Returns 'Actual Operating Time'. """
return frappe.db.sql("""select
sum(tsd.hours*60) as mins, sum(tsd.completed_qty) as completed_qty, min(tsd.from_time) as from_time,
max(tsd.to_time) as to_time from `tabTime Sheet Detail` as tsd, `tabTime Sheet` as ts where
max(tsd.to_time) as to_time from `tabTimesheet Detail` as tsd, `tabTimesheet` as ts where
ts.production_order = %s and tsd.operation_id = %s and ts.docstatus=1 and ts.name = tsd.parent""",
(self.production_order, operation_id), as_dict=1)[0]
@ -159,7 +157,7 @@ class TimeSheet(Document):
return
existing = frappe.db.sql("""select ts.name as name, tsd.from_time as from_time, tsd.to_time as to_time from
`tabTime Sheet Detail` tsd, `tabTime Sheet` ts where tsd.`{0}`=%(val)s and tsd.parent = ts.name and
`tabTimesheet Detail` tsd, `tabTimesheet` ts where tsd.`{0}`=%(val)s and tsd.parent = ts.name and
(
(%(from_time)s > tsd.from_time and %(from_time)s < tsd.to_time) or
(%(to_time)s > tsd.from_time and %(to_time)s < tsd.to_time) or
@ -198,7 +196,7 @@ class TimeSheet(Document):
def get_last_working_slot(self, time_sheet, workstation):
return frappe.db.sql(""" select max(from_time) as from_time, max(to_time) as to_time
from `tabTime Sheet Detail` where workstation = %(workstation)s""",
from `tabTimesheet Detail` where workstation = %(workstation)s""",
{'workstation': workstation}, as_dict=True)[0]
def update_cost(self):
@ -216,8 +214,8 @@ class TimeSheet(Document):
def make_sales_invoice(source_name, target=None):
target = frappe.new_doc("Sales Invoice")
target.append("timesheets", get_mapped_doc("Time Sheet", source_name, {
"Time Sheet": {
target.append("timesheets", get_mapped_doc("Timesheet", source_name, {
"Timesheet": {
"doctype": "Sales Invoice Timesheet",
"field_map": {
"total_billing_amount": "billing_amount",
@ -235,8 +233,8 @@ def make_salary_slip(source_name, target_doc=None):
target = frappe.new_doc("Salary Slip")
set_missing_values(source_name, target)
target.append("timesheets", get_mapped_doc("Time Sheet", source_name, {
"Time Sheet": {
target.append("timesheets", get_mapped_doc("Timesheet", source_name, {
"Timesheet": {
"doctype": "Salary Slip Timesheet",
"field_map": {
"total_hours": "working_hours",
@ -250,7 +248,7 @@ def make_salary_slip(source_name, target_doc=None):
return target
def set_missing_values(time_sheet, target):
doc = frappe.get_doc('Time Sheet', time_sheet)
doc = frappe.get_doc('Timesheet', time_sheet)
target.employee = doc.employee
target.employee_name = doc.employee_name
target.salary_slip_based_on_timesheet = 1

2
erpnext/projects/doctype/time_sheet/time_sheet_list.js → erpnext/projects/doctype/timesheet/timesheet_list.js

@ -1,4 +1,4 @@
frappe.listview_settings['Time Sheet'] = {
frappe.listview_settings['Timesheet'] = {
add_fields: ["status", "total_hours"],
get_indicator: function(doc) {
if (doc.status== "Billed") {

0
erpnext/projects/doctype/time_sheet_detail/__init__.py → erpnext/projects/doctype/timesheet_detail/__init__.py

4
erpnext/projects/doctype/time_sheet_detail/time_sheet_detail.json → erpnext/projects/doctype/timesheet_detail/timesheet_detail.json

@ -531,10 +531,10 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2016-07-06 13:40:41.419370",
"modified": "2016-07-06 18:35:24.106546",
"modified_by": "Administrator",
"module": "Projects",
"name": "Time Sheet Detail",
"name": "Timesheet Detail",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,

2
erpnext/projects/doctype/time_sheet_detail/time_sheet_detail.py → erpnext/projects/doctype/timesheet_detail/timesheet_detail.py

@ -6,5 +6,5 @@ from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
class TimeSheetDetail(Document):
class TimesheetDetail(Document):
pass

6
erpnext/projects/report/daily_time_sheet_summary/daily_time_sheet_summary.py

@ -12,7 +12,7 @@ def execute(filters=None):
filters["from_time"] = "00:00:00"
filters["to_time"] = "24:00:00"
columns = [_("Time Sheet") + ":Link/Time Sheet:120", _("Employee") + "::150", _("From Datetime") + "::140",
columns = [_("Timesheet") + ":Link/Timesheet:120", _("Employee") + "::150", _("From Datetime") + "::140",
_("To Datetime") + "::140", _("Hours") + "::70", _("Activity Type") + "::120", _("Task") + ":Link/Task:150",
_("Project") + ":Link/Project:120", _("Status") + "::70"]
@ -28,7 +28,7 @@ def execute(filters=None):
def get_data(conditions, filters):
time_sheet = frappe.db.sql(""" select ts.name, ts.employee, tsd.from_time, tsd.to_time, tsd.hours,
tsd.activity_type, tsd.task, tsd.project, ts.status from `tabTime Sheet Detail` tsd,
`tabTime Sheet` ts where ts.name = tsd.parent and %s order by ts.name"""%(conditions), filters, as_list=1)
tsd.activity_type, tsd.task, tsd.project, ts.status from `tabTimesheet Detail` tsd,
`tabTimesheet` ts where ts.name = tsd.parent and %s order by ts.name"""%(conditions), filters, as_list=1)
return time_sheet

0
erpnext/projects/report/daily_timesheet_summary/__init__.py

19
erpnext/projects/report/daily_timesheet_summary/daily_timesheet_summary.js

@ -0,0 +1,19 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.query_reports["Daily Timesheet Summary"] = {
"filters": [
{
"fieldname":"from_date",
"label": __("From Date"),
"fieldtype": "Date",
"default": frappe.datetime.get_today()
},
{
"fieldname":"to_date",
"label": __("To Date"),
"fieldtype": "Date",
"default": frappe.datetime.get_today()
},
]
}

18
erpnext/projects/report/daily_timesheet_summary/daily_timesheet_summary.json

@ -0,0 +1,18 @@
{
"add_total_row": 0,
"apply_user_permissions": 1,
"creation": "2016-07-06 19:31:25.534583",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"modified": "2016-07-06 19:31:25.534583",
"modified_by": "Administrator",
"module": "Projects",
"name": "Daily Timesheet Summary",
"owner": "Administrator",
"ref_doctype": "Timesheet",
"report_name": "Daily Timesheet Summary",
"report_type": "Script Report"
}

34
erpnext/projects/report/daily_timesheet_summary/daily_timesheet_summary.py

@ -0,0 +1,34 @@
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe import _
def execute(filters=None):
if not filters:
filters = {}
elif filters.get("from_date") or filters.get("to_date"):
filters["from_time"] = "00:00:00"
filters["to_time"] = "24:00:00"
columns = [_("Timesheet") + ":Link/Timesheet:120", _("Employee") + "::150", _("From Datetime") + "::140",
_("To Datetime") + "::140", _("Hours") + "::70", _("Activity Type") + "::120", _("Task") + ":Link/Task:150",
_("Project") + ":Link/Project:120", _("Status") + "::70"]
conditions = "ts.docstatus = 1"
if filters.get("from_date"):
conditions += " and tsd.from_time >= timestamp(%(from_date)s, %(from_time)s)"
if filters.get("to_date"):
conditions += " and tsd.to_time <= timestamp(%(to_date)s, %(to_time)s)"
data = get_data(conditions, filters)
return columns, data
def get_data(conditions, filters):
time_sheet = frappe.db.sql(""" select ts.name, ts.employee, tsd.from_time, tsd.to_time, tsd.hours,
tsd.activity_type, tsd.task, tsd.project, ts.status from `tabTimesheet Detail` tsd,
`tabTimesheet` ts where ts.name = tsd.parent and %s order by ts.name"""%(conditions), filters, as_list=1)
return time_sheet

2
erpnext/setup/doctype/company/delete_company_transactions.py

@ -73,7 +73,7 @@ def delete_bins(company_name):
def delete_time_sheets(company_name):
# Delete Time Logs as it is linked to Production Order / Project / Task, which are linked to company
frappe.db.sql("""
delete from `tabTime Sheet`
delete from `tabTimesheet`
where
company=%(company)s
""", {"company": company_name})

2
erpnext/setup/setup_wizard/domainify.py

@ -45,7 +45,7 @@ def get_domains():
},
'Services': {
'desktop_icons': ['Project', 'Time Sheet', 'Customer', 'Sales Order', 'Sales Invoice', 'Lead', 'Opportunity',
'desktop_icons': ['Project', 'Timesheet', 'Customer', 'Sales Order', 'Sales Invoice', 'Lead', 'Opportunity',
'Expense Claim', 'Employee', 'HR', 'ToDo'],
'remove_roles': ['Manufacturing User', 'Manufacturing Manager'],
'properties': [

2
erpnext/startup/notifications.py

@ -43,6 +43,6 @@ def get_notification_config():
"Purchase Receipt": {"docstatus": 0},
"Production Order": { "status": ("in", ("Draft", "Not Started", "In Process")) },
"BOM": {"docstatus": 0},
"Time Sheet": {"status": "Draft"}
"Timesheet": {"status": "Draft"}
}
}

Loading…
Cancel
Save