Commit d0622c20 authored by Frank Bergmann's avatar Frank Bergmann

Initial Import

parents
<?xml version="1.0"?>
<!-- Generated by the OpenACS Package Manager -->
<package key="intranet-trans-project-feedback" url="http://openacs.org/repository/apm/packages/intranet-trans-project-feedback" type="apm_application">
<package-name>]project-open[ Translation Project Feedback</package-name>
<pretty-plural>]project-open[ Translation Project Feedback</pretty-plural>
<initial-install-p>f</initial-install-p>
<singleton-p>t</singleton-p>
<implements-subsite-p>f</implements-subsite-p>
<inherit-templates-p>t</inherit-templates-p>
<auto-mount>intranet-trans-project-feedback</auto-mount>
<version name="0.1d" url="http://openacs.org/repository/download/apm/intranet-trans-project-feedback-0.1d.apm">
<owner url="mailto:klaus.hofeditz@project-open.com">System Administrator</owner>
<owner>mailto:frank.bergmann@project-open.com</owner>
<summary>Managing and evaluate feedback on Translation Projects</summary>
<vendor url="www.project-open.com">Project Open Business Solutions S.L.</vendor>
<description format="text/html">Provides a portlet to track feedback on Translation Projects plus some graphs and reports </description>
<maturity>0</maturity>
<provides url="intranet-trans-project-feedback" version="0.1d"/>
<callbacks>
</callbacks>
<parameters>
<!-- No version parameters -->
</parameters>
</version>
</package>
<if @report_code_found_p@>
<div id=@diagram_id@></div>
<script type='text/javascript'>
Ext.require(['Ext.chart.*', 'Ext.Window', 'Ext.fx.target.Sprite', 'Ext.layout.container.Fit']);
Ext.onReady(function () {
// ////////////////////////////////////////////////
// STORES
//
var translationProjectFeedbackNonComformityStore = Ext.create('Ext.data.Store', {
fields: [
{ name: 'first_day_period', type: 'string'},
{ name: 'number_projects', type: 'int'},
{ name: 'number_projects_non_conform', type: 'int'},
{ name: 'percentage_non_conform', type: 'int'}
],
autoLoad: true,
proxy: {
type: 'rest',
url: '/intranet-reporting/view', // This is the generic ]po[ REST interface
extraParams: {
format: 'json', // Ask for data in JSON format
limit: @diagram_limit@, // Limit the number of returned rows
report_code: '@diagram_report_code@', // The code of the data-source to retreive
start_date: '@start_date@',
end_date: '@end_date@',
period: '@period@'
},
reader: { type: 'json', root: 'data' } // Standard reader: Data are prefixed by "data".
}
});
var translationProjectFeedbackNonComformityProportionStore = Ext.create('Ext.data.Store', {
fields: [
{ name: 'choice', type: 'string' },
{ name: 'count', type: 'int'}
],
autoLoad: true,
proxy: {
type: 'rest',
url: '/intranet-reporting/view', // This is the generic ]po[ REST interface
extraParams: {
format: 'json', // Ask for data in JSON format
limit: @diagram_limit@, // Limit the number of returned rows
report_code: '@diagram_report_code@', // The code of the data-source to retreive
start_date: '@start_date@',
end_date: '@end_date@',
period: '@period@'
},
reader: { type: 'json', root: 'data' } // Standard reader: Data are prefixed by "data".
}
});
// ////////////////////////////////////////////////
// CHART TYPES
//
<if @chart_type@ eq "column_chart">
var ticketAgingChart = new Ext.chart.Chart({
xtype: 'chart',
width: @diagram_width@,
height: @diagram_height@,
title: '@diagram_title@',
renderTo: '@diagram_id@',
layout: 'fit',
animate: true,
shador: true,
store: @store@,
insetPadding: @diagram_inset_padding@,
// theme: '@diagram_theme@',
axes: [{
type: 'category',
position: 'bottom',
fields: ['first_day_period'],
label: { font: '@diagram_font@' },
// title: 'Number of tickets',
grid: false,
minimum: 0
}, {
type: 'Numeric',
position: 'left',
fields: ['number_projects'],
label: { font: '@diagram_font@' },
// title: 'Age of tickets (days)',
minimum: 0
}],
series: [{
type: 'column',
axis: 'left',
title: [ 'Total Projects', 'Projects not conform'],
xField: 'first_day_period',
yField: [ 'number_projects', 'number_projects_non_conform' ],
style: {
opacity: 0.80
},
tips: {
trackMouse: false,
width: @diagram_tooltip_width@,
height: @diagram_tooltip_height@
}
}],
legend: {
position: 'right',
labelFont: '@diagram_font@'
}
});
</if>
<elseif @chart_type@ eq "pie_chart">
chart = new Ext.chart.Chart({
width: @diagram_width@,
height: @diagram_height@,
animate: true,
store: @store@,
renderTo: '@diagram_id@',
shadow: true,
legend: {
position: 'right'
},
insetPadding: 25,
theme: 'Base:gradients',
series: [{
type: 'pie',
field: 'count',
showInLegend: true,
highlight: {
segment: {
margin: 20
}
},
label: {
field: 'choice',
display: 'rotate',
contrast: true,
font: '11px "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif',
renderer: function(val, label, storeItem, item, i, display, animate, index) {
var sumNonComformityProjects = translationProjectFeedbackNonComformityProportionStore.sum('count');
// console.log('sumNonComformityProjects:' + sumNonComformityProjects);
// console.log('val:' + val);
// console.log('count:' + storeItem.get('count'));
var ret = (parseFloat(storeItem.get('count') / sumNonComformityProjects) * 100.0).toFixed(2) + '%';
return ret + ' ' + val.substring(0,20);
}
},
animate: true
}]
});
</elseif>
<elseif @chart_type@ eq "line_chart">
chart = new Ext.chart.Chart({
renderTo: @diagram_id@,
width: @diagram_width@,
height: @diagram_height@,
animate: true,
store: @store@,
shadow: true,
theme: 'Category1',
legend: {
position: 'right'
},
axes: [{
type: 'Numeric',
minimum: 0,
position: 'left',
fields: ['percentage_non_conform'],
// title: 'Number of Hits',
grid: {
odd: {
opacity: 1,
fill: '#ddd',
stroke: '#bbb',
'stroke-width': 0.5
}
}
}, {
type: 'Category',
position: 'bottom',
fields: ['first_day_period'],
label: { font: '@diagram_font@' },
// title: ''
}],
series: [{
type: 'line',
highlight: {
size: 7,
radius: 7
},
axis: 'left',
xField: 'first_day_period',
yField: 'percentage_non_conform',
label: {
display: 'under',
field: 'percentage_non_conform',
minMargin: 200,
padding: 30,
font: '16px Helvetica, sans-serif',
renderer: function(val, label, storeItem, item, i, display, animate, index) {
return storeItem.get('percentage_non_conform') + '%';
}
}
}]
});
</elseif>
});
</script>
</if>
<else>
<%=[lang::message::lookup "" intranet-trans-project-feedback.CodeNotFound "No DataSource found for title: '$title', please check your Portlet Parameters"]%>
</else>
# /packages/intranet-trans-project-feedback/www/graph-panel.tcl
#
# Copyright (C) 2015 Project Open Business Solutions S.L.
#
# This program is free software. You can redistribute it
# and/or modify it under the terms of the GNU General
# Public License as published by the Free Software Foundation;
# either version 2 of the License, or (at your option)
# any later version. This program is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
# Profiles represent OpenACS groups used by ]project-open[
# However, for performance reasons we have introduced special
# caching and auxillary functions specific to ]po[.
# @author klaus.hofeditz@project-open.com
# ---------------------------------------------------------------------------
# DEFAULTS & PERMISSIONS
# ---------------------------------------------------------------------------
# Provided:
# title
# start_date
# end_date
# period
set current_url [ns_conn url]
set current_user_id [ad_maybe_redirect_for_registration]
set package_url "/simple-survey"
set report_code_found_p 1
if ![info exists return_url] { set return_url "/intranet-trans-project-feedback/dashboard" }
# Set Report Code
switch $title {
"Non Comformity" {
set store "translationProjectFeedbackNonComformityStore"
set chart_type "column_chart"
set diagram_report_code "translation_project_feedback_non_comformity"
if {![info exists diagram_width] || "" == $diagram_width} { set diagram_width 600 }
if {![info exists diagram_height] || "" == $diagram_height } { set diagram_height 350 }
if {![info exists diagram_font] || "" == $diagram_font} { set diagram_font "10px Helvetica, sans-serif" }
if {![info exists diagram_theme] || "" == $diagram_theme} { set diagram_theme "Custom" }
if {![info exists diagram_limit] || "" == $diagram_limit} { set diagram_limit 100 }
if {![info exists diagram_inset_padding] || "" == $diagram_inset_padding} { set diagram_inset_padding 5 }
if {![info exists diagram_tooltip_width] || "" == $diagram_tooltip_width} { set diagram_tooltip_width 230 }
if {![info exists diagram_tooltip_height] || "" == $diagram_tooltip_height} { set diagram_tooltip_height 20 }
if {![info exists diagram_legend_width] || "" == $diagram_legend_width} { set diagram_legend_width 150 }
if {![info exists diagram_title] || "" == $diagram_title} { set diagram_title [lang::message::lookup "" intranet-trans-project-feedback.$title $title] }
set diagram_id "translation_project_feedback_non_comformity"
}
"Non-Comformity - Proportions" {
set store "translationProjectFeedbackNonComformityProportionStore"
set chart_type "pie_chart"
set diagram_report_code "translation_project_feedback_non_comformity_proportions"
if {![info exists diagram_limit] || "" == $diagram_limit} { set diagram_limit 100 }
if {![info exists diagram_width] || "" == $diagram_width} { set diagram_width 800 }
if {![info exists diagram_height] || "" == $diagram_height } { set diagram_height 350 }
set diagram_id "translation_project_feedback_non_comformity_proportions"
}
"Conformity vs Non-Comformity" {
if {![info exists diagram_font] || "" == $diagram_font} { set diagram_font "10px Helvetica, sans-serif" }
set store "translationProjectFeedbackNonComformityStore"
set chart_type "line_chart"
set diagram_report_code "translation_project_feedback_non_comformity"
if {![info exists diagram_limit] || "" == $diagram_limit} { set diagram_limit 100 }
if {![info exists diagram_width] || "" == $diagram_width} { set diagram_width 600 }
if {![info exists diagram_height] || "" == $diagram_height } { set diagram_height 350 }
set diagram_id "translation_project_feedback_comformity_vs_non_comformity"
}
default {
set report_code_found_p 0
}
}
# ---------------------------------------------------------------------------
# Loading ExtJS libs
im_sencha_extjs_load_libraries
<form action="/intranet-trans-project-feedback/process-response" method="POST">
<input type="hidden" name="survey_id" value="@survey_id@" />
<input type="hidden" name="return_url" value="@return_url@" />
<input type="hidden" name="related_object_id" value="@project_id@" />
<input type="hidden" name="related_context_id" value="@current_user_id@" />
@html;noquote@
<input type="submit" value="@button_label@">
</form>
# /packages/intranet-trans-project-feedback/lib/survey-component.tcl
#
# Copyright (C) 2015 Project Open Business Solutions S.L.
#
# This program is free software. You can redistribute it
# and/or modify it under the terms of the GNU General
# Public License as published by the Free Software Foundation;
# either version 2 of the License, or (at your option)
# any later version. This program is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
# Profiles represent OpenACS groups used by ]project-open[
# However, for performance reasons we have introduced special
# caching and auxillary functions specific to ]po[.
# @author klaus.hofeditz@project-open.com
# @author philg@mit.edu
# @author nstrug@arsdigita.com
# ---------------------------------------------------------------------------
# DEFAULTS & PERMISSIONS
# ---------------------------------------------------------------------------
set current_url [ns_conn url]
set current_user_id [ad_maybe_redirect_for_registration]
set package_url "/simple-survey"
if { ![info exists return_url] || ""==$return_url } { set return_url "/intranet/projects/view?project_id=$project_id" }
im_project_permissions $current_user_id $project_id view read write admin
if {!$read} { return "" }
set survey_id [db_string get_data "select survey_id from survsimp_surveys where name = 'Project Translation Feedback'" -default 0]
if { 0 == $survey_id } {return [lang::message::lookup "" intranet-trans-project-feedback.SurveyNotFound "Survey 'Project Translation Feedback' not found"] }
# ad_require_permission $survey_id survsimp_take_survey
# ---------------------------------------------------------------------------
# Show Survey
# ---------------------------------------------------------------------------
db_1row survey_info "
select
name,
description,
single_response_p,
single_editable_p,
display_type
from
survsimp_surveys
where
survey_id = :survey_id"
set context [list [list "./" "Surveys"] "$name"]
set num_responses [db_string responses_count {
select count(response_id)
from survsimp_responses, acs_objects
where response_id = object_id
and survey_id = :survey_id
}]
if {$single_response_p == "t"} {
if {$num_responses == "0"} {
set button_label "Submit response"
set edit_previous_response_p "f"
} else {
set button_label "Modify submited response"
set edit_previous_response_p "t"
}
set previous_responses_link ""
} else {
set button_label "Submit response"
set edit_previous_response_p "f"
if {$num_responses == "0"} {
set previous_response_p "f"
} else {
set previous_response_p "t"
}
}
if {$single_response_p == "t" && $single_editable_p == "f"} {
set modification_allowed_p "f"
} else {
set modification_allowed_p "t"
}
# build a list containing the HTML (generated with survsimp_question_display) for each question
set rownum 0
set questions [list]
db_foreach question_ids_select {
select question_id
from survsimp_questions
where survey_id = :survey_id
and active_p = 't'
order by sort_key
} {
append html "[survsimp_question_display_trans_feedback $question_id $project_id $edit_previous_response_p]<br/><br/>"
}
-- /packages/intranet-trans-project-feedback/sql/postgres/intranet-trans-project-feedback-create.sql
--
-- Copyright (C) 2011-2015 ]project-open[
--
-- This program is free software. You can redistribute it
-- and/or modify it under the terms of the GNU General
-- Public License as published by the Free Software Foundation;
-- either version 2 of the License, or (at your option)
-- any later version. This program is distributed in the
-- hope that it will be useful, but WITHOUT ANY WARRANTY;
-- without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU General Public License for more details.
--
-- @author klaus.hofeditz@project-open.com
-- Create table for inquiries
CREATE OR REPLACE FUNCTION inline_0 ()
RETURNS INTEGER AS $BODY$
declare
v_count integer;
v_package_id integer;
v_survey_id integer;
begin
select count(*) into v_count from survsimp_surveys where name = 'Project Translation Feedback';
IF 0 = v_count THEN
-- Get package id of package intranet-employee-evaluation
select package_id into v_package_id from apm_packages where package_key = 'simple-survey';
select survsimp_survey__new (
null,
'Project Translation Feedback',
'Project Translation Feedback',
'',
'f', -- description_html_p
't', -- single_response_p
't', -- single_editable_p
't', -- enabled_p
'general', -- type
'list', -- display_type,
624,
v_package_id
) into v_survey_id;
END IF;
return 0;
end;$BODY$ LANGUAGE 'plpgsql';
SELECT inline_0 ();
DROP FUNCTION inline_0 ();
CREATE OR REPLACE FUNCTION inline_0 ()
RETURNS INTEGER AS $BODY$
declare
v_count integer;
v_survey_id integer;
v_next_choice_id integer;
v_question_id integer;
begin
select survey_id into v_survey_id from survsimp_surveys where name = 'Project Translation Feedback';
select acs_object__new (null, 'survsimp_question') into v_question_id;
insert into survsimp_questions(question_id, survey_id, sort_key, question_text, abstract_data_type, required_p, active_p, presentation_type, presentation_options, presentation_alignment)
values (
v_question_id,
v_survey_id,
100, --new__sort_key
'Type', --new__question_text
'choice', --new__abstract_data_type (e.g. choice, text)
'f', --new__required_p
't', --new__active_p
'select', --new__presentation_type
'', --new__presentation_options
'below' --new__presentation_alignment
);
select survsimp_choice_id_sequence.nextval into v_next_choice_id from dual;
insert into survsimp_question_choices (choice_id, question_id, label, sort_order) values (v_next_choice_id, v_question_id, 'CC - Client Complaint' ,1);
select survsimp_choice_id_sequence.nextval into v_next_choice_id from dual;
insert into survsimp_question_choices (choice_id, question_id, label, sort_order) values (v_next_choice_id, v_question_id, 'NC - Issue but no client complaint' ,2);
select survsimp_choice_id_sequence.nextval into v_next_choice_id from dual;
insert into survsimp_question_choices (choice_id, question_id, label, sort_order) values (v_next_choice_id, v_question_id, 'YAY - No issue' ,3);
return 0;
end;$BODY$ LANGUAGE 'plpgsql';
SELECT inline_0 ();
DROP FUNCTION inline_0 ();
CREATE OR REPLACE FUNCTION inline_0 ()
RETURNS INTEGER AS $BODY$
declare
v_count integer;
v_survey_id integer;
v_next_choice_id integer;
v_question_id integer;
begin
select survey_id into v_survey_id from survsimp_surveys where name = 'Project Translation Feedback';
select acs_object__new (null, 'survsimp_question') into v_question_id;
insert into survsimp_questions(question_id, survey_id, sort_key, question_text, abstract_data_type, required_p, active_p, presentation_type, presentation_options, presentation_alignment)
values (
v_question_id,
v_survey_id,
200, --new__sort_key,
'Sub Type', --new__question_text,
'choice', --new__abstract_data_type (e.g. choice, text)
'f', --new__required_p,
't', --new__active_p,
'select', --new__presentation_type,
'', --new__presentation_options,
'below' --new__presentation_alignment
);
select survsimp_choice_id_sequence.nextval into v_next_choice_id from dual;
insert into survsimp_question_choices (choice_id, question_id, label, sort_order) values (v_next_choice_id, v_question_id, 'TC - Issue with translator delivery resulting in late client delivery' ,1);
select survsimp_choice_id_sequence.nextval into v_next_choice_id from dual;
insert into survsimp_question_choices (choice_id, question_id, label, sort_order) values (v_next_choice_id, v_question_id, 'LIH - Late Inhouse. Late delivery due to inhouse issues' ,2);
select survsimp_choice_id_sequence.nextval into v_next_choice_id from dual;
insert into survsimp_question_choices (choice_id, question_id, label, sort_order) values (v_next_choice_id, v_question_id, 'IHP - Inhouse proofreading issues (typos, numbers, etc.)' ,3);
select survsimp_choice_id_sequence.nextval into v_next_choice_id from dual;
insert into survsimp_question_choices (choice_id, question_id, label, sort_order) values (v_next_choice_id, v_question_id, 'TTI - Translator Terminology inaccurate, text does not read well in target Language' ,4);
return 0;
end;$BODY$ LANGUAGE 'plpgsql';
SELECT inline_0 ();
DROP FUNCTION inline_0 ();
CREATE OR REPLACE FUNCTION inline_0 ()
RETURNS INTEGER AS $BODY$
declare
v_count integer;
v_survey_id integer;
v_question_id integer;
begin
select survey_id into v_survey_id from survsimp_surveys where name = 'Project Translation Feedback';
select acs_object__new (null, 'survsimp_question') into v_question_id;
insert into survsimp_questions(question_id, survey_id, sort_key, question_text, abstract_data_type, required_p, active_p, presentation_type, presentation_options, presentation_alignment)
values (
v_question_id,
v_survey_id,
300, --new__sort_key,
'Corrective Action', --new__question_text,
'text', --new__abstract_data_type (e.g. choice, text)
'f', --new__required_p,
't', --new__active_p,
'textarea', --new__presentation_type,
'', --new__presentation_options,
'below' --new__presentation_alignment
);
return 0;
end;$BODY$ LANGUAGE 'plpgsql';
SELECT inline_0 ();
DROP FUNCTION inline_0 ();
CREATE OR REPLACE FUNCTION inline_0 ()
RETURNS INTEGER AS $BODY$
declare
v_count integer;
v_survey_id integer;
v_question_id integer;
begin
select survey_id into v_survey_id from survsimp_surveys where name = 'Project Translation Feedback';
select acs_object__new (null, 'survsimp_question') into v_question_id;
insert into survsimp_questions(question_id, survey_id, sort_key, question_text, abstract_data_type, required_p, active_p, presentation_type, presentation_options, presentation_alignment)
values (
v_question_id,
v_survey_id,
400, --new__sort_key,
'Preventive Action', --new__question_text,
'text', --new__abstract_data_type (e.g. choice, text)
'f', --new__required_p,
't', --new__active_p,
'textarea', --new__presentation_type,
'', --new__presentation_options,
'below' --new__presentation_alignment
);
return 0;
end;$BODY$ LANGUAGE 'plpgsql';
SELECT inline_0 ();
DROP FUNCTION inline_0 ();
-- END SURVEY ---------------------------------------------------------------------------------------------------------------
-- --------------------------------------------------------------------------------------------------------------------------
-- Portlet Components
-- --------------------------------------------------------------------------------------------------------------------------
-- Feedback on Project Page
CREATE OR REPLACE FUNCTION inline_0 ()
RETURNS INTEGER AS $BODY$
declare
v_plugin_id integer;
v_employees integer;
begin
-- Groups
select group_id into v_employees from groups where group_name = 'Employees';
-- Plugins
SELECT im_component_plugin__new (
null, -- plugin_id
'im_component_plugin', -- object_type
now(), -- creation_date
null, -- creation_user
null, -- creation_ip
null, -- context_id
'Project Translation Feedback', -- plugin_name
'intranet-trans-project-feedback', -- package_name
'left', -- location
'/intranet/projects/view', -- page_url
null, -- view_name
200, -- sort_order
'im_project_translation_feedback_questions_component $project_id',
'lang::message::lookup "" intranet-trans-project-feedback.ProjectTranslationFeedback "Project Translation Feedback"'
into v_plugin_id);
PERFORM im_grant_permission(v_plugin_id, v_employees, 'read');
return 0;
end;$BODY$ LANGUAGE 'plpgsql';
SELECT inline_0 ();
DROP FUNCTION inline_0 ();
-- GRAPHS: Non-Comformity
CREATE OR REPLACE FUNCTION inline_0 ()
RETURNS INTEGER AS $BODY$
declare
v_plugin_id integer;
v_employees integer;
begin
-- Groups
select group_id into v_employees from groups where group_name = 'Employees';
-- Plugins
SELECT im_component_plugin__new (
null, -- plugin_id
'im_component_plugin', -- object_type
now(), -- creation_date
null, -- creation_user
null, -- creation_ip
null, -- context_id
'Non-Comformity', -- plugin_name
'intranet-trans-project-feedback', -- package_name
'left', -- location
'/intranet-trans-project-feedback/dashboard', -- page_url
null, -- view_name
200, -- sort_order
'im_project_translation_graph_panel "Non Comformity" "Column" $start_date $end_date $period',
'lang::message::lookup "" intranet-trans-project-feedback.NonComformity "Non-Comformity"'
into v_plugin_id);
PERFORM im_grant_permission(v_plugin_id, v_employees, 'read');
return 0;
end;$BODY$ LANGUAGE 'plpgsql';
SELECT inline_0 ();
DROP FUNCTION inline_0 ();
-- Non-Comformity - Proportions
CREATE OR REPLACE FUNCTION inline_0 ()
RETURNS INTEGER AS $BODY$
declare
v_plugin_id integer;
v_employees integer;
begin
-- Groups
select group_id into v_employees from groups where group_name = 'Employees';
-- Plugins
SELECT im_component_plugin__new (
null, -- plugin_id
'im_component_plugin', -- object_type
now(), -- creation_date
null, -- creation_user
null, -- creation_ip
null, -- context_id
'Non-Comformity - Proportions', -- plugin_name
'intranet-trans-project-feedback', -- package_name
'left', -- location
'/intranet-trans-project-feedback/dashboard', -- page_url
null, -- view_name
200, -- sort_order
'im_project_translation_graph_panel "Non Comformity - Proportions" $start_date $end_date $period',
'lang::message::lookup "" intranet-trans-project-feedback.NonComformityPercentage "Non-Comformity - Percentage"'
into v_plugin_id);
PERFORM im_grant_permission(v_plugin_id, v_employees, 'read');
return 0;
end;$BODY$ LANGUAGE 'plpgsql';
SELECT inline_0 ();
DROP FUNCTION inline_0 ();
-- Non-Comformity - Percentage
CREATE OR REPLACE FUNCTION inline_0 ()
RETURNS INTEGER AS $BODY$
declare
v_plugin_id integer;
v_employees integer;
begin
-- Groups
select group_id into v_employees from groups where group_name = 'Employees';
-- Plugins
SELECT im_component_plugin__new (
null, -- plugin_id
'im_component_plugin', -- object_type
now(), -- creation_date
null, -- creation_user
null, -- creation_ip
null, -- context_id
'Non-Comformity - Percentage', -- plugin_name
'intranet-trans-project-feedback', -- package_name
'left', -- location
'/intranet-trans-project-feedback/dashboard', -- page_url
null, -- view_name
200, -- sort_order
'im_project_translation_graph_panel "Non Comformity - Percentage" $start_date $end_date $period',
'lang::message::lookup "" intranet-trans-project-feedback.NonComformityPercentage "Non-Comformity - Percentage"'
into v_plugin_id);
PERFORM im_grant_permission(v_plugin_id, v_employees, 'read');
return 0;
end;$BODY$ LANGUAGE 'plpgsql';
SELECT inline_0 ();
DROP FUNCTION inline_0 ();
-- Non-Comformity - Type
CREATE OR REPLACE FUNCTION inline_0 ()
RETURNS INTEGER AS $BODY$
declare
v_plugin_id integer;
v_employees integer;
begin
-- Groups
select group_id into v_employees from groups where group_name = 'Employees';
-- Plugins
SELECT im_component_plugin__new (
null, -- plugin_id
'im_component_plugin', -- object_type
now(), -- creation_date
null, -- creation_user
null, -- creation_ip
null, -- context_id
'Comformity vs. Non-Comformity', -- plugin_name
'intranet-trans-project-feedback', -- package_name
'left', -- location
'/intranet-trans-project-feedback/dashboard', -- page_url
null, -- view_name
200, -- sort_order
'im_project_translation_graph_panel "Conformity vs Non-Comformity" $start_date $end_date $period',
'lang::message::lookup "" intranet-trans-project-feedback.NonComformityType "Non-Comformity - Type"'
into v_plugin_id);
PERFORM im_grant_permission(v_plugin_id, v_employees, 'read');
return 0;
end;$BODY$ LANGUAGE 'plpgsql';
SELECT inline_0 ();
DROP FUNCTION inline_0 ();
-- -----------------------------------------------------------------------------------------------------------------------
-- REST Data-Source for the report
-- -----------------------------------------------------------------------------------------------------------------------
-- Non-Comformity Main Report
create or replace function inline_0 ()
returns integer as $body$
DECLARE
v_id integer;
v_count integer;
v_report_id integer;
foo integer;
BEGIN
SELECT count(*) INTO v_count
FROM im_reports where report_code = 'translation_project_feedback_non_comformity';
IF v_count > 0 THEN return 1; END IF;
SELECT im_report_new (
'REST Non-Comformity', -- report_name
'translation_project_feedback_non_comformity', -- report_code
'intranet-trans-project-feedback', -- package_key
1000, -- report_sort_order
(select menu_id from im_menus where label = 'reporting-rest'), -- parent_menu_id
''
) into v_report_id;
update im_reports set report_description = 'Shows Total number of projects sampled vs. Projects with issues' where report_code = 'translation_project_feedback_non_comformity';
update
im_reports
set
report_sql = '
select
t._%period% as first_day_period,
sum(t.number_projects) as number_projects,
sum(t.number_projects_non_conform) as number_projects_non_conform,
CASE sum(t.number_projects) = 0
WHEN true THEN
0
ELSE
round((100 * sum(t.number_projects_non_conform)/sum(t.number_projects)))
END as percentage_non_conform
from (
select
s.project_start_date as _day,
to_char(s.project_start_date, ''YYYY-MM'') as _month,
to_char(s.project_start_date, ''YYYY-Q'') as _quarter,
to_char(s.project_start_date, ''YYYY'') as _year,
s.number_projects,
s.number_projects_non_conform
from (
select
im_day_enumerator as project_start_date,
(select
count(*)
from
im_projects
where
start_date::date = im_day_enumerator::date
and parent_id is null
) as number_projects,
(select count(*) from (
select distinct on (related_object_id)
r.related_object_id
from
im_projects p,
survsimp_responses r,
survsimp_question_responses qr,
survsimp_surveys s,
survsimp_questions q
where
s.name = ''Project Translation Feedback''
and r.survey_id = s.survey_id
and r.related_object_id = p.project_id
and r.response_id = qr.response_id
and q.survey_id = s.survey_id
and (q.question_text = ''Sub Type'' or q.question_text = ''Type'')
and q.question_id = qr.question_id
and qr.choice_id is not null
and p.start_date::date = im_day_enumerator::date
group by
r.related_object_id
) p) as number_projects_non_conform
from
im_day_enumerator(''%start_date%''::date, ''%end_date%''::date)
) s
) t
group by
t._%period%;
'
where
report_code = 'translation_project_feedback_non_comformity';
SELECT acs_permission__grant_permission( (select menu_id from im_menus where label = 'translation_project_feedback_non_comformity'), (select group_id from groups where group_name = 'Employees'), 'read') into foo;
return 0;
end;$body$ language 'plpgsql';
SELECT inline_0 ();
drop function inline_0 ();
-- Non-Comformity - Proportions
create or replace function inline_0 ()
returns integer as $body$
DECLARE
v_id integer;
v_count integer;
v_report_id integer;
foo integer;
BEGIN
SELECT count(*) INTO v_count
FROM im_reports where report_code = 'translation_project_feedback_non_comformity_proportions';
IF v_count > 0 THEN
RAISE NOTICE 'Report w/ code: translation_project_feedback_non_comformity_proportions already exists, skipped creation';
return 1;
END IF;
SELECT im_report_new (
'REST Non-Comformity (Proportions)', -- report_name
'translation_project_feedback_non_comformity_proportions', -- report_code
'intranet-trans-project-feedback', -- package_key
1000, -- report_sort_order
(select menu_id from im_menus where label = 'reporting-rest'), -- parent_menu_id
''
) into v_report_id;
update im_reports set report_description = 'Shows Total number of projects sampled vs. Projects with issues' where report_code = 'translation_project_feedback_non_comformity_proportions';
update
im_reports
set
report_sql = '
select
im_category_from_id(choice_id) as category,
count(*)
from
(
SELECT DISTINCT ON (related_object_id)
*
FROM survsimp_responses
ORDER BY related_object_id, response_id DESC
) r,
im_projects p,
survsimp_question_responses qr,
survsimp_surveys s,
survsimp_questions q
where
s.name = ''Project Translation Feedback''
and r.survey_id = s.survey_id
and r.related_object_id = p.project_id
and r.response_id = qr.response_id
and q.survey_id = s.survey_id
and (q.question_text = ''Sub Type'')
and q.question_id = qr.question_id
and qr.choice_id is not null
and p.start_date::date between ''%start_date%''::date and ''%end_date%''::date
and p.parent_id is null
group by
choice_id;
'
where
report_code = 'translation_project_feedback_non_comformity_proportions';
SELECT acs_permission__grant_permission( (select menu_id from im_menus where label = 'translation_project_feedback_non_comformity_proportions'), (select group_id from groups where group_name = 'Employees'), 'read') into foo;
return 0;
end;$body$ language 'plpgsql';
SELECT inline_0 ();
drop function inline_0 ();
-- /packages/intranet-trans-project-feedback/sql/postgres/intranet-trans-project-feedback-create.sql
--
-- Copyright (C) 2011-2015 ]project-open[
--
-- This program is free software. You can redistribute it
-- and/or modify it under the terms of the GNU General
-- Public License as published by the Free Software Foundation;
-- either version 2 of the License, or (at your option)
-- any later version. This program is distributed in the
-- hope that it will be useful, but WITHOUT ANY WARRANTY;
-- without even the implied warranty of MERCHANTABILITY or
-- FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU General Public License for more details.
--
-- @author klaus.hofeditz@project-open.com
CREATE OR REPLACE FUNCTION inline_0 ()
RETURNS INTEGER AS $BODY$
declare
v_count integer;
v_package_id integer;
v_survey_id integer;
r record;
foo integer;
begin
select survey_id into v_survey_id from survsimp_surveys where name = 'Project Translation Feedback';
FOR r IN select question_id from survsimp_questions where survey_id = v_survey_id
LOOP
-- rm response questions
delete from survsimp_question_responses where question_id = r.question_id;
-- rm questions
PERFORM survsimp_question__delete(r.question_id);
END LOOP;
-- rm response item
delete from survsimp_responses where survey_id = v_survey_id;
-- rm survey
delete from acs_object_context_index where ancestor_id = v_survey_id;
delete from acs_object_context_index where object_id = v_survey_id;
delete from acs_objects where context_id = v_survey_id;
PERFORM survsimp_survey__delete(v_survey_id);
return 0;
exception when others then
raise notice 'Unable to remove package:';
raise notice '% %', SQLERRM, SQLSTATE;
return 1;
end;$BODY$ LANGUAGE 'plpgsql';
SELECT inline_0 ();
DROP FUNCTION inline_0 ();
-- Delete REST reports
delete from im_reports where report_code = 'translation-project-feedback-non-comformity';
delete from im_reports where report_code = 'translation_project_feedback_non_comformity_proportions';
# /packages/intranet-trans-project-feedback/tcl/intranet-trans-project-feedback-procs.tcl
#
# Copyright (C) 2015 Project Open Business Solutions S.L.
#
# This program is free software. You can redistribute it
# and/or modify it under the terms of the GNU General
# Public License as published by the Free Software Foundation;
# either version 2 of the License, or (at your option)
# any later version. This program is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
# Profiles represent OpenACS groups used by ]project-open[
# However, for performance reasons we have introduced special
# caching and auxillary functions specific to ]po[.
# @author klaus.hofeditz@project-open.com
ad_proc -public im_project_translation_feedback_questions_component {
project_id
{ return_url "" }
} {
Returns a component showing the feedback questions
} {
set params [list \
[list project_id $project_id] \
[list return_url $return_url] \
]
return [string trim [ad_parse_template -params $params "/packages/intranet-trans-project-feedback/lib/survey-component"]]
}
ad_proc -public im_project_translation_graph_panel {
title
start_date
end_date
period
} {
Creates graphs used on Dashboard
} {
set params [list \
[list title $title] \
[list start_date $start_date] \
[list end_date $end_date] \
[list period $period] \
]
return [string trim [ad_parse_template -params $params "/packages/intranet-trans-project-feedback/lib/graph-panel"]]
}
proc_doc survsimp_question_display_trans_feedback {
question_id
related_object_id
{ edit_previous_response_p "f" }
} "
Customized version of simple-survey::survsimp_question_display
Ignores user - simple shows results of last responce collection
Returns a string of HTML to display for a question,
suitable for embedding in a form.
The form variable is of the form \"response_to_question.\$question_id
" {
set element_name "response_to_question.$question_id"
db_1row survsimp_question_properties "
select
survey_id,
sort_key,
question_text,
abstract_data_type,
required_p,
active_p,
presentation_type,
presentation_options,
presentation_alignment,
creation_user,
creation_date
from
survsimp_questions, acs_objects
where
object_id = question_id
and question_id = :question_id
"
set html $question_text
if { $presentation_alignment == "below" } {
append html "<br>"
} else {
append html " "
}
set user_value ""
if {$edit_previous_response_p == "t"} {
set user_id [ad_get_user_id]
set prev_response_query "
select
choice_id,
boolean_answer,
clob_answer,
number_answer,
varchar_answer,
date_answer,
attachment_file_name
from
survsimp_question_responses
where
question_id = :question_id
and response_id = (
select max(response_id)
from survsimp_responses r, survsimp_questions q, acs_objects
where q.question_id = :question_id
and object_id = r.survey_id
-- and creation_user = :user_id (CUST)
and q.survey_id = r.survey_id
and r.related_object_id = :related_object_id --(CUST)
)
"
set count 0
db_foreach survsimp_response $prev_response_query {
incr count
if {$presentation_type == "checkbox"} {
set selected_choices($choice_id) "t"
}
} if_no_rows {
set choice_id 0
set boolean_answer ""
set clob_answer ""
set number_answer ""
set varchar_answer ""
set date_answer ""
set attachment_file_name ""
}
}
switch -- $presentation_type {
"none" {
append html ""
}
"combined_type_one" {
# get all subquestions
if {[catch {
# Ignore question text
set html [create_html_combined_type_one $question_id]
} err_msg]} {
append html "Presentation type not supported, please install package \]po\[ Employee Evaluation"
ad_return_complaint xx $err_msg
}
}
"upload_file" {
if {$edit_previous_response_p == "t"} {
set user_value $attachment_file_name
}
append html "<input type=file name=$element_name $presentation_options>"
}
"textbox" {
if {$edit_previous_response_p == "t"} {
if {$abstract_data_type == "number" || $abstract_data_type == "integer"} {
set user_value $number_answer
} else {
set user_value $varchar_answer
}
}
append html "<input type=text name=$element_name value=\"[philg_quote_double_quotes $user_value]\" [ad_decode $presentation_options "large" "size=70" "medium" "size=40" "size=10"]>"
}
"textarea" {
if {$edit_previous_response_p == "t"} {
if {$abstract_data_type == "number" || $abstract_data_type == "integer"} {
set user_value $number_answer
} elseif { $abstract_data_type == "shorttext" } {
set user_value $varchar_answer
} else {
set user_value $clob_answer
}
}
append html "<textarea name=$element_name $presentation_options>$user_value</textarea>"
}
"date" {
if {$edit_previous_response_p == "t"} {
set user_value $date_answer
}
append html "[ad_dateentrywidget $element_name $user_value]"
}
"select" {
if { $abstract_data_type == "boolean" } {
if {$edit_previous_response_p == "t"} {
set user_value $boolean_answer
}
append html "
<select name=$element_name>
<option value=\"\">[lang::message::lookup "" simple-survey.Select_One "Select One"]</option>
<option value=\"t\" [ad_decode $user_value "t" "selected" ""]>True</option>
<option value=\"f\" [ad_decode $user_value "f" "selected" ""]>False</option>
</select>
"
} else {
if {$edit_previous_response_p == "t"} {
set user_value $choice_id
}
append html "
<select name=$element_name>
<option value=\"\">[lang::message::lookup "" simple-survey.Select_One "Select One"]</option>
"
db_foreach survsimp_question_choices "
select choice_id, label
from survsimp_question_choices
where question_id = :question_id
order by sort_order
" {
if { $user_value == $choice_id } {
append html "<option value=$choice_id selected>$label</option>\n"
} else {
append html "<option value=$choice_id>$label</option>\n"
}
}
append html "</select>"
}
}
"radio" {
if { $abstract_data_type == "boolean" } {
if {$edit_previous_response_p == "t"} { set user_value $boolean_answer }
set choices [list \
"<input type=radio name=$element_name value=t [ad_decode $user_value "t" "checked" ""]> True" \
"<input type=radio name=$element_name value=f [ad_decode $user_value "f" "checked" ""]> False" \
]
} else {
if {$edit_previous_response_p == "t"} { set user_value $choice_id }
set choices [list]
db_foreach sursimp_question_choices_2 "
select choice_id, label
from survsimp_question_choices
where question_id = :question_id
order by sort_order
" {
if { $user_value == $choice_id } {
lappend choices "<input type=radio name=$element_name value=$choice_id checked> $label"
} else {
lappend choices "<input type=radio name=$element_name value=$choice_id> $label"
}
}
}
if { $presentation_alignment == "beside" } {
append html [join $choices " "]
} else {
append html "<blockquote>\n[join $choices "<br>\n"]\n</blockquote>"
}
}
"checkbox" {
set choices [list]
db_foreach sursimp_question_choices_3 "
select * from survsimp_question_choices
where question_id = :question_id
order by sort_order
" {
if { [info exists selected_choices($choice_id)] } {
lappend choices "<input type=checkbox name=$element_name value=$choice_id checked> $label"
} else {
lappend choices "<input type=checkbox name=$element_name value=$choice_id> $label"
}
}
if { $presentation_alignment == "beside" } {
append html [join $choices " "]
} else {
append html "<blockquote>\n[join $choices "<br>\n"]\n</blockquote>"
}
}
}
return $html
}
<master>
<property name="title">@page_title@</property>
<property name="main_navbar_label">projects</property>
<property name="left_navbar">@left_navbar_html;noquote@</property>
<h1><%=[lang::message::lookup "" intranet-trans-project-feedback.DashboardProjectFeedback "Dashboard Project Feedback"]%></h1>
<%= [im_component_bay top] %>
<table cellpadding=0 cellspacing=0 border=0 width="100%">
<tr>
<td valign=top width='50%'>
<%= [im_component_bay left] %>
</td>
<td width=2>&nbsp;</td>
<td valign=top>
<%= [im_component_bay right] %>
</td>
</tr>
</table><br>
<table cellpadding=0 cellspacing=0 border=0 width='100%'>
<tr><td>
<!-- Bottom Component Bay -->
<%= [im_component_bay bottom] %>
</td></tr>
</table>
# /packages/intranet-trans-project-feedback/www/dashboard.tcl
#
# Copyright (C) 2015 Project Open Business Solutions S.L.
#
# This program is free software. You can redistribute it
# and/or modify it under the terms of the GNU General
# Public License as published by the Free Software Foundation;
# either version 2 of the License, or (at your option)
# any later version. This program is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
# Profiles represent OpenACS groups used by ]project-open[
# However, for performance reasons we have introduced special
# caching and auxillary functions specific to ]po[.
# @author klaus.hofeditz@project-open.com
ad_page_contract {
Shows dashboard for Translation Project Feedback
@author mbryzek@arsdigita.com
@author Frank Bergmann (frank.bergmann@project-open.com)
@author klaus.hofeditz@project-open.com
} {
{ start_date "" }
{ end_date "" }
{ period "" }
}
# ---------------------------------------------------------------------
# Permissions
# ---------------------------------------------------------------------
# ---------------------------------------------------------------------
# Defaults & Security
# ---------------------------------------------------------------------
set show_context_help_p 0
set user_id [ad_maybe_redirect_for_registration]
set return_url [im_url_with_query]
set current_url [ns_conn url]
set site_wide_admin_p [im_is_user_site_wide_or_intranet_admin $user_id]
set page_title ""
set left_navbar_html ""
set admin_html_content ""
db_1row todays_date "
select
to_char(sysdate::date, 'YYYY') as todays_year,
to_char(sysdate::date, 'MM') as todays_month,
to_char(sysdate::date, 'DD') as todays_day
from dual
"
# Show last 6 months by default
if {"" == $end_date} { set end_date "$todays_year-$todays_month-01" }
if {"" == $start_date} { set start_date [clock format [clock scan {-6 months} -base [clock scan $end_date] ] -format %Y-%m-%d] }
if { "" == $period } {
set period "month"
}
# ---------------------------------------------------------------------
# Validate
# ---------------------------------------------------------------------
if { "" != $start_date } {
if {[catch {
if { $start_date != [clock format [clock scan $start_date] -format %Y-%m-%d] } {
ad_return_complaint 1 "<strong>[_ intranet-core.Start_Date]</strong> [lang::message::lookup "" intranet-core.IsNotaValidDate "is not a valid date"].<br>
[lang::message::lookup "" intranet-core.Current_Value "Current value"]: '$start_date'<br>"
}
} err_msg]} {
ad_return_complaint 1 "<strong>[_ intranet-core.Start_Date]</strong> [lang::message::lookup "" intranet-core.DoesNotHaveRightFormat "doesn't have the right format"].<br>
[lang::message::lookup "" intranet-core.Current_Value "Current value"]: '$start_date'<br>
[lang::message::lookup "" intranet-core.Expected_Format "Expected Format"]: 'YYYY-MM-DD'"
}
}
if { "" != $end_date } {
if {[catch {
if { $end_date != [clock format [clock scan $end_date] -format %Y-%m-%d] } {
ad_return_complaint 1 "<strong>[_ intranet-core.End_Date]</strong> [lang::message::lookup "" intranet-core.IsNotaValidDate "is not a valid date"].<br>
[lang::message::lookup "" intranet-core.Current_Value "Current value"]: '$end_date'<br>"
}
} err_msg]} {
ad_return_complaint 1 "<strong>[_ intranet-core.End_Date]</strong> [lang::message::lookup "" intranet-core.DoesNotHaveRightFormat "doesn't have the right format"].<br>
[lang::message::lookup "" intranet-core.Current_Value "Current value"]: '$end_date'<br>
[lang::message::lookup "" intranet-core.Expected_Format "Expected Format"]: 'YYYY-MM-DD'"
}
}
# ---------------------------------------------------------------------
# Admin Box
# ---------------------------------------------------------------------
set sel_month ""
set sel_quarter ""
set sel_year ""
switch period {
month { set sel_month selected }
quarter { set sel_quarter selected }
year { set sel_year selected }
}
set admin_html_content "
<form>
<table border=0 cellspacing=1 cellpadding=1>
<tr valign=top><td>
<table border=0 cellspacing=1 cellpadding=1>
<tr>
<td class=form-label>[lang::message::lookup "" intranet-core.Start_Date "Start Date"]</td>
<td class=form-widget>
<input type=textfield name=start_date value=$start_date>
</td>
</tr>
<tr>
<td class=form-label>[lang::message::lookup "" intranet-core.End_Date "End Date"]</td>
<td class=form-widget>
<input type=textfield name=end_date value=$end_date>
</td>
</tr>
<tr>
<td class=form-label>[lang::message::lookup "" intranet-reporting.Period "Period"]</td>
<td class=form-widget>
<select name='period'>
<option $sel_month value='month'>[lang::message::lookup "" acs-datetime.Month "Month"]</option>
<option $sel_quarter value='quarter'>[lang::message::lookup "" intranet-core.Quarter "Quarter"]</option>
<option $sel_year value='year'>[lang::message::lookup "" intranet-core.Year "Year"]</option>
</select>
</td>
</tr>
<tr>
<td class=form-label></td>
<td class=form-widget><input type=submit value='[lang::message::lookup "" acs-kernel.common_Submit "Submit"]'></td>
</tr>
</table>
</tr>
</table>
</form>
"
set left_navbar_html $admin_html_content
<?xml version="1.0"?>
<queryset>
<rdbms><type>postgresql</type><version>7.1</version></rdbms>
<fullquery name="create_response">
<querytext>
select survsimp_response__new (
:response_id,
:survey_id,
null,
'f',
:user_id,
:creation_ip,
:survey_id
)
</querytext>
</fullquery>
<fullquery name="survsimp_question_response_text_insert">
<querytext>
insert into survsimp_question_responses
(response_id, question_id, clob_answer)
values
(:response_id, :question_id, :clob_answer)
</querytext>
</fullquery>
<fullquery name="create_item">
<querytext>
select content_item__new (
varchar :name,
null,
null,
null,
now(),
:user_id,
null,
:creation_ip,
'content_item',
'content_revision',
null,
null,
'text/plain',
null,
null,
'file'
)
</querytext>
</fullquery>
<fullquery name="create_rel">
<querytext>
select acs_rel__new (
null,
'user_blob_response_rel',
:user_id,
:item_id,
null,
null,
null
)
</querytext>
</fullquery>
<fullquery name="create_revision">
<querytext>
declare
v_revision_id integer;
begin
v_revision_id := content_revision__new (
'A Blob Response',
null,
now(),
:guessed_file_type,
null,
'not_important',
:item_id,
null,
now(),
:user_id,
:creation_ip
);
update cr_items
set live_revision = v_revision_id
where item_id = :item_id;
return v_revision_id;
end;
</querytext>
</fullquery>
<fullquery name="update_response">
<querytext>
update cr_revisions
set content = '[cr_create_content_file $item_id $revision_id $tmp_filename]'
where revision_id = :revision_id
</querytext>
</fullquery>
</queryset>
<master>
<property name=title>Response Submitted for @survey_name;noquote@</property>
<property name="context">@context;noquote@</property>
Response submitted for @survey_name@. Thank you.
# /packages/intranet-trans-project-feedback/www/process-response.tcl
#
# This program is free software. You can redistribute it
# and/or modify it under the terms of the GNU General
# Public License as published by the Free Software Foundation;
# either version 2 of the License, or (at your option)
# any later version. This program is distributed in the
# hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
# Profiles represent OpenACS groups used by ]project-open[
# However, for performance reasons we have introduced special
# caching and auxillary functions specific to ]po[.
# @author jsc@arsdigita.com
# @author nstrug@arsdigita.com
# @author klaus.hofeditz@project-open.com
ad_page_contract {
This is a slightly modified version of ~/packages/simple-survey/www/process-response.tcl
to avoid that multiple reposnes are given for the 'Translation Project Feedback'
Insert user response into database.
This page receives an input for each question named
response_to_question.$question_id
@param survey_id survey user is responding to
@param return_url optional redirect address
@param group_id
@param response_to_question since form variables are now named as response_to_question.$question_id, this is actually array holding user responses to all survey questions.
@param task_id Optionally specified workflow task_id from acs-workflow.
Behave like the user would have clicked the "Task done" button.
} {
survey_id:integer,notnull
{ related_object_id:integer "" }
{ related_context_id:integer "" }
return_url:optional
response_to_question:array,optional,multiple,html
{ task_id "" }
} -validate {
survey_exists -requires { survey_id } {
if ![db_0or1row survey_exists {
select 1 from survsimp_surveys where survey_id = :survey_id
}] {
ad_complain "Survey $survey_id does not exist"
}
}
check_questions -requires { survey_id:integer } {
set question_info_list [db_list_of_lists survsimp_question_info_list {
select question_id, question_text, abstract_data_type, presentation_type, required_p
from survsimp_questions
where survey_id = :survey_id
and active_p = 't'
order by sort_key
}]
## Validate input.
set questions_with_missing_responses [list]
foreach question $question_info_list {
set question_id [lindex $question 0]
set question_text [lindex $question 1]
set abstract_data_type [lindex $question 2]
set required_p [lindex $question 4]
# Need to clean-up after mess with :array,multiple flags
# in ad_page_contract. Because :multiple flag will sorround empty
# strings and all multiword values with one level of curly braces {}
# we need to get rid of them for almost any abstract_data_type
# except 'choice', where this is intended behaviour. Why bother
# with :multiple flag at all? Because otherwise we would lost all
# but first value for 'choice' abstract_data_type - see ad_page_contract
# doc and code for more info.
#
if { [exists_and_not_null response_to_question($question_id)] } {
if {$abstract_data_type != "choice"} {
set response_to_question($question_id) [join $response_to_question($question_id)]
}
}
if { $abstract_data_type == "date" } {
if [catch { set response_to_question($question_id) [validate_ad_dateentrywidget "" response_to_question.$question_id [ns_getform]]} errmsg] {
ad_complain "$errmsg: Please make sure your dates are valid."
}
}
if { [exists_and_not_null response_to_question($question_id)] } {
set response_value [string trim $response_to_question($question_id)]
} elseif {$required_p == "t"} {
lappend questions_with_missing_responses $question_text
continue
} else {
set response_to_question($question_id) ""
set response_value ""
}
if {![empty_string_p $response_value]} {
if { $abstract_data_type == "number" } {
if { ![regexp {^(-?[0-9]+\.)?[0-9]+$} $response_value] } {
ad_complain "The response to \"$question_text\" must be a number. Your answer was \"$response_value\"."
continue
}
} elseif { $abstract_data_type == "integer" } {
if { ![regexp {^[0-9]+$} $response_value] } {
ad_complain "The response to \"$question_text\" must be an integer. Your answer was \"$response_value\"."
continue
}
}
}
if { $abstract_data_type == "blob" } {
set tmp_filename $response_to_question($question_id.tmpfile)
set n_bytes [file size $tmp_filename]
if { $n_bytes == 0 && $required_p == "t" } {
ad_complain "Your file is zero-length. Either you attempted to upload a zero length file, a file which does not exist, or something went wrong during the transfer."
}
}
}
if { [llength $questions_with_missing_responses] > 0 } {
ad_complain "You didn't respond to all required sections. You skipped:"
foreach skipped_question $questions_with_missing_responses {
ad_complain $skipped_question
}
return 0
} else {
return 1
}
}
} -properties {
survey_name:onerow
}
# ad_require_permission $survey_id survsimp_take_survey
set user_id [ad_verify_and_get_user_id]
set response_id [db_nextval acs_object_id_seq]
set creation_ip [ad_conn peeraddr]
# -----------------------------------------------------
# Do the inserts.
# -----------------------------------------------------
db_transaction {
db_exec_plsql create_response {
begin
:1 := survsimp_response.new (
response_id => :response_id,
survey_id => :survey_id,
context_id => :survey_id,
creation_user => :user_id
);
end;
}
db_dml update_oid "
update survsimp_responses set
related_object_id = :related_object_id,
related_context_id = :related_context_id
where response_id = :response_id
"
set question_info_list [db_list_of_lists survsimp_question_info_list {
select question_id, question_text, abstract_data_type, presentation_type, required_p
from survsimp_questions
where survey_id = :survey_id
and active_p = 't'
and presentation_type <> 'none'
order by sort_key }]
foreach question $question_info_list {
set question_id [lindex $question 0]
set question_text [lindex $question 1]
set abstract_data_type [lindex $question 2]
set presentation_type [lindex $question 3]
set response_value [string trim $response_to_question($question_id)]
switch -- $abstract_data_type {
"choice" {
if { $presentation_type == "checkbox" } {
# Deal with multiple responses.
set checked_responses $response_to_question($question_id)
foreach response_value $checked_responses {
if { [empty_string_p $response_value] } {
set response_value [db_null]
}
db_dml survsimp_question_response_checkbox_insert "insert into survsimp_question_responses (response_id, question_id, choice_id)
values (:response_id, :question_id, :response_value)"
}
} else {
if { [empty_string_p $response_value] } {
set response_value [db_null]
}
db_dml survsimp_question_response_choice_insert "insert into survsimp_question_responses (response_id, question_id, choice_id)
values (:response_id, :question_id, :response_value)"
}
}
"shorttext" {
db_dml survsimp_question_choice_shorttext_insert "insert into survsimp_question_responses (response_id, question_id, varchar_answer)
values (:response_id, :question_id, :response_value)"
}
"boolean" {
if { [empty_string_p $response_value] } {
set response_value [db_null]
}
db_dml survsimp_question_response_boolean_insert "insert into survsimp_question_responses (response_id, question_id, boolean_answer)
values (:response_id, :question_id, :response_value)"
}
"number" {}
"integer" {
if { [empty_string_p $response_value] } {
set response_value [db_null]
}
db_dml survsimp_question_response_integer_insert "insert into survsimp_question_responses (response_id, question_id, number_answer)
values (:response_id, :question_id, :response_value)"
}
"text" {
if { [empty_string_p $response_value] } {
set response_value [db_null]
}
# fraber 060103: missing variable clob_answer in .xql file
set clob_answer $response_value
db_dml survsimp_question_response_text_insert "
insert into survsimp_question_responses
(response_id, question_id, clob_answer)
values (:response_id, :question_id, empty_clob())
returning clob_answer into :1" -clobs [list $response_value]
}
"date" {
if { [empty_string_p $response_value] } {
set response_value [db_null]
}
db_dml survsimp_question_response_date_insert "insert into survsimp_question_responses (response_id, question_id, date_answer)
values (:response_id, :question_id, :response_value)"
}
"blob" {
if { ![empty_string_p $response_value] } {
# this stuff only makes sense to do if we know the file exists
set tmp_filename $response_to_question($question_id.tmpfile)
set file_extension [string tolower [file extension $response_value]]
# remove the first . from the file extension
regsub {\.} $file_extension "" file_extension
set guessed_file_type [ns_guesstype $response_value]
set n_bytes [file size $tmp_filename]
# strip off the C:\directories... crud and just get the file name
if ![regexp {([^/\\]+)$} $response_value match client_filename] {
# couldn't find a match
set client_filename $response_value
}
if { $n_bytes == 0 } {
error "This should have been checked earlier."
} else {
### add content repository support
# 1. create new content item
# 2. create relation between user and content item
# 3. create a new empty content revision and make live
# 4. update the cr_revisions table with the blob data
# 5. update the survey table
db_transaction {
set name "blob-response-$response_id"
set item_id [db_exec_plsql create_item "
begin
:1 := content_item.new (
name => :name,
creation_ip => :creation_ip);
end;"]
set rel_id [db_exec_plsql create_rel "
begin
:1 := acs_rel.new (
rel_type => 'user_blob_response_rel',
object_id_one => :user_id,
object_id_two => :item_id);
end;"]
set revision_id [db_exec_plsql create_revision "
begin
:1 := content_revision.new (
title => 'A Blob Response',
item_id => :item_id,
text => 'not_important',
mime_type => :guessed_file_type,
creation_date => sysdate,
creation_user => :user_id,
creation_ip => :creation_ip);
update cr_items
set live_revision = :1
where item_id = :item_id;
end;"]
db_dml update_response "
update cr_revisions
set content = empty_blob()
where revision_id = :revision_id
returning content into :1" -blob_files [list $tmp_filename]
set content_length [cr_file_size $tmp_filename]
db_dml survsimp_question_response_blob_insert "
insert into survsimp_question_responses
(response_id, question_id, item_id,
content_length,
attachment_file_name, attachment_file_type,
attachment_file_extension)
values
(:response_id, :question_id, :item_id,
:content_length,
:response_value, :guessed_file_type,
:file_extension)"
}
}
}
}
}
}
} on_error {
ad_complain "Database Error. There was an error while trying to process your response: $errmsg"
return
}
#
# Survey type-specific stuff
#
set type [db_string get_type "select type from survsimp_surveys where survey_id = :survey_id"]
switch $type {
"general" {
set survey_name [db_string survsimp_name_from_id "select name from survsimp_surveys where survey_id = :survey_id" ]
db_release_unused_handles
if {[info exists return_url] && ![empty_string_p $return_url]} {
ad_returnredirect "$return_url"
ad_script_abort
} else {
set context [list "Response Submitted"]
}
}
"scored" {
db_foreach get_score "select variable_name, sum(score) as sum_of_scores
from survsimp_choice_scores, survsimp_question_responses, survsimp_variables
where survsimp_choice_scores.choice_id = survsimp_question_responses.choice_id
and survsimp_choice_scores.variable_id = survsimp_variables.variable_id
and survsimp_question_responses.response_id = :response_id
group by variable_name" {
set sum_score($variable_name) $sum_of_scores
}
set logic [db_string get_logic "select logic from survsimp_logic, survsimp_logic_surveys_map
where survsimp_logic.logic_id = survsimp_logic_surveys_map.logic_id
and survey_id = :survey_id"]
if {[info exists return_url] && ![empty_string_p $return_url]} {
db_release_unused_handles
ad_returnredirect $return_url
}
eval $logic
db_release_unused_handles
ad_script_abort
}
default {
if {[info exists return_url] && ![empty_string_p $return_url]} {
ad_returnredirect "$return_url"
ad_script_abort
} else {
set context {"Response Submitted"}
}
}
}
<?xml version="1.0"?>
<queryset>
<fullquery name="survey_exists">
<querytext>
select 1 from survsimp_surveys where survey_id = :survey_id
</querytext>
</fullquery>
<fullquery name="survsimp_question_info_list">
<querytext>
select question_id, question_text, abstract_data_type, presentation_type, required_p
from survsimp_questions
where survey_id = :survey_id
and active_p = 't'
order by sort_key
</querytext>
</fullquery>
<fullquery name="survsimp_question_info_list">
<querytext>
select question_id, question_text, abstract_data_type, presentation_type, required_p
from survsimp_questions
where survey_id = :survey_id
and active_p = 't'
order by sort_key
</querytext>
</fullquery>
<fullquery name="survsimp_question_response_checkbox_insert">
<querytext>
insert into survsimp_question_responses (response_id, question_id, choice_id)
values (:response_id, :question_id, :response_value)
</querytext>
</fullquery>
<fullquery name="survsimp_question_response_choice_insert">
<querytext>
insert into survsimp_question_responses (response_id, question_id, choice_id)
values (:response_id, :question_id, :response_value)
</querytext>
</fullquery>
<fullquery name="survsimp_question_choice_shorttext_insert">
<querytext>
insert into survsimp_question_responses (response_id, question_id, varchar_answer)
values (:response_id, :question_id, :response_value)
</querytext>
</fullquery>
<fullquery name="survsimp_question_response_boolean_insert">
<querytext>
insert into survsimp_question_responses (response_id, question_id, boolean_answer)
values (:response_id, :question_id, :response_value)
</querytext>
</fullquery>
<fullquery name="survsimp_question_response_integer_insert">
<querytext>
insert into survsimp_question_responses (response_id, question_id, number_answer)
values (:response_id, :question_id, :response_value)
</querytext>
</fullquery>
<fullquery name="survsimp_question_response_date_insert">
<querytext>
insert into survsimp_question_responses (response_id, question_id, date_answer)
values (:response_id, :question_id, :response_value)
</querytext>
</fullquery>
<fullquery name="get_type">
<querytext>
select type from survsimp_surveys where survey_id = :survey_id
</querytext>
</fullquery>
<fullquery name="survsimp_name_from_id">
<querytext>
select name from survsimp_surveys where survey_id = :survey_id
</querytext>
</fullquery>
<fullquery name="get_score">
<querytext>
select variable_name, sum(score) as sum_of_scores
from survsimp_choice_scores, survsimp_question_responses, survsimp_variables
where survsimp_choice_scores.choice_id = survsimp_question_responses.choice_id
and survsimp_choice_scores.variable_id = survsimp_variables.variable_id
and survsimp_question_responses.response_id = :response_id
group by variable_name
</querytext>
</fullquery>
<fullquery name="get_logic">
<querytext>
select logic from survsimp_logic, survsimp_logic_surveys_map
where survsimp_logic.logic_id = survsimp_logic_surveys_map.logic_id
and survey_id = :survey_id
</querytext>
</fullquery>
<fullquery name="survsimp_question_response_blob_insert">
<querytext>
insert into survsimp_question_responses
(response_id, question_id, item_id,
content_length,
attachment_file_name, attachment_file_type,
attachment_file_extension)
values
(:response_id, :question_id, :item_id,
:content_length,
:response_value, :guessed_file_type,
:file_extension)
</querytext>
</fullquery>
</queryset>
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