2021-04-19 11:19:28 +00:00
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
2021-04-20 12:23:41 +00:00
import frappe
from frappe import _
from erpnext . payroll . doctype . salary_structure_assignment . salary_structure_assignment import get_employee_currency
from erpnext . accounts . utils import get_currency_precision
from frappe . utils import flt
from erpnext . setup . utils import get_exchange_rate
2021-04-19 11:19:28 +00:00
def execute ( filters = None ) :
columns , data = [ ] , [ ]
data = get_data ( filters )
columns = get_columns ( )
charts = get_chart_data ( data )
return columns , data , None , charts
def get_data ( filters ) :
2021-04-20 12:23:41 +00:00
data = get_rows ( filters )
data = calculate_cost_and_profit ( data )
return data
def get_rows ( filters ) :
2021-04-19 11:19:28 +00:00
conditions = get_conditions ( filters )
2021-04-20 12:23:41 +00:00
standard_working_hours = frappe . db . get_single_value ( " HR Settings " , " standard_working_hours " )
2021-04-22 05:49:44 +00:00
if not standard_working_hours :
hr_settings = " <a href= ' /app/hr-settings ' >HR Settings</a> "
frappe . msgprint ( _ ( " The metrics for this report are calculated based on the Standard Working Hours. Please set Standard Working Hours in {0} . " ) . format ( hr_settings ) )
return [ ]
2021-04-20 12:23:41 +00:00
sql = """
SELECT
2021-04-19 11:19:28 +00:00
*
2021-04-20 12:23:41 +00:00
FROM
2021-04-19 11:19:28 +00:00
( SELECT
2021-04-20 12:23:41 +00:00
si . customer_name , si . base_grand_total ,
si . name as voucher_no , tabTimesheet . employee ,
tabTimesheet . title as employee_name , tabTimesheet . parent_project as project ,
tabTimesheet . start_date , tabTimesheet . end_date ,
tabTimesheet . total_billed_hours , tabTimesheet . name as timesheet ,
ss . base_gross_pay , ss . total_working_days ,
2021-04-19 11:19:28 +00:00
tabTimesheet . total_billed_hours / ( ss . total_working_days * { 0 } ) as utilization
2021-04-20 12:23:41 +00:00
FROM
2021-04-19 11:19:28 +00:00
` tabSalary Slip Timesheet ` as sst join ` tabTimesheet ` on tabTimesheet . name = sst . time_sheet
join ` tabSales Invoice Timesheet ` as sit on sit . time_sheet = tabTimesheet . name
2021-04-20 12:23:41 +00:00
join ` tabSales Invoice ` as si on si . name = sit . parent and si . status != " Cancelled "
join ` tabSalary Slip ` as ss on ss . name = sst . parent and ss . status != " Cancelled " """ .format(standard_working_hours)
2021-04-19 11:19:28 +00:00
if conditions :
2021-04-20 12:23:41 +00:00
sql + = """
WHERE
{ 0 } ) as t """ .format(conditions)
return frappe . db . sql ( sql , filters , as_dict = True )
def calculate_cost_and_profit ( data ) :
for row in data :
row . fractional_cost = row . base_gross_pay * row . utilization
row . profit = row . base_grand_total - row . base_gross_pay * row . utilization
2021-04-19 11:19:28 +00:00
return data
def get_conditions ( filters ) :
conditions = [ ]
2021-04-20 12:23:41 +00:00
if filters . get ( " company " ) :
2021-04-22 05:49:44 +00:00
conditions . append ( " tabTimesheet.company= {0} " . format ( frappe . db . escape ( filters . get ( " company " ) ) ) )
2021-04-20 12:23:41 +00:00
if filters . get ( " start_date " ) :
conditions . append ( " tabTimesheet.start_date>= ' {0} ' " . format ( filters . get ( " start_date " ) ) )
if filters . get ( " end_date " ) :
conditions . append ( " tabTimesheet.end_date<= ' {0} ' " . format ( filters . get ( " end_date " ) ) )
if filters . get ( " customer_name " ) :
2021-04-22 05:49:44 +00:00
conditions . append ( " si.customer_name= {0} " . format ( frappe . db . escape ( filters . get ( " customer_name " ) ) ) )
2021-04-20 12:23:41 +00:00
if filters . get ( " employee " ) :
2021-04-22 05:49:44 +00:00
conditions . append ( " tabTimesheet.employee= {0} " . format ( frappe . db . escape ( filters . get ( " employee " ) ) ) )
2021-04-20 12:23:41 +00:00
if filters . get ( " project " ) :
2021-04-22 05:49:44 +00:00
conditions . append ( " tabTimesheet.parent_project= {0} " . format ( frappe . db . escape ( filters . get ( " project " ) ) ) )
2021-04-19 11:19:28 +00:00
2021-04-20 12:23:41 +00:00
conditions = " and " . join ( conditions )
2021-04-19 11:19:28 +00:00
return conditions
def get_chart_data ( data ) :
if not data :
return None
labels = [ ]
utilization = [ ]
for entry in data :
2021-04-20 12:23:41 +00:00
labels . append ( entry . get ( " employee_name " ) + " - " + str ( entry . get ( " end_date " ) ) )
utilization . append ( entry . get ( " utilization " ) )
2021-04-19 11:19:28 +00:00
charts = {
2021-04-20 12:23:41 +00:00
" data " : {
" labels " : labels ,
" datasets " : [
2021-04-19 11:19:28 +00:00
{
2021-04-20 12:23:41 +00:00
" name " : " Utilization " ,
" values " : utilization
2021-04-19 11:19:28 +00:00
}
]
} ,
2021-04-20 12:23:41 +00:00
" type " : " bar " ,
" colors " : [ " #84BDD5 " ]
2021-04-19 11:19:28 +00:00
}
return charts
def get_columns ( ) :
return [
{
2021-04-20 12:23:41 +00:00
" fieldname " : " customer_name " ,
" label " : _ ( " Customer " ) ,
" fieldtype " : " Link " ,
" options " : " Customer " ,
" width " : 150
} ,
{
" fieldname " : " employee " ,
" label " : _ ( " Employee " ) ,
" fieldtype " : " Link " ,
" options " : " Employee " ,
" width " : 130
} ,
{
" fieldname " : " employee_name " ,
" label " : _ ( " Employee Name " ) ,
" fieldtype " : " Data " ,
" width " : 120
2021-04-19 11:19:28 +00:00
} ,
{
2021-04-20 12:23:41 +00:00
" fieldname " : " voucher_no " ,
" label " : _ ( " Sales Invoice " ) ,
" fieldtype " : " Link " ,
" options " : " Sales Invoice " ,
" width " : 180
2021-04-19 11:19:28 +00:00
} ,
{
2021-04-20 12:23:41 +00:00
" fieldname " : " timesheet " ,
" label " : _ ( " Timesheet " ) ,
" fieldtype " : " Link " ,
" options " : " Timesheet " ,
" width " : 130
2021-04-19 11:19:28 +00:00
} ,
{
2021-04-20 12:23:41 +00:00
" fieldname " : " project " ,
" label " : _ ( " Project " ) ,
" fieldtype " : " Link " ,
" options " : " Project " ,
" width " : 100
2021-04-19 11:19:28 +00:00
} ,
{
2021-04-20 12:23:41 +00:00
" fieldname " : " base_grand_total " ,
" label " : _ ( " Bill Amount " ) ,
" fieldtype " : " Currency " ,
" options " : " currency " ,
" width " : 100
2021-04-19 11:19:28 +00:00
} ,
{
2021-04-20 12:23:41 +00:00
" fieldname " : " base_gross_pay " ,
" label " : _ ( " Cost " ) ,
" fieldtype " : " Currency " ,
" options " : " currency " ,
" width " : 100
2021-04-19 11:19:28 +00:00
} ,
{
2021-04-20 12:23:41 +00:00
" fieldname " : " profit " ,
" label " : _ ( " Profit " ) ,
" fieldtype " : " Currency " ,
" options " : " currency " ,
" width " : 100
2021-04-19 11:19:28 +00:00
} ,
{
2021-04-20 12:23:41 +00:00
" fieldname " : " utilization " ,
" label " : _ ( " Utilization " ) ,
" fieldtype " : " Percentage " ,
" width " : 120
2021-04-19 11:19:28 +00:00
} ,
{
2021-04-20 12:23:41 +00:00
" fieldname " : " fractional_cost " ,
" label " : _ ( " Fractional Cost " ) ,
" fieldtype " : " Int " ,
" width " : 100
2021-04-19 11:19:28 +00:00
} ,
{
2021-04-20 12:23:41 +00:00
" fieldname " : " total_billed_hours " ,
" label " : _ ( " Total Billed Hours " ) ,
" fieldtype " : " Int " ,
" width " : 100
2021-04-19 11:19:28 +00:00
} ,
{
2021-04-20 12:23:41 +00:00
" fieldname " : " start_date " ,
" label " : _ ( " Start Date " ) ,
" fieldtype " : " Date " ,
" width " : 120
2021-04-19 11:19:28 +00:00
} ,
{
2021-04-20 12:23:41 +00:00
" fieldname " : " end_date " ,
" label " : _ ( " End Date " ) ,
" fieldtype " : " Date " ,
" width " : 120
2021-04-19 11:19:28 +00:00
} ,
{
2021-04-20 12:23:41 +00:00
" label " : _ ( " Currency " ) ,
" fieldname " : " currency " ,
" fieldtype " : " Link " ,
" options " : " Currency " ,
" width " : 100
2021-04-19 11:19:28 +00:00
}
2021-04-20 12:23:41 +00:00
]