Commit f8b5dc2b authored by aecres's avatar aecres

- WIP: revenues by department widget

parent 6fb4284b
......@@ -21,7 +21,7 @@ Ext.onReady(function () {
revenueByDeptsChart = new Ext.chart.Chart({
xtype: 'chart',
animate: true,
animate: false,
store: revenueByDeptsStore,
legend: { position: 'right' },
insetPadding: 20,
......@@ -31,7 +31,7 @@ Ext.onReady(function () {
type: 'Numeric',
position: 'left',
fields: @dept_list_json;noquote@,
title: 'Revenue (in 1000 USD)'
title: 'Revenue (x 1000 @default_currency@)'
}, {
type: 'Time',
position: 'bottom',
......
......@@ -15,6 +15,13 @@ if {![info exists diagram_width]} { set diagram_width 600 }
if {![info exists diagram_height]} { set diagram_height 500 }
if {![info exists diagram_title]} { set diagram_title [lang::message::lookup "" intranet-reporting-dashboard.Revenue_by_Department "Revenue by Department"] }
# Main classifier
# set dept_sql "coalesce(acs_object__name(project_cost_center_id), 'none')"
# set dept_sql "coalesce(im_category_from_id(aec_area_id), 'none')"
#set dept_sql "coalesce((select category from im_categories where category_id = aec_area_id), 'none')"
set dept_sql "coalesce((select cost_center_name from im_cost_centers where cost_center_id = project_cost_center_id), 'none')"
# ----------------------------------------------------
# Diagram Setup
# ----------------------------------------------------
......@@ -38,6 +45,51 @@ set invoice_finished_period 30
# should have to invoices, so "revenue" should be zero.
# ----------------------------------------------------
set middle_sql "
select main_p.project_id,
'<a href=/intranet/projects/view?project_id='||main_p.project_id||'>'||
main_p.project_name || '</a>' as name,
main_p.start_date,
main_p.end_date,
main_p.department,
revenue * now_percent / 100.0 / 1000.0 as now_revenue,
external_cost * now_percent / 100.0 / 1000.0 as now_external_cost,
internal_cost * now_percent / 100.0 / 1000.0 as now_internal_cost,
(revenue * now_percent - external_cost * now_percent - internal_cost * now_percent) / 100.0 / 1000.0 as now_profit
from
(select *,
round(CASE
WHEN (:now::date - end_date) > 0 THEN 100.0 -- project finished
WHEN (:now::date - start_date) < 0 THEN 0.0 -- not yet started
ELSE 100.0 * (:now::date - start_date) / (greatest(1, end_date - start_date)) -- in course
END,2) as now_percent
from (
select project_id,
project_name,
$dept_sql as department,
start_date::date as start_date,
greatest(end_date::date, start_date::date + (cost_invoices_cache/5000)::integer) as end_date,
project_status_id,
cost_invoices_cache as revenue,
cost_bills_cache as external_cost,
cost_timesheet_logged_cache + cost_expense_logged_cache as internal_cost
from im_projects
where parent_id is null and
end_date >= :first_project_start::date
) p
where 1=1
) main_p
where
1 = 1
-- order by profit ASC
-- order by revenue * now_percent - external_cost * now_percent - internal_cost * now_percent
"
# set first_project_start [db_string now "select now()::date - 365"]
# set now [db_string now "select now()::date"]
# ad_return_complaint 1 [im_ad_hoc_query -format html "$middle_sql"]
set revenue_sql "
select
department,
......@@ -46,67 +98,14 @@ select
sum(now_internal_cost) as internal_cost,
sum(now_profit) as profit
from
(select
main_p.project_id,
main_p.department,
-- main_p.project_name,
-- main_p.start_date,
-- main_p.end_date,
CASE WHEN status_id in (71, 72, 73, 74, 75, 77, 82, 83, 10000408) THEN 0.0
ELSE round(revenue * now_percent / 100000.0) END as now_revenue,
round(external_cost * now_percent / 100000.0) as now_external_cost,
round(internal_cost * now_percent / 100000.0) as now_internal_cost,
CASE WHEN status_id in (77, 82, 83, 10000408) THEN 0.0 ELSE round(revenue * now_percent / 100000.0) END
- round(external_cost * now_percent / 100000.0) - round(internal_cost * now_percent / 100000.0) as now_profit
from
(select
main_p.project_id as project_id,
main_p.project_name as project_name,
coalesce(im_category_from_id(aec_area_id), 'none') as department,
main_p.start_date::date as start_date,
main_p.end_date::date as end_date,
main_p.project_status_id as status_id,
round(CASE
WHEN (:now::date - main_p.end_date::date) > 0 THEN 100.0 -- project finished
WHEN (:now::date - main_p.start_date::date) < 0 THEN 0.0 -- not yet started
ELSE 100.0 * (:now::date - main_p.start_date::date) /
(greatest(1, main_p.end_date::date - main_p.start_date::date)) -- in course
END,2) as now_percent,
main_p.project_budget as budget,
-- Revenue - 30 days after project end all invoices have been written.
-- Before that we assume that the quoted amount will be invoiced later.
CASE WHEN :now::date - main_p.end_date::date > :invoice_finished_period
THEN greatest(main_p.cost_invoices_cache, main_p.project_budget)
ELSE greatest(main_p.cost_invoices_cache, main_p.cost_quotes_cache, main_p.project_budget)
END as revenue,
-- External costs - 30 days after project end all provider bills have been written.
-- Before we assume that all Purchase Orders will convert to bills.
CASE WHEN :now::date - main_p.end_date::date > :invoice_finished_period
THEN main_p.cost_purchase_orders_cache
ELSE greatest(main_p.cost_purchase_orders_cache, main_p.cost_bills_cache)
END as external_cost,
main_p.cost_timesheet_logged_cache + main_p.cost_expense_logged_cache as internal_cost
from im_projects main_p
where main_p.parent_id is null and
main_p.end_date >= :first_project_start::date
) main_p
where
revenue > 0.0
) t
($middle_sql) t
group by department
order by department
"
# Get the list of all departments
set dept_list [db_list dept_list "select distinct im_category_from_id(aec_area_id) from im_projects order by im_category_from_id(aec_area_id)"]
set dept_list [db_list dept_list "select dept from (select distinct $dept_sql as dept from im_projects) t order by lower(dept)"]
set dept_list_json "\['[join $dept_list "', '"]'\]"
......@@ -167,7 +166,7 @@ foreach now $months {
set rev_hash_old($dept) $value; # update the old value for next iteration
set diff [expr $value - $old_value]
set diff [expr round(1000.0 * ($value - $old_value)) / 1000.0]
lappend rev_line "'$dept': $diff"
}
......
......@@ -526,3 +526,26 @@ SELECT acs_permission__grant_permission(
'read'
);
-- Revenues by department
--
SELECT im_component_plugin__new (
null, 'im_component_plugin', now(), null, null, null,
'Revenue by Department', -- plugin_name
'intranet-reporting-dashboard', -- package_name
'left', -- location
'/intranet-invoices/dashboard', -- page_url
null, -- view_name
120, -- sort_order
'im_dashboard_revenue_by_dept -diagram_width 600 -diagram_height 500',
'lang::message::lookup "" intranet-reporting-dashboard.Revenue_by_Department "Revenue by Department"'
);
SELECT acs_permission__grant_permission(
(select plugin_id from im_component_plugins where plugin_name = 'Revenue by Department'),
(select group_id from groups where group_name = 'Senior Managers'),
'read'
);
......@@ -872,3 +872,35 @@ ad_proc -public im_dashboard_project_eva {
return [string trim $result]
}
# ---------------------------------------------------------------
# Revenues by department
# ---------------------------------------------------------------
ad_proc -public im_dashboard_revenue_by_dept {
{-diagram_width 600}
{-diagram_height 500}
} {
Returns a HTML component with a timeline of a revenues
by department.
} {
# Sencha check and permissions
if {![im_sencha_extjs_installed_p]} { return "" }
set current_user_id [ad_conn user_id]
if {![im_permission $current_user_id view_finance]} { return "You don't have the right to see financial data" }
im_sencha_extjs_load_libraries
# Call the portlet page
set params [list \
[list diagram_width $diagram_width] \
[list diagram_height $diagram_height] \
]
set result [ad_parse_template -params $params "/packages/intranet-reporting-dashboard/lib/revenue-by-dept"]
return [string trim $result]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment