Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
I
intranet-reporting-dashboard
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
project-open
intranet-reporting-dashboard
Commits
2c3048c4
Commit
2c3048c4
authored
Dec 07, 2020
by
Frank Bergmann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- Started to implement project-phases-volume indicator
parent
fe89ad2a
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
313 additions
and
0 deletions
+313
-0
project-phases-volume.adp
lib/project-phases-volume.adp
+130
-0
project-phases-volume.tcl
lib/project-phases-volume.tcl
+31
-0
intranet-reporting-dashboard-create.sql
sql/postgresql/intranet-reporting-dashboard-create.sql
+21
-0
intranet-reporting-dashboard-procs.tcl
tcl/intranet-reporting-dashboard-procs.tcl
+32
-0
project-phases-volume.json.tcl
www/project-phases-volume.json.tcl
+99
-0
No files found.
lib/project-phases-volume.adp
0 → 100644
View file @
2c3048c4
<div id=@diagram_id@></div>
<script type='text/javascript' <if @::__csp_nonce@ not nil>nonce="@::__csp_nonce;literal@"</if>>
Ext.require(['Ext.chart.*', 'Ext.Window', 'Ext.fx.target.Sprite', 'Ext.layout.container.Fit']);
Ext.onReady(function () {
projectPhasesStore = Ext.create('Ext.data.Store', {
fields: ['date', 'planned_ts_value', 'total_planned_ts_value', 'timesheet', 'invoice', 'quote', 'po'],
autoLoad: true,
proxy: {
type: 'rest',
url: '/intranet-reporting-dashboard/project-eva.json',
extraParams: { // Parameters to the data-source
diagram_project_id: @diagram_project_id@ // Number of customers to show
},
reader: { type: 'json', root: 'data' }
}
});
projectEvaChart = new Ext.chart.Chart({
animate: false,
store: projectPhasesStore,
legend: { position: 'right' },
insetPadding: 20,
theme: 'Base:gradients',
axes: [{
type: 'Numeric',
minimum: 0,
position: 'left',
fields: [
'planned_ts_value',
'invoice',
'quote',
'po',
'timesheet'
]
}, {
type: 'Time',
position: 'bottom',
fields: 'date',
dateFormat: 'M d'
}],
series: [{
// Planned value composed of planned timesheet plus POs (purchase orders - external costs)
type: 'area',
axis: 'left',
xField: 'date',
yField: ['planned_ts_value', 'po'],
highlight: true
}, {
// Horizontal line for total planned value
type: 'line',
title: '@axis_title_total_planned_ts_value_l10n@',
axis: 'left',
xField: 'date',
yField: 'total_planned_ts_value',
showMarkers: false,
style: { fill: '#FF0000', stroke: '#FF0000', 'stroke-width': 1 }
}, {
// Invoices
type: 'line',
title: '@axis_title_invoices_l10n@',
axis: 'left',
xField: 'date',
yField: 'invoice',
showMarkers: false,
style: { stroke: '#@invoice_color@', 'stroke-width': 1 }
}, {
// Quotes
type: 'line',
title: '@axis_title_quotes_l10n@',
axis: 'left',
xField: 'date',
yField: 'quote',
showMarkers: false,
style: { stroke: '#@quote_color@', 'stroke-width': 1 }
}, {
// Actual costs area chart
type: 'area',
axis: 'left',
xField: 'date',
yField: ['timesheet', 'bills', 'expbundle'],
showMarkers: false,
tips: {
trackMouse: false,
renderer: function(storeItem, item) {
this.setTitle(storeItem.get('date'));
this.update(storeItem.get('total_planned_ts_value'));
}
},
style: {
fill: '#FF0000',
stroke: '#FF0000',
'stroke-width': 1
}
}]
});
var projectEvaPanel = Ext.create('widget.panel', {
width: @diagram_width@,
height: @diagram_height@,
title: '@diagram_title@',
renderTo: '@diagram_id@',
layout: 'fit',
header: false,
tbar: [{
xtype: 'combo',
editable: false,
store: false,
mode: 'local',
displayField: 'display',
valueField: 'value',
triggerAction: 'all',
width: 150,
forceSelection: true,
value: 'all_time',
listeners:{select:{fn:function(combo, comboValues) {
var value = comboValues[0].data.value;
var extraParams = projectPhasesStore.getProxy().extraParams;
extraParams.diagram_interval = value;
projectPhasesStore.load();
}
}
}
}],
items: projectEvaChart
});
});
</script>
lib/project-phases-volume.tcl
0 → 100644
View file @
2c3048c4
# /packages/intranet-reporting-dashboard/lib/project-phases-volume.tcl
#
# Copyright (C
)
2014
]
project-open
[
#
# All rights reserved. Please check
# http://www.project-open.com/license/ for details.
# ----------------------------------------------------------------------
# Variables
# ---------------------------------------------------------------------
# The following variables are expected in the environment
# defined by the calling /tcl/*.tcl libary:
if
{
!
[
info
exists diagram_width
]}
{
set diagram_width 600
}
if
{
!
[
info
exists diagram_height
]}
{
set diagram_height 400
}
if
{
!
[
info
exists diagram_title
]}
{
set diagram_title
[
lang::message::lookup
""
intranet-reporting-dashboard.Project_Phases_Volume
"Volume of Project Phases"
]
}
# Create a random ID for the diagram
set
diagram_rand
[
expr
{
round
(
rand
()
* 100000000.0
)}]
set
diagram_id
"project_phases_volume_
$diagram
_rand"
set
default_currency
[
im_parameter -package_id
[
im_package_cost_id
]
"DefaultCurrency"
""
"EUR"
]
# ----------------------------------------------------------------------
# Calculate Diagram Parameters
# ---------------------------------------------------------------------
db_1row project_info
"
select 1
"
sql/postgresql/intranet-reporting-dashboard-create.sql
View file @
2c3048c4
...
...
@@ -573,3 +573,24 @@ SELECT acs_permission__grant_permission(
'read'
);
-- Revenues by year over months
--
SELECT
im_component_plugin__new
(
null
,
'im_component_plugin'
,
now
(),
null
,
null
,
null
,
'Volume of Project Phases'
,
-- plugin_name
'intranet-reporting-dashboard'
,
-- package_name
'top'
,
-- location
'/intranet-invoices/dashboard'
,
-- page_url
null
,
-- view_name
10
,
-- sort_order
'im_dashboard_project_phases_volume -diagram_width 600 -diagram_height 500'
,
'lang::message::lookup "" intranet-reporting-dashboard.Project_Phases_Volume "Volume of Project Phases"'
);
SELECT
acs_permission__grant_permission
(
(
select
plugin_id
from
im_component_plugins
where
plugin_name
=
'Volume of Project Phases'
),
(
select
group_id
from
groups
where
group_name
=
'Senior Managers'
),
'read'
);
tcl/intranet-reporting-dashboard-procs.tcl
View file @
2c3048c4
...
...
@@ -950,3 +950,35 @@ ad_proc -public im_dashboard_revenue_by_year_monthly {
# ---------------------------------------------------------------
# Revenues by month over year
# ---------------------------------------------------------------
ad_proc -public im_dashboard_project_phases_volume
{
{
-diagram_width 600
}
{
-diagram_height 500
}
{
-diagram_title
""
}
}
{
Returns a HTML component with a diagram of project volumes per phase
}
{
# 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
]
\
[
list
diagram_title
$diagram
_title
]
\
]
set result
[
ad_parse_template -params
$params
"/packages/intranet-reporting-dashboard/lib/project-phases-volume"
]
return
[
string
trim
$result
]
}
www/project-phases-volume.json.tcl
0 → 100644
View file @
2c3048c4
# /packages/intranet-reporting-dashboard/www/project-phases-volume.tcl
#
# Copyright (C
)
2014
]
project-open
[
#
# All rights reserved. Please check
# http://www.project-open.com/license/ for details.
ad_page_contract
{
Datasource for top-customers Sencha pie chart.
}
{
}
# ----------------------------------------------------
# Defaults & Permissions
# ----------------------------------------------------
set
current_user_id
[
ad_conn user_id
]
if
{
!
[
im_permission
$current
_user_id view_finance
]}
{
set json
"{
\"
success
\"
: false,
\"
message
\"
:
\"
Insufficient permissions - you need the view_finance privilege to see this page.
\"
}"
doc_return 400
"application/json"
$json
ad_script_abort
}
set
default_currency
[
im_parameter -package_id
[
im_package_cost_id
]
"DefaultCurrency"
""
"EUR"
]
set
default_hourly_cost
[
im_parameter -package_id
[
im_package_cost_id
]
"DefaultTimesheetHourlyCost"
""
30
]
set
message
"Data loaded"
# ----------------------------------------------------
# Calculate diagram data
# ----------------------------------------------------
set
sql
"
select main_p.project_id as project_id,
main_p.project_name as project_name,
main_p.project_status_id,
-- Presales Opportunities
main_p.presales_value,
main_p.presales_probability,
-- Planned Hours
(
select sum(coalesce(t.planned_units,0))
from im_projects p,
im_timesheet_tasks t
where p.project_id = t.task_id and
p.tree_sortkey between main_p.tree_sortkey and tree_right(main_p.tree_sortkey) and
not exists (select project_id from im_projects leaf_p where leaf_p.parent_id = p.project_id)
) as planned_hours,
-- Value of planned hours
round((
select sum(coalesce(planned_units, 0) * coalesce(sum_hourly_rate, :default_hourly_cost::float) / (coalesce(sum_percentage)+0.00000001))
from (
select planned_units,
(
select sum(coalesce(bom.percentage, 100::numeric) * coalesce(e.hourly_cost, :default_hourly_cost::numeric))
from im_employees e,
acs_rels r,
im_biz_object_members bom
where r.object_id_one = p.project_id and
r.object_id_two = e.employee_id and
r.rel_id = bom.rel_id
) as sum_hourly_rate,
(
select sum(coalesce(bom.percentage, 100::numeric))
from acs_rels r,
im_biz_object_members bom
where r.object_id_one = p.project_id and
r.rel_id = bom.rel_id
) as sum_percentage
from im_projects p,
im_timesheet_tasks t
where p.project_id = t.task_id and
p.tree_sortkey between main_p.tree_sortkey and tree_right(main_p.tree_sortkey) and
not exists (select project_id from im_projects leaf_p where leaf_p.parent_id = p.project_id)
) t
)::numeric, 2) as planned_hours_value
from im_projects main_p
where main_p.parent_id is null and
main_p.project_status_id not in (
[
im_project_status_deleted
]
)
"
ad_return_complaint 1
[
im_ad_hoc_query -format html
$sql
]
# ----------------------------------------------------
# Format and return the data
# ----------------------------------------------------
set
json
[
im_sencha_sql_to_store -include_empty_p 0 -data_source_p 1 -sql
$sql
]
doc_return 200
"application/json"
$json
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment