Commit 79b6b8db authored by Frank Bergmann's avatar Frank Bergmann

-- get project import to work

   added storing of mappings
parent 8fb1efa2
......@@ -42,6 +42,54 @@ ad_proc -public im_csv_import_parser_no_change {
return [list $arg ""]
}
ad_proc -public im_csv_import_parser_user_name {
{-parser_args "" }
arg
} {
Returns a user_id from parties
} {
if {[regexp {'} $arg match]} {
set err "Found a email (email) with single quote, consider removing single quotes from emails"
im_security_alert -location "im_csv_import_parser_project_nr" -message $err -value $arg
return [list $arg $err]
}
set sql "
select party_id
from parties p
where p.email = '$arg'
"
set party_id [db_string party_id_from_name $sql -default ""]
set err ""
if {"" == $party_id} { set err "Didn't find user with email ='$arg'" }
return [list $party_id $err]
}
ad_proc -public im_csv_import_parser_company_name {
{-parser_args "" }
arg
} {
Returns a company_id from im_companies
} {
if {[regexp {'} $arg match]} {
set err "Found a company name ($arg) with single quote, consider removing single quotes from companies"
im_security_alert -location "im_csv_import_parser_project_nr" -message $err -value $arg
return [list $arg $err]
}
set sql "
select min(c.company_id)
from im_companies c
where c.company_name = '$arg'
"
set company_id [db_string company_id_from_name $sql -default ""]
set err ""
if {"" == $company_id} { set err "Didn't find company with company_name ='$arg'" }
return [list $company_id $err]
}
ad_proc -public im_csv_import_parser_project_nr {
{-parser_args "" }
arg
......@@ -77,7 +125,21 @@ ad_proc -public im_csv_import_parser_date_european {
if {1 == [string length $month]} { set dom "0$month" }
return [list "$year-$month-$dom" ""]
}
return [list "" "Error parsing European date format '$arg': expected 'dd.mm.yyyy'"]
return [list "" "Error parsing European date format '$arg': expected 'dd.mm.yyyy'. If the error remains, try to import ANSI dates (2015-01-01) and set parser to 'No change'"]
}
ad_proc -public im_csv_import_parser_date_european_dashes {
{-parser_args "" }
arg
} {
Parses a European date format like '08/06/2011' as the 8th of June, 2011
} {
if {[regexp {^(.+)/(.+)/(....)$} $arg match dom month year]} {
if {1 == [string length $dom]} { set dom "0$dom" }
if {1 == [string length $month]} { set dom "0$month" }
return [list "$year-$month-$dom" ""]
}
return [list "" "Error parsing European date format '$arg': expected 'dd/mm/yyyy' ()"]
}
......@@ -271,16 +333,19 @@ ad_proc -public im_csv_import_parsers {
switch $object_type {
im_project - im_company - im_conf_item - im_risk - im_timesheet_task - im_ticket {
set parsers {
no_change "No Change"
hard_coded "Hard Coded Functionality"
date_european "European Date Parser (DD.MM.YYYY)"
number_european "European Number Parser (20.000,00)"
date_american "American Date Parser (MM/DD/YYYY)"
number_american "American Number Parser (20,000.00)"
category "Category Parser"
cost_center "Cost Center Parser"
project_nr "Project from Project Nr"
project_name "Project from Project Name"
no_change "No Change"
hard_coded "Hard Coded Functionality"
date_european "European Date Parser (DD.MM.YYYY)"
date_european_dashes "European Date Parser (DD/MM/YYYY)"
number_european "European Number Parser (20.000,00)"
date_american "US Date Parser (MM/DD/YYYY)"
number_american "US Number Parser (20,000.00)"
category "Category ID from Category Name"
cost_center "Cost Center Parser"
project_nr "Project from Project Nr"
project_name "Project from Project Name"
company_name "Company ID from Company Name"
user_name "User ID from user-email"
}
}
default {
......@@ -338,10 +403,15 @@ ad_proc -public im_csv_import_guess_parser {
parent_nrs { return [list "hard_coded" "" ""] }
customer_name { return [list "hard_coded" "" "company_id"] }
project_status { return [list "hard_coded" "" "project_status_id"] }
project_type { return [list "hard_coded" "" "project_type_id"] }
on_track_status { return [list "hard_coded" "" "on_track_status_id"] }
customer_contact { return [list "" "" "company_contact_id"] }
project_manager { return [list "hard_coded" "" "project_lead_id"] }
project_path { return [list "project_path" "" "project_path"] }
project_type { return [list "category" "Intranet Project Type" "project_type_id"] }
project_status { return [list "category" "Intranet Project Status" "project_status_id"] }
project_budget { return [list "" "" "project_budget"] }
start_date { return [list "" "" "start_date"] }
end_date { return [list "" "" "end_date"] }
}
}
}
......
......@@ -3,7 +3,34 @@
<property name="context">@context_bar;literal@</property>
<property name="main_navbar_label">@main_navbar_label;literal@</property>
<form enctype="multipart/form-data" method=POST action="import-@redirect_object_type@.tcl">
<script type="text/javascript">
$(document).ready(function() {
// Initialize
$('#@form_id@').sayt({'days': 180});
// if($('#@form_id@').sayt({'checksaveexists': true}) == true)
// { console.log('Form has an existing save cookie.'); } else { console.log('No cookie found'); };
// Do not save the hidden fields
$('#@form_id@').sayt({'exclude':
[
'[name=return_url]',
'[name=object_type]',
'[name=import_filename]'
]
});
$('#forms_delete_save_button').click(function() {
$('#@form_id@').sayt({'erase': true});
console.log('Form cookie was deleted.');
alert('Saved settings have been deleted');
return false;
});
});
</script>
<form enctype="multipart/form-data" method=POST action="import-@redirect_object_type@.tcl" id="@form_id@">
<%= [export_vars -form {object_type return_url import_filename}] %>
<table>
......@@ -47,6 +74,10 @@
<td><input type="submit" value="<%= [lang::message::lookup "" intranet-csv-import.Import_CSV "Import CSV"] %>"></td>
</tr>
</table>
<p>
The mapping showing up on this page will be saved as-you-type to simplify the import process.<br/>
This allows you to go back, reload the file without loosing your mapping settings.<br/>
To erase the savings, please click <span id="forms_delete_save_button" style="text-decoration:underline;cursor:pointer" >here</span>.
</p>
</form>
......@@ -11,6 +11,20 @@ ad_page_contract {
object_type
}
# ---------------------------------------------------------------------
# Note:
# ---------------------------------------------------------------------
# This script uses jquery-save-as-you-type in order to store
# the user settings for mapping. This way a user does not need
# to start all over again if an import fails.
# The script stores ALL form vars so please add any new vars
# added to the form that should not be stored to the
# "exclude" section see (.adp file) to avoid side effects.
template::head::add_javascript -src "/intranet-csv-import/js/jquery-save-as-you-type/source/sayt.min.jquery.js" -order 1000
template::head::add_javascript -src "/intranet-csv-import/js/jquery-save-as-you-type/dependencies/jquery-cookie.js" -order 1000
# ---------------------------------------------------------------------
# Default & Security
# ---------------------------------------------------------------------
......@@ -28,9 +42,11 @@ set admin_p [im_is_user_site_wide_or_intranet_admin $current_user_id]
# Get the file from the user.
# number_of_bytes is the upper-limit
set max_n_bytes [im_parameter -package_id [im_package_filestorage_id] MaxNumberOfBytes "" 0]
set max_n_bytes [parameter::get -package_id [apm_package_id_from_key im_package_filestorage_id] -parameter "MaxNumberOfBytes" -default 0]
set tmp_filename [ns_queryget upload_file.tmpfile]
im_security_alert_check_tmpnam -location "import-2.tcl" -value $tmp_filename
if { $max_n_bytes && ([file size $tmp_filename] > $max_n_bytes) } {
ad_return_complaint 1 "Your file is larger than the maximum permissible upload size:
[util_commify_number $max_n_bytes] bytes"
......@@ -39,13 +55,30 @@ if { $max_n_bytes && ([file size $tmp_filename] > $max_n_bytes) } {
# Empty return_url?
# Choose depending on the object type...
# Varied form_id's tio support 'jquery-save-as-you-type'
if {"" == $return_url} {
switch $object_type {
im_company { set return_url "/intranet/companies/index" }
im_conf_item { set return_url "/intranet-helpdesk/index" }
im_project { set return_url "/intranet/projects/index" }
person { set return_url "/intranet/users/index" }
default { set return_url "/intranet" }
im_company {
set return_url "/intranet/companies/index"
set form_id "intranet-csv-import-import2-companies"
}
im_conf_item {
set return_url "/intranet-helpdesk/index"
set form_id "intranet-csv-import-import2-confitems"
}
im_project {
set return_url "/intranet/projects/index"
set form_id "intranet-csv-import-import2-projects"
}
person {
set return_url "/intranet/users/index"
set form_id "intranet-csv-import-import2-users"
}
default {
set return_url "/intranet"
set form_id "intranet-csv-import-import2-other"
}
}
}
......@@ -103,7 +136,6 @@ set values_lol [im_csv_get_values $lines_content $separator]
# set error [im_csv_import_check_list_of_lists $values_lol]
# if {"" != $error} { ad_return_complaint 1 $error }
# Take a sample of max_row rows from the file and show
set max_row 10
for {set i 1} {$i <= $max_row} {incr i} {
......@@ -159,7 +191,7 @@ foreach header_name $headers {
set default_parser_args [lindex $defs 1]
set override_map [lindex $defs 2]
set parser [im_select parser.$cnt $parser_pairs $default_parser]
set args "<input type=text name=parser_args.$cnt value=\"$default_parser_args\">\n"
set args "<input type=text name=parser_args.$cnt value=\"$default_parser_args\" size=\"40\">\n"
# Mapping - Map to which object field?
set default_map $object_field_best_guess
......@@ -168,10 +200,8 @@ foreach header_name $headers {
ns_log Notice "import-2: header_name=$header_name, default_map=$default_map, override_map=$override_map, map=$map"
if {"hard_coded" == $default_parser} { set map [im_select map.$cnt $object_type_pairs "hard_coded"] }
multirow append mapping $header_name $column $map $parser $args [lindex $row_1 $cnt] [lindex $row_2 $cnt] [lindex $row_3 $cnt] [lindex $row_4 $cnt] [lindex $row_5 $cnt]
incr cnt
......@@ -187,3 +217,4 @@ switch $object_type {
set redirect_object_type $object_type
}
}
......@@ -21,8 +21,6 @@ ad_page_contract {
parser_args:array
}
# ad_return_complaint 1 "<pre>\n\n[array get column]\n\n[array get map]\n\n[array get parser]\n\n[array get parser_args]\n\n</pre>"
# ---------------------------------------------------------------------
# Default & Security
# ---------------------------------------------------------------------
......@@ -129,7 +127,7 @@ foreach csv_line_fields $values_list_of_lists {
set project_nr ""
set project_path ""
set customer_name ""
set customer_id ""
set company_id ""
set parent_nrs ""
set parent_id ""
set project_status ""
......@@ -207,18 +205,25 @@ foreach csv_line_fields $values_list_of_lists {
# -------------------------------------------------------
# Transform the variables
set i 0
foreach varname $var_name_list {
set p $parser($i)
set p_args $parser_args($i)
set target_varname $map($i)
ns_log Notice "import-im_project: Parser: $varname -> $target_varname"
ns_log Notice "import-im_project: Parser: p_args: $p_args"
ns_log Notice "import-im_project: Parser: target_varname: $target_varname"
switch $p {
no_change { }
no_change {
set $target_varname [set $varname]
ns_log Notice "import-im_project: Parser: no change: varname: $varname, val: [set $varname]"
}
default {
set proc_name "im_csv_import_parser_$p"
if {[catch {
set val [set $varname]
ns_log Notice "import-im_project: Parser: val: $val"
if {"" != $val} {
set result [$proc_name -parser_args $p_args $val]
set res [lindex $result 0]
......@@ -240,9 +245,9 @@ foreach csv_line_fields $values_list_of_lists {
}
incr i
ns_log Notice "import-im_project: -------------------------------------------"
}
# -------------------------------------------------------
# Specific field transformations
......@@ -306,18 +311,18 @@ foreach csv_line_fields $values_list_of_lists {
# On track status can be NULL without problems
set on_track_status_id [im_id_from_category [list $on_track_status] "Intranet Project On Track Status"]
# customer_id
if {"" == $customer_id } {
set customer_id [db_string cust "select company_id from im_companies where lower(company_name) = trim(lower(:customer_name))" -default ""]
# company_id
if {"" == $company_id } {
set company_id [db_string cust "select company_id from im_companies where lower(company_name) = trim(lower(:customer_name))" -default ""]
}
if {"" == $customer_id } {
set customer_id [db_string cust "select company_id from im_companies where lower(company_path) = trim(lower(:customer_name))" -default ""]
if {"" == $company_id } {
set company_id [db_string cust "select company_id from im_companies where lower(company_path) = trim(lower(:customer_name))" -default ""]
}
# For compatibility
set company_id $customer_id
set company_id $company_id
if {"" == $customer_id } {
set customer_id [im_company_internal]
if {"" == $company_id } {
set company_id [im_company_internal]
if {$ns_write_p} { ns_write "<li><font color=brown>Warning: Didn't find customer_name='$customer_name', using 'internal' customer</font>\n" }
}
......@@ -331,7 +336,6 @@ foreach csv_line_fields $values_list_of_lists {
if {$ns_write_p} { ns_write "<li><font color=brown>Warning: Didn't find customer contact '$customer_contact'.</font>\n" }
}
# -------------------------------------------------------
# Check if the project already exists
......@@ -391,7 +395,7 @@ foreach csv_line_fields $values_list_of_lists {
-project_name $project_name \
-project_nr $project_nr \
-project_path $project_path \
-company_id $customer_id \
-company_id $company_id \
-parent_id $parent_id \
-project_type_id $project_type_id \
-project_status_id $project_status_id \
......@@ -412,7 +416,7 @@ foreach csv_line_fields $values_list_of_lists {
project_name = :project_name,
project_nr = :project_nr,
project_path = :project_path,
company_id = :customer_id,
company_id = :company_id,
parent_id = :parent_id,
project_status_id = :project_status_id,
project_type_id = :project_type_id,
......@@ -591,7 +595,6 @@ foreach csv_line_fields $values_list_of_lists {
}
if {$ns_write_p} {
ns_write "</ul>\n"
ns_write "<p>\n"
......@@ -606,3 +609,4 @@ if {$ns_write_p} {
}
......@@ -46,7 +46,7 @@
<table>
<tr>
<td>
We espect that the import file contains the column names in the first row.
We expect that the import file contains the column names in the first row.<br/>
</td>
</tr>
</table>
......
/**
* jQuery Cookie plugin
*
* https://github.com/carhartl/jquery-cookie
*
* Copyright (c) 2010 Klaus Hartl (stilbuero.de)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
jQuery.cookie = function (key, value, options) {
// key and at least value given, set cookie...
if (arguments.length > 1 && String(value) !== "[object Object]") {
options = jQuery.extend({}, options);
if (value === null || value === undefined) {
options.expires = -1;
}
if (typeof options.expires === 'number') {
var days = options.expires, t = options.expires = new Date();
t.setDate(t.getDate() + days);
}
value = String(value);
return (document.cookie = [
encodeURIComponent(key), '=',
options.raw ? value : encodeURIComponent(value),
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
options.path ? '; path=' + options.path : '',
options.domain ? '; domain=' + options.domain : '',
options.secure ? '; secure' : ''
].join(''));
}
// key and possibly options given, get cookie...
options = value || {};
var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent;
return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null;
};
\ No newline at end of file
/*
*******************************************************************************
*
* sayt - Save As You Type
*
*******************************************************************************
*
* This plugin autosaves form input as it is being entered by the
* user. It is saved to a cookie during each keyup and change.
*
* When a page is reloaded for any reason, the form data is automatically
* re-entered for the user by reading the cookie. The cookie can be deleted
* on the fly by the plugin if required.
*
*******************************************************************************
*
* Intructions:
* By: Ben Griffiths, ben@ben-griffiths.com
* Version: 1.4.3
*
* Dependencies:
*
* jquery-cookie 1.0.0 (Relies on the jQuery Cookie plugin https://github.com/carhartl/jquery-cookie)
* - Included.
*
*******************************************************************************
*
* Licensed under The MIT License (MIT)
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.opensource.org/licenses/mit-license.php
*
* Copyright (c) 2011 Ben Griffiths (mail@thecodefoundryltd.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*******************************************************************************
*/
(function(e){e.fn.sayt=function(t){function l(t){var r="";jQuery.each(t,function(e,t){r=r+t.name+":::--FIELDANDVARSPLITTER--:::"+t.value+":::--FORMSPLITTERFORVARS--:::"});e.cookie(s,r,{expires:n["days"]});if(typeof Storage!=="undefined"){localStorage.setItem(s,r)}else{e.cookie(s,r,{expires:n["days"]})}}function c(e,t,n){var r=(e+"").indexOf(t,n||0);return r===-1?false:r}function h(t,n){var r=e.extend({},t);var s=r.find("[data-sayt-exclude]");s.remove();for(i in n){s=r.find(n[i]);s.remove()}var o=r.serializeArray();return o}var n=e.extend({prefix:"autosaveFormCookie-",erase:false,days:3,autosave:true,savenow:false,recover:false,autorecover:true,checksaveexists:false,exclude:[]},t);var r=this;var s=n.prefix+r.attr("id");if(n["erase"]==true){e.cookie(s,null);if(typeof Storage!=="undefined"){localStorage.removeItem(s)}else{e.cookie(s,null)}return true}var o;if(typeof Storage!=="undefined"){o=localStorage.getItem(s)}else{o=e.cookie(s)}if(n["checksaveexists"]==true){if(o){return true}else{return false}return false}if(n["savenow"]==true){var u=h(r,n["exclude"]);l(u);return true}if(n["autorecover"]==true||n["recover"]==true){if(o){var a=o.split(":::--FORMSPLITTERFORVARS--:::");var f={};e.each(a,function(t,n){var r=n.split(":::--FIELDANDVARSPLITTER--:::");if(e.trim(r[0])!=""){if(e.trim(r[0])in f){f[e.trim(r[0])]=f[e.trim(r[0])]+":::--MULTISELECTSPLITTER--:::"+r[1]}else{f[e.trim(r[0])]=r[1]}}});e.each(f,function(t,n){if(c(n,":::--MULTISELECTSPLITTER--:::")>0){var r=n.split(":::--MULTISELECTSPLITTER--:::");e.each(r,function(n,r){e('input[name="'+t+'"], select[name="'+t+'"], textarea[name="'+t+'"]').find('[value="'+r+'"]').prop("selected",true);e('input[name="'+t+'"][value="'+r+'"], select[name="'+t+'"][value="'+r+'"], textarea[name="'+t+'"][value="'+r+'"]').prop("checked",true)})}else{e('input[name="'+t+'"], select[name="'+t+'"], textarea[name="'+t+'"]').val([n])}})}if(n["recover"]==true){return true}}if(n["autosave"]==true){this.find("input, select, textarea").each(function(t){e(this).change(function(){var e=h(r,n["exclude"]);l(e)});e(this).keyup(function(){var e=h(r,n["exclude"]);l(e)})})}}})(jQuery)
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