Task added to expense claim
all cost (expense claim and time log) against Task; task updates project cost.
This commit is contained in:
parent
8026137998
commit
50234cb0fe
@ -191,6 +191,14 @@
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"fieldname": "task",
|
||||
"fieldtype": "Link",
|
||||
"label": "Task",
|
||||
"options": "Task",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"fieldname": "email_id",
|
||||
"fieldtype": "Data",
|
||||
@ -220,7 +228,7 @@
|
||||
"icon": "icon-money",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2015-03-26 04:41:50.473196",
|
||||
"modified": "2015-03-30 05:17:43.963137",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Expense Claim",
|
||||
|
@ -21,17 +21,18 @@ class ExpenseClaim(Document):
|
||||
self.validate_sanctioned_amount()
|
||||
self.validate_exp_details()
|
||||
self.validate_expense_approver()
|
||||
self.validate_task()
|
||||
set_employee_name(self)
|
||||
|
||||
def on_submit(self):
|
||||
if self.approval_status=="Draft":
|
||||
frappe.throw(_("""Approval Status must be 'Approved' or 'Rejected'"""))
|
||||
if self.project:
|
||||
self.update_project()
|
||||
if self.task:
|
||||
self.update_task()
|
||||
|
||||
def on_cancel(self):
|
||||
if self.project:
|
||||
self.update_project()
|
||||
self.update_task()
|
||||
|
||||
def validate_exp_details(self):
|
||||
if not self.get('expenses'):
|
||||
@ -42,10 +43,14 @@ class ExpenseClaim(Document):
|
||||
frappe.throw(_("{0} ({1}) must have role 'Expense Approver'")\
|
||||
.format(get_fullname(self.exp_approver), self.exp_approver), InvalidExpenseApproverError)
|
||||
|
||||
def update_project(self):
|
||||
def update_task(self):
|
||||
expense_amount = frappe.db.sql("""select sum(total_sanctioned_amount) from `tabExpense Claim`
|
||||
where project = %s and approval_status = "Approved" and docstatus=1""",self.project)
|
||||
frappe.db.set_value("Project", self.project, "total_expense_claims", expense_amount)
|
||||
where project = %s and task = %s and approval_status = "Approved" and docstatus=1""",(self.project, self.task))
|
||||
frappe.db.set_value("Project", self.project, "total_expense_claim", expense_amount)
|
||||
|
||||
def validate_task(self):
|
||||
if self.project and not self.task:
|
||||
frappe.throw(_("Task is Mandatory if Time Log is against a project"))
|
||||
|
||||
def validate_sanctioned_amount(self):
|
||||
if self.total_sanctioned_amount > self.total_claimed_amount:
|
||||
|
@ -206,9 +206,9 @@
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "total_expense_claims",
|
||||
"fieldname": "total_expense_claim",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Expense Claims",
|
||||
"label": "Total Expense Claim",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
@ -278,7 +278,7 @@
|
||||
"icon": "icon-puzzle-piece",
|
||||
"idx": 1,
|
||||
"max_attachments": 4,
|
||||
"modified": "2015-03-23 06:44:19.538443",
|
||||
"modified": "2015-03-30 08:42:33.940104",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Projects",
|
||||
"name": "Project",
|
||||
|
@ -25,6 +25,19 @@ erpnext.projects.Task = frappe.ui.form.Controller.extend({
|
||||
this.frm.doc.project && frappe.model.remove_from_locals("Project",
|
||||
this.frm.doc.project);
|
||||
},
|
||||
|
||||
refresh: function(doc) {
|
||||
if(!doc.__islocal) {
|
||||
cur_frm.add_custom_button(__("Time Logs"), function() {
|
||||
frappe.route_options = {"project": doc.project, "task": doc.name}
|
||||
frappe.set_route("List", "Time Log");
|
||||
}, "icon-list", true);
|
||||
cur_frm.add_custom_button(__("Expense Claims"), function() {
|
||||
frappe.route_options = {"project": doc.project, "task": doc.name}
|
||||
frappe.set_route("List", "Expense Claim");
|
||||
}, "icon-list", true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
@ -6,16 +6,6 @@
|
||||
"doctype": "DocType",
|
||||
"document_type": "Master",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "task_details",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "",
|
||||
"oldfieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"print_width": "50%",
|
||||
"search_index": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"fieldname": "subject",
|
||||
"fieldtype": "Data",
|
||||
@ -110,28 +100,27 @@
|
||||
{
|
||||
"fieldname": "time_and_budget",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Time and Budget",
|
||||
"label": "",
|
||||
"oldfieldtype": "Section Break",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "expected",
|
||||
"fieldtype": "Column Break",
|
||||
"label": "Expected",
|
||||
"oldfieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"print_width": "50%",
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"fieldname": "exp_total_hrs",
|
||||
"fieldtype": "Data",
|
||||
"label": "Total Hours (Expected)",
|
||||
"default": "0",
|
||||
"description": "in Hours",
|
||||
"fieldname": "expected_time",
|
||||
"fieldtype": "Float",
|
||||
"label": "Expected Time",
|
||||
"oldfieldname": "exp_total_hrs",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_12",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"fieldname": "allocated_budget",
|
||||
"fieldtype": "Currency",
|
||||
@ -143,8 +132,8 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "actual",
|
||||
"fieldtype": "Column Break",
|
||||
"label": "Actual",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "",
|
||||
"oldfieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"print_width": "50%",
|
||||
@ -156,7 +145,14 @@
|
||||
"label": "Actual Start Date",
|
||||
"oldfieldname": "act_start_date",
|
||||
"oldfieldtype": "Date",
|
||||
"permlevel": 0
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_15",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"fieldname": "act_end_date",
|
||||
@ -164,16 +160,50 @@
|
||||
"label": "Actual End Date",
|
||||
"oldfieldname": "act_end_date",
|
||||
"oldfieldtype": "Date",
|
||||
"permlevel": 0
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "actual_budget",
|
||||
"fieldname": "section_break_17",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "in Hours",
|
||||
"fieldname": "actual_time",
|
||||
"fieldtype": "Float",
|
||||
"label": "Actual Time",
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_20",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"fieldname": "actual_cost",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Actual Budget",
|
||||
"label": "Actual Cost",
|
||||
"oldfieldname": "actual_budget",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "total_expense_claim",
|
||||
"fieldtype": "Currency",
|
||||
"label": "Total Expense Claim",
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "more_details",
|
||||
@ -217,7 +247,7 @@
|
||||
"icon": "icon-check",
|
||||
"idx": 1,
|
||||
"max_attachments": 5,
|
||||
"modified": "2015-02-20 05:09:27.295024",
|
||||
"modified": "2015-03-30 05:50:04.409614",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Projects",
|
||||
"name": "Task",
|
||||
|
@ -4,7 +4,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe, json
|
||||
|
||||
from frappe.utils import getdate, today
|
||||
from frappe.utils import getdate
|
||||
from frappe import _
|
||||
|
||||
|
||||
@ -26,28 +26,34 @@ class Task(Document):
|
||||
return ret
|
||||
|
||||
def validate(self):
|
||||
self.validate_dates()
|
||||
|
||||
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):
|
||||
frappe.throw(_("'Expected Start Date' can not be greater than 'Expected End Date'"))
|
||||
|
||||
if self.act_start_date and self.act_end_date and getdate(self.act_start_date) > getdate(self.act_end_date):
|
||||
frappe.throw(_("'Actual Start Date' can not be greater than 'Actual End Date'"))
|
||||
|
||||
self.update_status()
|
||||
|
||||
def update_status(self):
|
||||
status = frappe.db.get_value("Task", self.name, "status")
|
||||
if self.status=="Working" and status !="Working" and not self.act_start_date:
|
||||
self.act_start_date = today()
|
||||
|
||||
if self.status=="Closed" and status != "Closed" and not self.act_end_date:
|
||||
self.act_end_date = today()
|
||||
|
||||
def on_update(self):
|
||||
self.update_percentage()
|
||||
self.update_project()
|
||||
|
||||
def update_percentage(self):
|
||||
"""update percent complete in project"""
|
||||
if self.project and not self.flags.from_project:
|
||||
project = frappe.get_doc("Project", self.project)
|
||||
project.run_method("update_percent_complete")
|
||||
|
||||
def update_project(self):
|
||||
total_activity_cost = frappe.db.sql("""select sum(actual_cost) from `tabTask`
|
||||
where project = %s""",self.project)
|
||||
frappe.db.set_value("Project", self.project, "total_activity_cost", total_activity_cost)
|
||||
|
||||
total_expense_claim = frappe.db.sql("""select sum(total_expense_claim) from `tabTask`
|
||||
where project = %s""",self.project)
|
||||
frappe.db.set_value("Project", self.project, "total_expense_claim", total_expense_claim)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_events(start, end, filters=None):
|
||||
from frappe.desk.reportview import build_match_conditions
|
||||
|
@ -91,6 +91,25 @@
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "",
|
||||
"fieldname": "project",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Project",
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "",
|
||||
"fieldname": "task",
|
||||
"fieldtype": "Link",
|
||||
"label": "Task",
|
||||
"options": "Task",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:!doc.for_manufacturing",
|
||||
"fieldname": "activity_type",
|
||||
@ -102,15 +121,6 @@
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:!doc.for_manufacturing",
|
||||
"fieldname": "task",
|
||||
"fieldtype": "Link",
|
||||
"label": "Task",
|
||||
"options": "Task",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.for_manufacturing",
|
||||
"fieldname": "section_break_11",
|
||||
@ -188,22 +198,6 @@
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_9",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "",
|
||||
"fieldname": "project",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Project",
|
||||
"options": "Project",
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "",
|
||||
"fieldname": "section_break_24",
|
||||
|
@ -24,15 +24,20 @@ class TimeLog(Document):
|
||||
self.check_workstation_timings()
|
||||
self.validate_production_order()
|
||||
self.validate_manufacturing()
|
||||
self.validate_task()
|
||||
self.validate_cost()
|
||||
|
||||
def on_submit(self):
|
||||
self.update_production_order()
|
||||
self.update_project()
|
||||
if self.for_manufacturing:
|
||||
self.update_production_order()
|
||||
if self.task:
|
||||
self.update_task()
|
||||
|
||||
def on_cancel(self):
|
||||
self.update_production_order()
|
||||
self.update_project()
|
||||
if self.for_manufacturing:
|
||||
self.update_production_order()
|
||||
if self.task:
|
||||
self.update_task()
|
||||
|
||||
def before_update_after_submit(self):
|
||||
self.set_status()
|
||||
@ -128,7 +133,7 @@ class TimeLog(Document):
|
||||
def update_production_order(self):
|
||||
"""Updates `start_date`, `end_date`, `status` for operation in Production Order."""
|
||||
|
||||
if self.for_manufacturing and self.production_order:
|
||||
if self.production_order:
|
||||
if not self.operation_id:
|
||||
frappe.throw(_("Operation ID not set"))
|
||||
|
||||
@ -217,10 +222,22 @@ class TimeLog(Document):
|
||||
else:
|
||||
self.billing_amount = 0
|
||||
|
||||
def update_project(self):
|
||||
activity_cost = frappe.db.sql("""select sum(billing_cost) from `tabTime Log`
|
||||
where project = %s and docstatus=1""",self.project)
|
||||
frappe.db.set_value("Project", self.project, "total_activity_cost", activity_cost)
|
||||
def validate_task(self):
|
||||
if self.project and not self.task:
|
||||
frappe.throw(_("Task is Mandatory if Time Log is against a project"))
|
||||
|
||||
def update_task(self):
|
||||
tl = frappe.db.sql("""select min(from_time) as start_date, max(to_time) as end_date, sum(billing_amount) as cost, sum(hours) as time
|
||||
from `tabTime Log` where project = %s and task = %s and docstatus=1""",(self.project, self.task),as_dict=1)[0]
|
||||
|
||||
task = frappe.get_doc("Task", self.task)
|
||||
if task.status == "Open":
|
||||
task.status = "Working"
|
||||
task.actual_cost= tl.cost
|
||||
task.actual_time= tl.time
|
||||
task.act_start_date= tl.start_date
|
||||
task.act_end_date= tl.end_date
|
||||
task.save()
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_events(start, end, filters=None):
|
||||
|
Loading…
Reference in New Issue
Block a user