mirror of
https://gitlab.com/t6353/sharee.bike.git
synced 2024-11-15 23:26:34 +01:00
1502 lines
52 KiB
Perl
Executable file
1502 lines
52 KiB
Perl
Executable file
package DBtank;
|
|
#
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
# Copyright (c) Rainer Gümpelein, TeilRad GmbH
|
|
#
|
|
use strict;
|
|
use warnings;
|
|
use POSIX;
|
|
use DBI;
|
|
use DBI::Const::GetInfoType;
|
|
use CGI ':standard';
|
|
use Lib::Config;
|
|
use Mod::Basework;
|
|
use Scalar::Util qw(looks_like_number);
|
|
use Config::General;
|
|
use Data::Dumper;
|
|
|
|
my $cf = new Config;
|
|
my $bw = new Basework;
|
|
my $q = new CGI;
|
|
$q->import_names('R');
|
|
my $debug = 1;
|
|
|
|
sub new {
|
|
my $class = shift;
|
|
my $self = {};
|
|
|
|
my $globalconf_file = "/var/www/copri4/shareeconf/global.cfg";
|
|
my $conf = Config::General->new($globalconf_file);
|
|
my %globalconf = $conf->getall;
|
|
$self = \%globalconf;
|
|
|
|
bless($self,$class);
|
|
return $self;
|
|
}
|
|
|
|
my $today = strftime("%d.%m.%Y",localtime(time));
|
|
my $date_time = strftime("%d.%m.%Y %H:%M",localtime(time));
|
|
my %varenv = $cf->envonline();
|
|
|
|
#dbconnect_intern, on default $dbh_intern will be used
|
|
my $dbh_intern = &dbconnect("");
|
|
sub dbconnect {
|
|
my $self = shift;
|
|
my $options ="";
|
|
my $database = "dbi:Pg:dbname=$varenv{dbname};host=$varenv{dbhost};port=5432;options='$options'";
|
|
my $dbh = DBI->connect($database, $varenv{dbuser}, $varenv{dbpassw},{ RaiseError => 1, AutoCommit => 1 }) or die "Can't connect to $varenv{dbname}: $DBI::errstr";
|
|
my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
#$bw->log("--> dbconnect_intern --> $varenv{syshost} $source",$database,"");
|
|
return $dbh if($dbh);
|
|
}
|
|
|
|
|
|
#dbconnect_extern for copri operator instance
|
|
sub dbconnect_extern {
|
|
my $self = shift;
|
|
my $dbname = shift;
|
|
my $instance_type = "operator";
|
|
$instance_type = "primary" if($dbname eq "sharee_primary");
|
|
|
|
my $globalconf_file = "/var/www/copri4/shareeconf/global.cfg";
|
|
my $conf = Config::General->new($globalconf_file);
|
|
my %globalconf = $conf->getall;
|
|
|
|
$bw->log("dbconnect_extern call with instance_type:$instance_type and copri_instance:",$dbname,"");
|
|
|
|
#keep in mind, only one DB can be returned by this way
|
|
#while (my ($key, $value) = each %{ $self->{$instance_type} }) {
|
|
while (my ($key, $value) = each %{ $globalconf{$instance_type} }) {
|
|
if($key eq $dbname){
|
|
$bw->log("dbconnect_XX",$value->{database}->{dbname},"");
|
|
my $database = "dbi:Pg:dbname=$value->{database}->{dbname};host=$value->{database}->{host};port=$value->{database}->{port};options='$value->{database}->{options}'";
|
|
$database .= ";sslmode=$value->{database}->{sslmode}" if($value->{database}->{sslmode} && $value->{database}->{host} ne "localhost");
|
|
my $dbh = DBI->connect($database, $value->{database}->{user}, $value->{database}->{passwd},{ RaiseError => 0, AutoCommit => 1 });
|
|
$bw->log("--> dbconnect_extern success --> $database, $value->{database}->{user}, $value->{database}->{passwd}",$database,"");
|
|
return $dbh if($dbh);
|
|
}
|
|
}
|
|
$bw->log("ERROR, dbconnect_extern call with dbname: $dbname |instance_type:$instance_type","","");
|
|
return "";
|
|
}
|
|
|
|
#get operator conf by oprefix
|
|
sub get_operator_conf {
|
|
my $self = shift;
|
|
my $oprefix = shift || "";
|
|
|
|
my $globalconf_file = "/var/www/copri4/shareeconf/global.cfg";
|
|
my $conf = Config::General->new($globalconf_file);
|
|
my %globalconf = $conf->getall;
|
|
|
|
while (my ($key, $operator) = each %{ $globalconf{operator} }) {
|
|
if($oprefix && $oprefix eq $operator->{oprefix}){
|
|
$bw->log("get operator conf by oprefix: $oprefix",$operator->{oprefix},"");
|
|
return $operator;
|
|
}
|
|
}
|
|
$bw->log("Cannot get operator conf by oprefix: $oprefix","","");
|
|
return 0;
|
|
}
|
|
|
|
#get dbname because varenv{dbname} seems not stable
|
|
sub get_dbname {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
return $source;
|
|
}
|
|
|
|
|
|
#loop extern operator db's for specific tablefield sync
|
|
sub update_operatorsloop {
|
|
my $self = shift;
|
|
my $dbname = shift || "";
|
|
my $adrc_id = shift || 0;
|
|
my $todo = shift || "update";
|
|
|
|
use DBI::Const::GetInfoType;
|
|
my $authref = {
|
|
table => "contentadr",
|
|
fetch => "one",
|
|
template_id => "202",
|
|
c_id => "$adrc_id",
|
|
};
|
|
my $dbh_primary = $self->dbconnect_extern("sharee_primary");
|
|
my $source_primary = $dbh_primary->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
my $record_primary = { c_id => 0 };
|
|
$record_primary = $self->fetch_record($dbh_primary,$authref) if($adrc_id && $adrc_id > 0);
|
|
|
|
$bw->log("update_operatorsloop by copri_instance-dbname: $dbname | owner: $record_primary->{owner} | get_info-dbname: $source_primary","","");
|
|
|
|
my $rows = 0;
|
|
if($record_primary->{c_id}){
|
|
|
|
my %operator_hash = ();
|
|
#keep in mind, shareedms-operators updates sharee_primary, that's because we have to also loop
|
|
#if($dbname eq "sharee_primary"){
|
|
if($record_primary->{txt17}){
|
|
if($record_primary->{txt17} =~ /\w\s\w/){
|
|
%operator_hash = map { $_ => "$self->{operator}{$_}->{operatorApp}" } split(/\s+/,$record_primary->{txt17});
|
|
}else{
|
|
%operator_hash = ( "$record_primary->{txt17}" => "$self->{operator}{$record_primary->{txt17}}->{operatorApp}" );
|
|
}
|
|
foreach my $sharee_operator (keys (%operator_hash)){
|
|
if($sharee_operator =~ /sharee_/){
|
|
$sharee_operator =~ s/\s//g;
|
|
my $dbh_operator = $self->dbconnect_extern("$sharee_operator");
|
|
if($todo eq "update"){
|
|
|
|
#this will be saved by operator DMS and have to keep intividual
|
|
$bw->log("disabled condition: if($sharee_operator ne $dbname || $record_primary->{owner} == 197 || $dbname eq \"sharee_primary\"","","");
|
|
#if($sharee_operator ne "$dbname" || $record_primary->{owner} == 197 || $dbname eq "sharee_primary"){
|
|
delete $record_primary->{txt17};#operators
|
|
delete $record_primary->{txt30} if($dbname ne "sharee_lv" && $record_primary->{txt30} ne "5511");#Tarif, exception sharee_lv;#Tarif
|
|
delete $record_primary->{txt15};#Bonusnr
|
|
delete $record_primary->{int07};#Rabatt
|
|
delete $record_primary->{txt18};#Service tour
|
|
delete $record_primary->{int05};#Web-Login
|
|
delete $record_primary->{int16};#payone-cron-interval
|
|
delete $record_primary->{int19};#Ilockit Admin
|
|
#delete $record_primary->{int12};#Vde (remove delete for global setting)
|
|
delete $record_primary->{int23};#mini_answer count will be saved on operator
|
|
delete $record_primary->{txt29};#Sonstiges
|
|
#}
|
|
|
|
my $update = {
|
|
%$record_primary,
|
|
table => "contentadr",
|
|
};
|
|
$bw->log("--> save_account update_operatorsloop $sharee_operator by $source_primary",$update->{c_id},"");
|
|
|
|
$bw->log("UPDATE adr from record_primary to operator on loop $sharee_operator",$record_primary->{c_id},"");
|
|
$rows = $self->update_record($dbh_operator,$update,$record_primary);
|
|
if($rows != 1){
|
|
$bw->log("INSERT adr from record_primary to operator on loop $sharee_operator",$record_primary->{c_id},"");
|
|
my $insert = {
|
|
%$record_primary,
|
|
table => "contentadr",
|
|
mtime => 'now()',
|
|
};
|
|
#owner => "198",
|
|
|
|
my $c_id = $self->insert_contentoid($dbh_operator,$insert,"");
|
|
$rows = 1 if($c_id);
|
|
#pseudo code copied fom net_booking. have to be done elsewehre because of $apif
|
|
if(1==2){
|
|
my $ctadr = { c_id => $c_id };
|
|
my ($bike_group,$bike_node,$user_tour,$tariff_content,$adrtarif_hash);# = $apif->fetch_tariff($ctadr,"");
|
|
foreach my $id (keys (%$tariff_content)){
|
|
# #int18
|
|
#<sharing_type>
|
|
# 2 = "public"
|
|
# 3 = "private"
|
|
# 4 = "hidden-lv"
|
|
#</sharing_type>
|
|
my $update_op = {
|
|
table => "contentadr",
|
|
};
|
|
if($tariff_content->{$id}->{int18} && ($tariff_content->{$id}->{int18} == 2 || $tariff_content->{$id}->{int18} == 3 || $tariff_content->{$id}->{int18} == 4)){
|
|
#if($tariff_content->{$id}->{int12} && $tariff_content->{$id}->{int12} == $ct->{main_id} && $tariff_content->{$id}->{barcode}){
|
|
$update_op->{txt30} = $tariff_content->{$id}->{barcode};
|
|
$rows = $self->update_record($dbh_operator,$update,$ctadr);
|
|
#}
|
|
}
|
|
}
|
|
}#end of reminder
|
|
|
|
}
|
|
}elsif($todo eq "delete"){
|
|
$bw->log("DELETE adr from operators and at last primary $sharee_operator",$record_primary,"");
|
|
$rows += $self->delete_content($dbh_operator,"contentadr",$record_primary->{c_id});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#}
|
|
}
|
|
return $rows;
|
|
}
|
|
|
|
#return system and contentadr username by c_id (owner last change)
|
|
sub sys_username {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $owner = shift || "";
|
|
my $u_name = "";
|
|
|
|
if(looks_like_number($owner)){
|
|
my $channel_map = $self->channel_map();
|
|
|
|
foreach my $id (sort { $channel_map->{$a} cmp $channel_map->{$b} } keys (%$channel_map)){
|
|
if($id == $owner){
|
|
$u_name = $channel_map->{$id};
|
|
}
|
|
}
|
|
|
|
if(!$u_name){
|
|
my $users_pref = {
|
|
table => "contentadr",
|
|
fetch => "one",
|
|
c_id => $owner,
|
|
};
|
|
my $ct_users = $self->fetch_tablerecord($dbh,$users_pref);
|
|
$u_name = $ct_users->{txt01};
|
|
}
|
|
|
|
}
|
|
return $u_name;
|
|
}
|
|
|
|
#collect serviceapp and DMS users for search select username u_id mapping
|
|
sub users_map(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $mapref = shift || "";
|
|
|
|
my $and = "";
|
|
if(ref($mapref) eq "HASH"){
|
|
foreach my $key (keys (%$mapref)){
|
|
$and = " and u.$key=$mapref->{$key}" if($key =~ /int/);
|
|
}
|
|
}
|
|
|
|
my $sql = "SELECT ct.* FROM contentadr ct, users u WHERE ct.c_id=u.u_id $and";
|
|
my $sth = $dbh->prepare($sql);
|
|
my $rc = $sth->execute();
|
|
my $users_rec = $sth->fetchall_hashref('c_id');
|
|
$bw->log("DBtank users_map:",$sql,"") if($debug);
|
|
|
|
return $users_rec;
|
|
}
|
|
|
|
|
|
#booking channel id's
|
|
#TODO migrate all to global.cfg <merchant_ids>
|
|
sub channel_map(){
|
|
my $self = shift;
|
|
my $channel = {
|
|
167 => "sig cmd",
|
|
168 => "shareeio",
|
|
169 => "sigo connector",
|
|
172 => "reserve timeout",
|
|
#173 => "merchant fallback",#mig
|
|
#175 => "example App",#mig
|
|
176 => "Mein konrad App",#mig
|
|
177 => "LastenradBay App",#mig
|
|
179 => "cronjob",
|
|
178 => "payone API",
|
|
#181 => "SMS API",
|
|
#182 => "velofactur API",
|
|
183 => "Ilockit API",
|
|
#184 => "web App",#mig
|
|
#185 => "konstanz App",#mig
|
|
186 => "sharee.bike App",#mig
|
|
187 => "shareetool",#mig
|
|
188 => "sys API",
|
|
192 => "web Bayern",
|
|
#193 => "web demo",#mig
|
|
#194 => "web example",#mig
|
|
195 => "web konrad",#mig and import
|
|
196 => "copri",#mig
|
|
197 => "web sharee.bike",#mig
|
|
198 => "primary",#mig
|
|
199 => "LV API",#mig
|
|
201 => "web Renta",#mig
|
|
};
|
|
return $channel;
|
|
}
|
|
|
|
|
|
#get tpl
|
|
sub get_tpl {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $tpl_id = shift || 0;
|
|
my $sth = $dbh->prepare("SELECT * FROM template WHERE tpl_id='$tpl_id'");
|
|
my $rc = $sth->execute();
|
|
my $tpl = $sth->fetchrow_hashref();
|
|
return $tpl;
|
|
}
|
|
|
|
#get uri_path and meta data like tpl_order by menue path
|
|
sub get_node_meta {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $viewsel = shift;
|
|
my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
|
|
my $node_name1 = $q->escapeHTML(@{$viewsel}[-1]);
|
|
my @node_path = ("$node_name1");
|
|
|
|
my $where = "WHERE n.main_id=rel.main_id and rel.template_id=tpl.tpl_id and node_name = '$node_name1'";
|
|
pop @{$viewsel};
|
|
my @reverse_viewsel = reverse(@{$viewsel});
|
|
#print Dumper(@reverse_viewsel) . "<br>\n";
|
|
|
|
#bsp
|
|
#SELECT * FROM nodes n,relation rel, template tpl WHERE n.main_id=rel.main_id and rel.template_id=tpl.tpl_id and n.node_name = 'Firma' and n.parent_id IN (SELECT n.main_id from nodes n where n.node_name='Einstellung' and n.parent_id IN (SELECT n.main_id from nodes n where n.node_name='JBW'));
|
|
|
|
foreach(@reverse_viewsel){
|
|
#print $_ . "<br>\n";
|
|
my $node_nameX = $q->escapeHTML($_);
|
|
push(@node_path, $node_nameX);
|
|
$where .= " and n.parent_id IN (SELECT n.main_id from nodes n where n.node_name='$node_nameX'";
|
|
}
|
|
|
|
foreach(@reverse_viewsel){
|
|
$where .= ")";
|
|
}
|
|
my $sql = "SELECT * FROM nodes n,relation rel, template tpl $where";
|
|
my $sth = $dbh->prepare($sql);
|
|
my $rc = $sth->execute();
|
|
my $nrt = $sth->fetchrow_hashref();
|
|
|
|
my @reverse_node_path = reverse(@node_path);
|
|
my $uri_path = "";
|
|
foreach(@reverse_node_path){
|
|
$uri_path .= "$_/";
|
|
}
|
|
$uri_path =~ s/\/$//;
|
|
$bw->log("get_node_meta $uri_path | $source",$sql,"") if($debug);
|
|
#print Dumper($nrt);
|
|
return $nrt;
|
|
}
|
|
|
|
sub get_node {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $main_id = shift;
|
|
my $sth = $dbh->prepare("SELECT * FROM nodes WHERE main_id=$main_id");
|
|
my $rc = $sth->execute();
|
|
my $node = $sth->fetchrow_hashref();
|
|
return $node;
|
|
}
|
|
|
|
# Nodes einer Ebene
|
|
sub collect_node {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $main_id = shift;
|
|
my $sth = $dbh->prepare("SELECT * FROM nodes WHERE parent_id=$main_id");
|
|
my $rc = $sth->execute();
|
|
my $nodes = $sth->fetchall_hashref("main_id");
|
|
my $rows = $sth->rows;
|
|
return ($nodes,$rows);
|
|
}
|
|
|
|
# Nodes einer Ebene mit relation
|
|
sub collect_noderel {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $main_id = shift;
|
|
my $template_id = shift || "";
|
|
#my $where = "WHERE n.main_id=rel.main_id and rel.content_id=0 and n.parent_id=$main_id";
|
|
my $where = "WHERE n.main_id=rel.main_id and rel.content_id=0 and n.parent_id=$main_id and node_public='t'";
|
|
$where .= " and rel.template_id=$template_id" if($template_id);
|
|
my $sth = $dbh->prepare("SELECT * FROM nodes n, relation rel $where");
|
|
my $rc = $sth->execute();
|
|
my $nodes = $sth->fetchall_hashref("main_id");
|
|
my $rows = $sth->rows;
|
|
return ($nodes,$rows);
|
|
}
|
|
|
|
#recursive node runner to get node path
|
|
sub recurse_select {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $main_id = shift || "";
|
|
my $sth = $dbh->prepare("SELECT parent_id,node_name FROM nodes where main_id=$main_id");
|
|
my $rc = $sth->execute();
|
|
my $node = $sth->fetchrow_hashref();
|
|
return ($node->{parent_id},$node->{node_name});
|
|
}
|
|
sub recurse_node {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $main_id = shift || "";
|
|
my $depth=$1 if($main_id =~ /^(\d)/);
|
|
my $uri_path = "?failure=recurse_node";
|
|
my @nodes = ();
|
|
if($main_id && $main_id > 20000){
|
|
$uri_path = "";
|
|
for(my $i=0; $i<$depth;$i++){
|
|
($main_id,my $node_name) = $self->recurse_select($dbh,$main_id) if($main_id);
|
|
push(@nodes, $node_name);
|
|
#print $main_id . "|$node_name\n";
|
|
}
|
|
my @node_path = reverse(@nodes);
|
|
foreach(@node_path){
|
|
$uri_path .= "$_/";
|
|
}
|
|
$uri_path =~ s/\/$//;
|
|
}
|
|
return $uri_path;
|
|
}
|
|
###############################
|
|
|
|
|
|
#get one subnode
|
|
#ex. get contentpos template_id from subnode
|
|
#select n.n_id,n.parent_id,n.main_id,rel.template_id from nodes n, relation rel where n.main_id=rel.main_id and n.parent_id=300029;
|
|
# n_id | parent_id | main_id | template_id
|
|
#------+-----------+---------+-------------
|
|
# 431 | 300029 | 400004 | 401
|
|
sub get_subrelnode {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $main_id = shift;
|
|
my $template_id = shift || "";
|
|
my $node_name = shift || "";
|
|
my $where = "";
|
|
$where .= " and rel.template_id = $template_id" if($template_id);
|
|
$where .= " and n.node_name = '$node_name'" if($node_name);
|
|
my $sql = "SELECT * FROM nodes n, relation rel where n.main_id=rel.main_id and n.parent_id=$main_id $where";
|
|
my $sth = $dbh->prepare($sql);
|
|
my $rc = $sth->execute();
|
|
my $node = $sth->fetchrow_hashref();
|
|
$bw->log("get_subrelnode",$sql,"");
|
|
return $node;
|
|
}
|
|
|
|
#because of different and dynamic pos templates we need template grouping
|
|
sub pos_template_group {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $fetch = shift;
|
|
my $ctcp_where = "1=1";
|
|
|
|
if($fetch->{table} eq "content" && $fetch->{table_pos} eq "contentpos"){
|
|
$ctcp_where .= " and ct.c_id=cp.cc_id";
|
|
}elsif($fetch->{table} eq "contentadr" && $fetch->{table_pos} eq "contentadrpos"){
|
|
$ctcp_where .= " and ct.c_id=cp.ca_id";
|
|
}
|
|
|
|
my $sql = "SELECT tpl_id,tpl_order from template where tpl_id IN (SELECT cp.template_id from $fetch->{table_pos} cp, $fetch->{table} ct where $ctcp_where group by cp.template_id)";
|
|
|
|
my $sth = $dbh->prepare($sql);
|
|
my $rc = $sth->execute();
|
|
my $templates = $sth->fetchall_hashref("tpl_id");
|
|
|
|
$bw->log("pos_template_group",$sql,"");
|
|
return $templates;
|
|
}
|
|
|
|
#fetch relation, template, nodes
|
|
sub fetch_rel4tpl4nd(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $fetch = shift;
|
|
my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
|
|
$fetch->{content_id}=0 if($fetch->{content_id} eq "null");
|
|
my $where = "WHERE nodes.main_id=relation.main_id and relation.template_id=template.tpl_id";
|
|
$where .= " and nodes.parent_id=$fetch->{parent_id}" if($fetch->{parent_id});
|
|
$where .= " and relation.main_id=$fetch->{main_id}" if($fetch->{main_id});
|
|
$where .= " and relation.content_id=$fetch->{content_id}" if($fetch->{content_id});
|
|
$where .= " and relation.template_id=$fetch->{template_id}" if($fetch->{template_id});
|
|
if($fetch->{template_id1} && $fetch->{template_id2}){
|
|
$where .= " and relation.template_id >= $fetch->{template_id1} and relation.template_id <= $fetch->{template_id2}";
|
|
}
|
|
$where .= " and relation.rel_id=$fetch->{rel_id}" if($fetch->{rel_id});
|
|
$where .= " order by content_id $fetch->{ascdesc}" if($fetch->{ascdesc});
|
|
|
|
my $sql = "SELECT * FROM relation,template,nodes $where";
|
|
my $sth = $dbh->prepare($sql);
|
|
my $rc = $sth->execute();
|
|
|
|
my $rel = { main_id => 0 };
|
|
if($fetch->{fetch} eq "all" && $fetch->{keyfield}){
|
|
$rel = $sth->fetchall_hashref($fetch->{keyfield});
|
|
}else{
|
|
$rel = $sth->fetchrow_hashref();
|
|
}
|
|
#$bw->log("fetch_rel4tpl4nd $source",$sql,"") if($debug);
|
|
|
|
return $rel;
|
|
}
|
|
|
|
#azn time worktime from Von Bis
|
|
sub select_worktime {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $fetch = shift;
|
|
|
|
my $sql = "SELECT $fetch->{end_at} - $fetch->{start_at} AS worktime FROM $fetch->{table} where ct_id = $fetch->{ct_id} and barcode = $fetch->{barcode} and $fetch->{end_at} is not null and $fetch->{start_at} is not null";
|
|
my $sth = $dbh->prepare($sql);
|
|
my $rc = $sth->execute();
|
|
my $record = $sth->fetchrow_hashref();
|
|
$bw->log("DBtank select_worktime: ",$sql,"") if($debug);
|
|
|
|
return $record;
|
|
}
|
|
|
|
#all position of contenttrans
|
|
sub collect_contentpos(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $table = shift;
|
|
my $ct_id = shift || "";
|
|
my $where = "where ctt.c_id=pos.ct_id and ctt.c_id='$ct_id'";
|
|
|
|
if($ct_id){
|
|
my $sth = $dbh->prepare("SELECT pos.* FROM contenttranspos pos, contenttrans ctt $where");
|
|
my $rc = $sth->execute();
|
|
my $cpos = $sth->fetchall_hashref("c_id");
|
|
my $rows = $sth->rows;
|
|
return ($cpos,$rows);
|
|
}else{
|
|
my $cpos = { c_id => 0 };
|
|
my $rows = 0;
|
|
return ($cpos,$rows);
|
|
}
|
|
}
|
|
|
|
#Collect table ...post
|
|
sub collect_post(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $fetch = shift;
|
|
my $count = shift || "";
|
|
|
|
my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
my $table;
|
|
my $table_pos;
|
|
my $ct_where = "1=1";
|
|
my $cp_where = "1=1";
|
|
my $ctcp_where = "1=1";
|
|
my $poscid = "";
|
|
|
|
if($fetch->{table} eq "content" && $fetch->{table_pos} eq "contentpos"){
|
|
#*2
|
|
$ctcp_where .= " and ct.c_id=cp.cc_id";
|
|
$poscid = "cp.cc_id";
|
|
}elsif($fetch->{table} eq "contentadr" && $fetch->{table_pos} eq "contentadrpos"){
|
|
#*1
|
|
$ctcp_where .= " and ct.c_id=cp.ca_id";
|
|
$poscid = "cp.ca_id";
|
|
}elsif(($fetch->{table} eq "contenttrans" && $fetch->{table_pos} eq "contenttranspos") || ($fetch->{table} eq "contenttver" && $fetch->{table_pos} eq "contenttverpos")){
|
|
#*3
|
|
$ctcp_where .= " and ct.c_id=cp.ct_id";
|
|
$poscid = "cp.ct_id";
|
|
}else{
|
|
return;
|
|
}
|
|
|
|
foreach my $key (keys %$fetch){
|
|
if($fetch->{$key}){
|
|
$fetch->{$key} =~ s/^\s//g;
|
|
$fetch->{$key} =~ s/\s$//g;
|
|
my $op = "=";
|
|
my $value = $fetch->{$key};
|
|
($op, $value) = split(/::/, $fetch->{$key}) if($fetch->{$key} =~ /::/);
|
|
if($key =~ /^(ct_name|txt\d+)$/ && $value){
|
|
if($op eq "IN"){
|
|
$cp_where .= " and cp.$key $op $value";
|
|
}else{
|
|
if($key eq "txt01" && $value =~ /NaN/){
|
|
$cp_where .= " and $value";
|
|
}else{
|
|
$cp_where .= " and cp.$key $op '$value'";
|
|
}
|
|
}
|
|
}elsif($key =~ /ct\.close_time|ct\.state|ct\.int14/ && $value){#used to get open invoices
|
|
$ct_where .= " and $key $op $value";
|
|
}elsif($key =~ /time/ && $value){
|
|
if($value =~ /interval/){
|
|
$cp_where .= " and cp.$key $op $value";#format like (now() - integer '7 day')
|
|
}elsif($key eq "time_range"){
|
|
$cp_where .= " and $value";#look at only_first_free
|
|
}else{
|
|
$cp_where .= " and cp.$key $op '$value'";
|
|
}
|
|
}elsif($varenv{systype} && $varenv{systype} eq "azn"){
|
|
if($key =~ /^ct\.(contentadr_id|owner|barcode|int\d+)$/ && $value){
|
|
$ct_where .= " and $key $op $value";
|
|
}elsif($key eq "barcode" && $fetch->{fetch} eq "all"){
|
|
if($value =~ /\d-\d/){
|
|
my ($start_val,$end_val) = split(/-/, $value);
|
|
$cp_where .= " and (cp.$key >= $start_val AND cp.$key <= $end_val)";
|
|
}else{
|
|
my $start_val = $value . "01";
|
|
my $end_val = $value . "31";
|
|
$cp_where .= " and (cp.$key >= $start_val AND cp.$key <= $end_val)";
|
|
}
|
|
}elsif($key =~ /^(c_id|ca_id|ct_id|owner|barcode|int\d+)$/ && $value){
|
|
$cp_where .= " and cp.$key $op $value";
|
|
}
|
|
#}
|
|
#selects also push event=RENTAL_END station_lock_state bikes to view feedback and miniquery
|
|
#elsif($key eq "int10" && $value eq "('3','2')" && $fetch->{show_dialog}){
|
|
# $cp_where .= " and (cp.$key $op $value OR cp.int28 = 3)";#select only if no dialog saved
|
|
}elsif($key =~ /^(c_id|ca_id|ct_id|owner|barcode|int\d+)$/ && $value){
|
|
$cp_where .= " and cp.$key $op $value";
|
|
}elsif($fetch->{catch} && $key eq "template_id" && $value){
|
|
$cp_where .= " and cp.$key $op $value";
|
|
}elsif(!$fetch->{catch} && $key =~ /main_id|template_id/ && $value){
|
|
$ct_where .= " and rel.$key $op $value";
|
|
}
|
|
}
|
|
}
|
|
|
|
my $sth = "";
|
|
my $sql = "";
|
|
my $limit = "";
|
|
$limit = "LIMIT $count" if(looks_like_number($count));
|
|
if($fetch->{catch} && $fetch->{catch} eq "content_contentpos"){
|
|
$sql = "SELECT cp.* from $fetch->{table_pos} cp, $fetch->{table} ct where $ctcp_where and $cp_where and $ct_where order by cp.mtime DESC $limit";
|
|
$sth = $dbh->prepare($sql);
|
|
}else{
|
|
#rental pos with capture booking ct.state
|
|
$sql = "SELECT cp.*, ct.state FROM $fetch->{table_pos} cp, $fetch->{table} ct WHERE $cp_where and cp.ct_id=ct.c_id and $poscid IN (SELECT ct.c_id FROM relation rel, $fetch->{table} ct WHERE rel.content_id=ct.c_id and $ct_where) order by cp.mtime ASC";#mtime aufsteigend get last (newest) entry
|
|
$sth = $dbh->prepare($sql);
|
|
}
|
|
#$bw->log("DBtank collect_post $source",$sql,"") if($debug);
|
|
my $rc = $sth->execute();
|
|
|
|
my $record = { c_id => 0 };
|
|
if($fetch->{fetch} eq "all" && $fetch->{keyfield}){
|
|
$record = $sth->fetchall_hashref($fetch->{keyfield});
|
|
}elsif($fetch->{fetch} eq "one"){
|
|
$record = $sth->fetchrow_hashref();
|
|
}
|
|
return $record;
|
|
}
|
|
|
|
#fetch all|one content + relation + nodes
|
|
sub fetch_record(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $fetch = shift;
|
|
my $fetch_sql = shift || "";
|
|
my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
|
|
my $where = "where ct.c_id=rel.content_id and nd.main_id=rel.main_id";
|
|
$where .= "$fetch_sql" if($fetch_sql);#enhancement to get bike_group OR
|
|
my $order = "";
|
|
|
|
foreach my $key (keys %$fetch){
|
|
if($fetch->{$key}){
|
|
$fetch->{$key} =~ s/^\s//g;
|
|
$fetch->{$key} =~ s/\s$//g;
|
|
my $op = "=";
|
|
my $value = $fetch->{$key};
|
|
($op, $value) = split(/::/, $fetch->{$key}) if($fetch->{$key} =~ /::/);
|
|
#$value = $q->escapeHTML($value);#In DB context will always done by API
|
|
#can also be "rel.main_id IN (300005,300024)"
|
|
$where .= " and rel.$key $op $value" if($key =~ /^(parent_id|main_id|template_id|rel_id)$/ && $value);
|
|
if($key =~ /^(ct_name$|txt\d+|uri\d+|state)$/ && $value){
|
|
if($value =~ /length/){
|
|
$where .= " and $value";
|
|
}elsif($value eq "null"){
|
|
$where .= " and (ct.$key is null OR ct.$key = '')";
|
|
}else{
|
|
$where .= " and ct.$key $op '$value'";
|
|
}
|
|
}
|
|
if($key =~ /^(c_id|barcode|int\d+|owner|contentadr_id)$/){
|
|
if(looks_like_number($value) || $value eq "null"){
|
|
if($value eq "null"){
|
|
$where .= " and (ct.$key is null OR ct.$key = 0)";
|
|
}else{
|
|
$where .= " and ct.$key $op $value";
|
|
}
|
|
}elsif($op eq "IN"){
|
|
$where .= " and ct.$key $op $value";
|
|
}
|
|
}
|
|
if($key =~ /^(type_id)$/){
|
|
if(looks_like_number($value)){
|
|
$where .= " and nd.$key $op $value";
|
|
}
|
|
}
|
|
|
|
if($varenv{systype} && $varenv{systype} eq "azn" && $key =~ /start_time|end_time/){
|
|
if($key =~ /start_time/){
|
|
$where .= " and (ct.end_time >= '$fetch->{start_time}' AND ct.start_time <= '$fetch->{end_time}')";
|
|
$order = " order by ct.start_time DESC";#because to get ct_id for contenttverpos Übertrag
|
|
}
|
|
}elsif($key =~ /close_time$/ && $value){
|
|
$where .= " and ct.$key $op $value";
|
|
}elsif($key =~ /time$/ && $value){
|
|
if($value =~ /interval/){
|
|
$where .= " and ct.$key $op $value";
|
|
}else{
|
|
$where .= " and ct.$key $op '$value'";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#ct.* because of nd.txt01 and ct.txt01 .
|
|
my $sql = "SELECT ct.*,rel.*,nd.node_name,nd.parent_id,nd.type_id,nd.energy_id FROM $fetch->{table} ct, relation rel, nodes nd $where $order";
|
|
my $sth = $dbh->prepare($sql);
|
|
my $rc = $sth->execute();
|
|
#$bw->log("DBtank fetch_record $source: $rc",$sql,"") if($debug);
|
|
|
|
my $record = { c_id => 0 };
|
|
if($fetch->{fetch} eq "all" && $fetch->{keyfield}){
|
|
$record = $sth->fetchall_hashref($fetch->{keyfield});
|
|
}elsif($fetch->{fetch} eq "one"){
|
|
$record = $sth->fetchrow_hashref();
|
|
}
|
|
return $record;
|
|
}
|
|
|
|
#fetch just in one table --> without relation ...
|
|
sub fetch_tablerecord(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my ($fetch) = @_;
|
|
my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
my $where = "where 1=1";
|
|
|
|
foreach my $key (keys %$fetch){
|
|
if($fetch->{$key}){
|
|
$fetch->{$key} =~ s/^\s//g;
|
|
$fetch->{$key} =~ s/\s$//g;
|
|
my $op = "=";
|
|
my $value = $fetch->{$key};
|
|
($op, $value) = split(/::/, $fetch->{$key}) if($fetch->{$key} =~ /::/);
|
|
#print "$key: $fetch->{$key}|$op, $value\n";
|
|
#$value = $q->escapeHTML($value);#In DB context will always done by API
|
|
|
|
if($key =~ /ct_name/ && $value =~ /CAST/){#CAST(c_id AS text)
|
|
$where .= " and $key $op $value";
|
|
}elsif($key =~ /^(ct_name$|txt\d+|uri\d+|state)$/ && $value){
|
|
if($value eq "null"){
|
|
$where .= " and $key $op $value";
|
|
}elsif($op eq "IN"){
|
|
$where .= " and $key $op $value";
|
|
}else{
|
|
$where .= " and $key $op '$value'";
|
|
}
|
|
}elsif($key =~ /_itime$/ && $value){
|
|
$where .= " and itime $op '$value'";
|
|
}elsif($key =~ /start_mtime|end_mtime/ && $value){
|
|
$key =~ s/start_mtime/mtime/;
|
|
$key =~ s/end_mtime/mtime/;
|
|
$where .= " and $key $op '$value'";
|
|
}elsif($key =~ /time$/ && $value && $value =~ /interval/){#<= (now() - interval '15 minutes')
|
|
$where .= " and $key $op $value";
|
|
}elsif($key =~ /time$/ && $value){
|
|
$where .= " and $key $op '$value'";
|
|
}elsif($key =~ /^(c_id|u_id|ct_id|ca_id|barcode|int\d+|owner|template_id)$/ && $value){
|
|
if($value eq "null"){
|
|
$where .= " and ($key is null OR $key = 0)";
|
|
}else{
|
|
$where .= " and $key $op $value";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#prio data with newest end_time
|
|
$where .= " order by end_time DESC" if($fetch->{table} eq "contenttranspos");
|
|
$where .= " order by $fetch->{order} DESC" if($fetch->{order});
|
|
|
|
my $sql = "SELECT * FROM $fetch->{table} $where";
|
|
my $sth = $dbh->prepare($sql);
|
|
my $rc = $sth->execute();
|
|
#$bw->log("DBtank fetch_tablerecord $source:",$sql,"") if($debug);
|
|
|
|
my $record = { c_id => 0 };
|
|
if($fetch->{fetch} eq "all" && $fetch->{keyfield}){
|
|
$record = $sth->fetchall_hashref($fetch->{keyfield});
|
|
}elsif($fetch->{fetch} eq "one"){
|
|
$record = $sth->fetchrow_hashref();
|
|
}
|
|
return $record;
|
|
}
|
|
|
|
#update sql
|
|
sub update_sql(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $update_sql = shift;
|
|
my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
my $rows = 0;
|
|
|
|
my $sql = "$update_sql";
|
|
|
|
my $sth = $dbh->prepare($sql);
|
|
$rows = $sth->execute();
|
|
|
|
$bw->log("DBtank update_sql $source: $rows",$sql,"") if($debug);
|
|
|
|
return $rows;
|
|
|
|
}
|
|
|
|
#update one value
|
|
sub update_one(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $update = shift;
|
|
my $one_in = shift || "";
|
|
my $c_id = shift || "";
|
|
|
|
my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
my $rows = 0;
|
|
my $where = "";
|
|
if($c_id){
|
|
$where = "where c_id = $c_id";
|
|
}elsif($update->{c_id}){
|
|
$where = "where c_id = $update->{c_id}";
|
|
}
|
|
|
|
if($update->{table} eq "users" && $update->{u_id}){
|
|
$where = "where u_id = $update->{u_id}";
|
|
}
|
|
if($update->{table} eq "nodes" && $update->{main_id}){
|
|
$where = "where main_id = $update->{main_id}";
|
|
}
|
|
if($update->{table} eq "relation" && $update->{main_id}){
|
|
$where = "where main_id = $update->{main_id} and content_id=0";
|
|
}
|
|
if($update->{table} eq "relation" && $update->{rel_id}){
|
|
$where = "where rel_id = $update->{rel_id}";
|
|
}
|
|
if($update->{table} eq "template" && $update->{tpl_id}){
|
|
$where = "where tpl_id = $update->{tpl_id}";
|
|
}
|
|
|
|
|
|
my $one = $one_in;
|
|
if($update->{table} =~ /^users|relation|node|template/){
|
|
$one .= ",change='now()'" if($update->{change} ne "no_time");
|
|
}else{
|
|
$one .= ",mtime='now()'" if($update->{mtime} ne "no_time");
|
|
}
|
|
$one .= ",owner=$update->{owner}" if($update->{owner});
|
|
|
|
#only update if input
|
|
if($where && $one_in){
|
|
my $sql = "UPDATE $update->{table} set $one $where";
|
|
my $sth = $dbh->prepare($sql);
|
|
$rows = $sth->execute();
|
|
$bw->log("DBtank update_one $source: $rows",$sql,"") if($debug);
|
|
}
|
|
return $rows;
|
|
}
|
|
|
|
|
|
#update all
|
|
sub update_record(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $update = shift;
|
|
my $record = shift;
|
|
my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
my $where = "";
|
|
my $set = "";
|
|
my $rows = 0;
|
|
|
|
#print Dumper($update);
|
|
if(looks_like_number($record->{c_id}) || (looks_like_number($record->{barcode}) && $record->{barcode} > 0)){
|
|
if($record->{c_id}){
|
|
$where = "where c_id = $record->{c_id}";
|
|
}else{
|
|
$where = "where barcode = $record->{barcode}";
|
|
}
|
|
foreach my $key (keys %$update){
|
|
$update->{$key} =~ s/^\s//g if($update->{$key});
|
|
$update->{$key} =~ s/\s$//g if($update->{$key});
|
|
my $value = $update->{$key} || "";
|
|
$value = "$update->{$key}" if(looks_like_number($update->{$key}));
|
|
if($key =~ /^(ct_name$|txt\d+|state|start_time|end_time|byte)/){
|
|
if($value && $value eq "null"){
|
|
$set .= " $key=$value,";
|
|
}else{
|
|
$set .= " $key='$value',";
|
|
}
|
|
}
|
|
if($key =~ /^(barcode|contentadr_id|int\d+|time\d+|owner|owner_end|start_at\d+|end_at\d+)$/){
|
|
$value =~ s/,/\./ if($value);
|
|
if($key =~ /int\d+|time\d+|start_at\d+|end_at\d+/ && $value && $value =~ /\d+:\d+/){#azn time format
|
|
$set .= " $key='$value',";
|
|
}elsif(looks_like_number($value) || ($value && $value eq "null")){
|
|
$set .= " $key=$value,";
|
|
}elsif($key =~ /int\d+/ && !$value){
|
|
$set .= " $key=null,";#we need this for null values in operators loop
|
|
}
|
|
}
|
|
if($key =~ /(mtime|atime|pay_time|invoice_time)$/){
|
|
if($value && $value =~ /^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}$/){
|
|
$set .= " $key='$value',";
|
|
}else{
|
|
$set .= " $key='now()',";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if($set){
|
|
$set =~ s/,$//;
|
|
my $sql = "UPDATE $update->{table} set $set $where";
|
|
my $sth = $dbh->prepare($sql);
|
|
$rows = $sth->execute();
|
|
$bw->log("DBtank update_record $source: $rows",$sql,"") if($debug);
|
|
}
|
|
return $rows;
|
|
}#update_record
|
|
|
|
#insert content
|
|
sub insert_users {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $u_id = shift;
|
|
my $owner = shift;
|
|
my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
|
|
my $sql = "INSERT INTO users (u_id,itime,mtime,owner) VALUES ('$u_id','now()','now()','$owner')";
|
|
my $sth = $dbh->prepare($sql);
|
|
my $rows = $sth->execute();
|
|
$bw->log("DBtank INSERT DMS users $source $rows",$sql,"") if($debug);
|
|
return $u_id;
|
|
}
|
|
|
|
sub select_users(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $u_id = shift || 0;
|
|
my $sqlcon = shift || "";#used with "and int09=1"
|
|
my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
|
|
my $sql = "SELECT * FROM users WHERE u_id=$u_id $sqlcon";
|
|
my $sth = $dbh->prepare($sql);
|
|
my $rc = $sth->execute();
|
|
my $users = $sth->fetchrow_hashref();
|
|
$bw->log("DBtank SELECT DMS users $source u_id: $users->{u_id}",$sql,"") if($debug);
|
|
return $users;
|
|
}
|
|
|
|
#insert_content with all
|
|
sub insert_contenthash(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $table = shift;
|
|
my $sethash = shift;
|
|
my ($keys,$values);
|
|
if(ref($sethash) eq "HASH"){
|
|
foreach my $key (sort (keys(%$sethash))){
|
|
$keys .= $key . ",";
|
|
$values .= "\'$sethash->{$key}\'" . ",";
|
|
}
|
|
$keys =~ s/,$//;
|
|
$values =~ s/,$//;
|
|
}
|
|
#print "$keys --> $values\n";
|
|
my $sth = $dbh->prepare("INSERT INTO $table ($keys) VALUES ($values)");
|
|
my $rows = $sth->execute();
|
|
return $rows;
|
|
}
|
|
|
|
#insert content
|
|
sub insert_contentoid {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $insert = shift;
|
|
my $reset_keys = shift || "";
|
|
my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
|
|
if($insert->{table} eq "contentadr" && $reset_keys eq "reset_adropkeys"){
|
|
delete $insert->{txt17};#operators
|
|
delete $insert->{txt30} if($source ne "sharee_lv" && $insert->{txt30} ne "5511");#Tarif, exception sharee_lv
|
|
delete $insert->{txt15};#Bonusnr
|
|
delete $insert->{int07};#Rabatt
|
|
delete $insert->{txt18};#Service tour
|
|
delete $insert->{int05};#Web-Login
|
|
delete $insert->{int16};#payone-cron-interval
|
|
delete $insert->{int19};#Ilockit Admin
|
|
#delete $insert->{int12};#Vde (remove delete for global setting)
|
|
delete $insert->{txt29};#Sonstiges
|
|
}
|
|
|
|
my $columns = "";
|
|
my $values = "";
|
|
|
|
foreach my $key (keys(%$insert)){
|
|
$insert->{$key} =~ s/^\s//g if($insert->{$key});
|
|
$insert->{$key} =~ s/\s$//g if($insert->{$key});
|
|
#because of time format without of looks_like_number
|
|
if($varenv{systype} && $varenv{systype} eq "azn" && $insert->{table} eq "contenttverpos" && $key =~ /start_at|end_at|int/){
|
|
$columns .= "$key,";
|
|
if(!$insert->{$key} || $insert->{$key} eq "null"){
|
|
$values .= "null,";
|
|
}else{
|
|
$values .= "'$insert->{$key}',";
|
|
}
|
|
}
|
|
elsif($key =~ /^c_id|ct_name|barcode|txt|int|time|owner/ && ($insert->{$key} || looks_like_number($insert->{$key}))){
|
|
$columns .= "$key,";
|
|
if($key =~ /_id|barcode|int|owner/ && !looks_like_number($insert->{$key})){
|
|
$values .= "null,";
|
|
}else{
|
|
$values .= "'$insert->{$key}',";
|
|
}
|
|
}
|
|
elsif($key =~ /template_id|cc_id|ct_id|ca_id/ && $insert->{table} =~ /contentpos|contentadrpos|contenttranspos/){
|
|
$columns .= "$key,";
|
|
if(!looks_like_number($insert->{$key})){
|
|
$values .= "null,";
|
|
}else{
|
|
$values .= "'$insert->{$key}',";
|
|
}
|
|
}
|
|
}
|
|
|
|
$columns =~ s/,$//;
|
|
$values =~ s/,$//;
|
|
|
|
my $sql = "INSERT INTO $insert->{table} ($columns) VALUES ($values) RETURNING c_id";
|
|
my $sth = $dbh->prepare($sql);
|
|
my $rows = $sth->execute();
|
|
|
|
my $last_id;
|
|
$sth->bind_columns(\$last_id);
|
|
my $c_id = $sth->fetchrow_array();
|
|
$bw->log("insert_contentoid $source c_id: $c_id",$sql,"") if($debug);
|
|
|
|
if($insert->{table} =~ /content$|contentadr$|contenttrans$|contenttver$|contentuser$/ && $insert->{main_id} && $insert->{template_id}){
|
|
my $foreignkey = "";
|
|
$foreignkey = "ca_id" if($insert->{table} eq "contentadr");
|
|
$foreignkey = "cc_id" if($insert->{table} eq "content");
|
|
$foreignkey = "ct_id" if($insert->{table} eq "contenttrans");
|
|
$foreignkey = "cu_id" if($insert->{table} eq "contentuser");
|
|
$foreignkey = "cv_id" if($insert->{table} eq "contenttver");
|
|
my $sql_rel = "INSERT INTO relation (main_id,content_id,template_id,change,$foreignkey) VALUES('$insert->{main_id}','$c_id','$insert->{template_id}','now()','$c_id')";
|
|
my $sth3 = $dbh->prepare($sql_rel);
|
|
$sth3->execute();
|
|
$bw->log("insert_contentoid relation $source c_id: $c_id",$sql_rel,"") if($debug);
|
|
}
|
|
|
|
return $c_id;
|
|
}
|
|
|
|
|
|
#delete content
|
|
sub delete_content(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $table = shift;
|
|
my $c_id = shift || 0;
|
|
my $template_id = shift || "";
|
|
|
|
my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
my $rows = 0;
|
|
if($c_id){
|
|
my $where = "c_id=$c_id";
|
|
$where = "template_id = $template_id" if($table eq "contentpos" && $template_id && $c_id eq "all");
|
|
$where = "u_id=$c_id" if($table eq "users");
|
|
my $sql = "DELETE FROM $table WHERE $where";
|
|
my $sth = $dbh->prepare($sql);
|
|
$rows = $sth->execute();
|
|
$bw->log("delete_content $source: $rows",$sql,"") if($debug);
|
|
}
|
|
return $rows;
|
|
}
|
|
|
|
|
|
#collect contenttranspos with contenttrans
|
|
sub collect_transpos {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $search = shift;
|
|
|
|
$search->{offset} = 0 if(!$search->{offset});
|
|
|
|
my $where = "where cp.ct_id=ct.c_id";
|
|
foreach my $key (keys (%$search)){
|
|
$search->{$key} =~ s/^\s//g;
|
|
$search->{$key} =~ s/\s$//g;
|
|
$where .= " and cp.c_id = $search->{$key}" if(($key eq "c_id" || $key eq "cttpos_id") && $search->{$key});
|
|
$where .= " and cp.$key ilike '%$search->{$key}%'" if($key eq "txt08" && $search->{$key});
|
|
$where .= " and cp.$key ilike '%$search->{$key}%'" if($key eq "txt23" && $search->{$key});
|
|
$where .= " and cp.int04 = $search->{$key}" if($key eq "int04" && looks_like_number($search->{$key}));
|
|
$where .= " and cp.int06 = $search->{$key}" if($key eq "int06" && looks_like_number($search->{$key}));
|
|
$where .= " and cp.ct_name = '$search->{$key}'" if($key eq "cp_ct_name" && $search->{$key});
|
|
$where .= " and ct.ct_name = '$search->{$key}'" if($key eq "ct_ct_name" && $search->{$key});
|
|
$where .= " and ct.txt06 ilike '$search->{$key}%'" if($key eq "ct_txt06" && $search->{$key});
|
|
$where .= " and cp.$key = '$search->{$key}'" if($key eq "ct_id" && looks_like_number($search->{$key}));
|
|
$where .= " and cp.$key = $search->{$key}" if($key eq "int10" && looks_like_number($search->{$key}));
|
|
$where .= " and cp.$key = $search->{$key}" if($key eq "int20" && looks_like_number($search->{$key}));
|
|
$where .= " and cp.$key = $search->{$key}" if($key eq "barcode" && looks_like_number($search->{$key}));
|
|
$where .= " and cp.$key = $search->{$key}" if($key eq "int12" && looks_like_number($search->{$key}));
|
|
$where .= " and (cp.$key = $search->{$key} OR cp.owner_end = $search->{$key})" if($key eq "owner" && looks_like_number($search->{$key}));
|
|
$where .= " and (cp.$key is $search->{$key} OR cp.$key = 0)" if($key eq "int34" && $search->{$key} eq "null");
|
|
}
|
|
|
|
#adding itime to get also not rental dependent entries
|
|
if($search->{start_date_time} && $search->{end_date_time}){
|
|
$where .= " and ((cp.end_time >= '$search->{start_date_time}' and cp.end_time <= '$search->{end_date_time}' and cp.start_time <= '$search->{end_date_time}') OR (cp.itime >= '$search->{start_date_time}' and cp.itime <= '$search->{end_date_time}'))";
|
|
}elsif($search->{start_time_interval}){
|
|
$where .= " and cp.start_time <= $search->{start_time_interval}";
|
|
}
|
|
|
|
$where .= " ORDER BY cp.c_id DESC LIMIT $search->{limit} OFFSET $search->{offset}" if($search->{limit});
|
|
my $sql = "SELECT cp.*,ct.txt07 AS phone from $search->{table} cp, contenttrans ct $where";
|
|
my $sth = $dbh->prepare($sql);
|
|
my $rc = $sth->execute();
|
|
my $ct = $sth->fetchall_hashref("c_id");
|
|
#$bw->log("collect_transpos",$sql,"") if($debug);
|
|
return $ct;
|
|
}
|
|
|
|
#collect contenttheftpos
|
|
sub collect_theftpos {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $search = shift;
|
|
|
|
$search->{offset} = 0 if(!$search->{offset});
|
|
|
|
my $where = "where 1=1";
|
|
foreach my $key (keys (%$search)){
|
|
$search->{$key} =~ s/\s//g;
|
|
$where .= " and cp.c_id = $search->{$key}" if($key eq "cttpos_id" && $search->{$key});
|
|
$where .= " and cp.end_time >= '$search->{$key}'" if($key eq "start_date_time");
|
|
$where .= " and cp.end_time <= '$search->{$key}'" if($key eq "end_date_time");
|
|
$where .= " and cp.start_time <= '$search->{$key}'" if($key eq "end_date_time");
|
|
$where .= " and cp.$key ilike '%$search->{$key}%'" if($key eq "txt06" && $search->{$key});
|
|
$where .= " and cp.$key = $search->{$key}" if($key eq "int10" && looks_like_number($search->{$key}));#bike_state
|
|
$where .= " and cp.$key = $search->{$key}" if($key eq "int20" && looks_like_number($search->{$key}));#lock_state
|
|
$where .= " and cp.$key = $search->{$key}" if($key eq "barcode" && looks_like_number($search->{$key}));
|
|
$where .= " and cp.$key = $search->{$key}" if($key eq "int12" && looks_like_number($search->{$key}));#flot_id
|
|
$where .= " and cp.$key = $search->{$key}" if($key eq "int13" && looks_like_number($search->{$key}));#deviceId
|
|
$where .= " and cp.$key = $search->{$key}" if($key eq "owner" && looks_like_number($search->{$key}));
|
|
}
|
|
$where .= " ORDER BY cp.c_id DESC LIMIT $search->{limit} OFFSET $search->{offset}" if($search->{limit});
|
|
my $sth = $dbh->prepare("SELECT cp.* from $search->{table} cp $where");
|
|
my $rc = $sth->execute();
|
|
my $ct = $sth->fetchall_hashref("c_id");
|
|
$sth->finish;
|
|
return $ct;
|
|
}
|
|
|
|
# new node
|
|
sub insert_nodeoid(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $insert = shift;
|
|
my $node_name = $insert->{node_name};
|
|
my $node_path = $insert->{node_name};
|
|
($node_name,$node_path) = split(/\|/,$node_name) if($node_name =~ /\|/);
|
|
|
|
my $sth2 = $dbh->prepare("INSERT INTO nodes (main_id,parent_id,lang,node_name,node_path,n_sort,owner,node_public) VALUES('$insert->{main_id}','$insert->{parent_id}','$insert->{lang}','$node_name','$node_path','$insert->{n_sort}','$insert->{owner}','t')");
|
|
my $rc = $sth2->execute();
|
|
$sth2 = $dbh->prepare("INSERT INTO relation (main_id,template_id,content_id,lang,change) VALUES('$insert->{main_id}','$insert->{template_id}','$insert->{content_id}','$insert->{lang}','now()') RETURNING rel_id");
|
|
$rc = $sth2->execute();
|
|
|
|
my $last_id;
|
|
$sth2->bind_columns(\$last_id);
|
|
my $rel_id = $sth2->fetchrow_array();
|
|
|
|
return $rel_id;
|
|
}
|
|
|
|
# Delete node and relation! (without content)
|
|
sub delete_noderel(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $main_id = shift;
|
|
|
|
my $sth = $dbh->prepare("DELETE FROM relation WHERE main_id=$main_id and content_id=0");
|
|
my $rc = $sth->execute();
|
|
$sth = $dbh->prepare("DELETE FROM nodes WHERE main_id=$main_id");
|
|
$rc = $sth->execute();
|
|
$sth->finish();
|
|
return $rc;
|
|
}
|
|
|
|
sub delete_template(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $tpl_id = shift;
|
|
my $sth = $dbh->prepare("DELETE FROM template WHERE tpl_id=$tpl_id");
|
|
my $rc = $sth->execute();
|
|
return $rc;
|
|
}
|
|
|
|
# get next free node
|
|
sub get_freenode(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $prefix_id = shift;
|
|
|
|
my $s_id = "$prefix_id";
|
|
my $e_id = "$prefix_id";
|
|
$s_id .= "00001";
|
|
$e_id .= "99999";
|
|
my $main_id = "";
|
|
for (my $x_id=$s_id; $x_id < $e_id; $x_id++){
|
|
my $sth1 = $dbh->prepare("SELECT main_id from nodes where main_id='$x_id'");
|
|
my $rc1 = $sth1->execute();
|
|
$main_id = $sth1->fetchrow_array();
|
|
if(!$main_id){
|
|
return $x_id;
|
|
}
|
|
}
|
|
}
|
|
#
|
|
|
|
# get next free template id
|
|
sub get_freetpl(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my ($s_id,$e_id) = @_;
|
|
my $tpl_id = "";
|
|
for (my $x_id=$s_id; $x_id < $e_id; $x_id++){
|
|
my $sth1 = $dbh->prepare("SELECT tpl_id from template where tpl_id='$x_id'");
|
|
my $rc1 = $sth1->execute();
|
|
$tpl_id = $sth1->fetchrow_array();
|
|
if(!$tpl_id){
|
|
return $x_id;
|
|
}
|
|
}
|
|
}
|
|
#
|
|
|
|
sub rental_description_template {
|
|
my $self = shift;
|
|
my $tpl_order = {
|
|
1 => {int35 => "Mietgebühr"},#unit_price1
|
|
2 => {int36 => "ab 2. Tag"},#unit_price2
|
|
#3 => {int37 => "Grundgebühr"},#startup_price
|
|
4 => {int17 => "Max. Gebühr"},#max_fee/day
|
|
5 => {time01 => "Zeiteinheit"},#unit_time
|
|
6 => {time02 => "Gratis Mietzeit"},#free_time
|
|
7 => {xduration => "Aktuelle Mietzeit"},
|
|
8 => {xprice => "Aktuelle Mietkosten"},
|
|
};
|
|
return $tpl_order;
|
|
}
|
|
|
|
sub time_format {
|
|
my $self = shift;
|
|
my $time = shift;
|
|
my $time_unit = "";
|
|
my $day = "";
|
|
if($time =~ /(\d+) day/){
|
|
$day = $1;
|
|
if($1 > 0 && $1 <= 1){
|
|
$day .= " Tag ";
|
|
}else{
|
|
$day .= " Tage ";
|
|
}
|
|
$time_unit .= $day;
|
|
$time =~ s/\d+ day //;
|
|
}
|
|
my ($std,$min,$sec) = split(/:/,$time);
|
|
$std =~ s/^0//;
|
|
$min =~ s/^0//;
|
|
$time_unit .= "$std Std " if($std > 0);
|
|
$time_unit .= "$min Min " if($min > 0);
|
|
return $time_unit;
|
|
}
|
|
|
|
# copy template
|
|
sub copy_template(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $master_tpl_id = shift;
|
|
my $new_tpl_id = shift;
|
|
my $owner = shift;
|
|
my $source = $dbh->get_info( $GetInfoType{SQL_DATABASE_NAME} );
|
|
|
|
my $columns = "tpl_name,tpl_order,ct_table,tpl_height,tpl_width,bg_color";
|
|
my $sql = "INSERT INTO template ($columns) SELECT $columns from template where tpl_id=$master_tpl_id RETURNING tpl_id";
|
|
my $sth = $dbh->prepare($sql);
|
|
my $rows = $sth->execute();
|
|
|
|
my $last_id;
|
|
$sth->bind_columns(\$last_id);
|
|
my $auto_tpl_id = $sth->fetchrow_array();
|
|
$bw->log("DBtank copy_template $source: $rows",$sql,"") if($debug);
|
|
|
|
my $sth2 = $dbh->prepare("UPDATE template set tpl_id=$new_tpl_id, change='now()',owner=$owner where tpl_id=$auto_tpl_id");
|
|
$rows = $sth2->execute();
|
|
|
|
return $new_tpl_id;
|
|
}
|
|
|
|
|
|
#content of txt08 changed to ctadr->{txt01} Name
|
|
sub insert_pos(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $ctt_id = shift;
|
|
my $ct = shift || {};
|
|
my $ct_station = shift || {};
|
|
my $ctadr = shift || {};
|
|
my $ct_tariff = shift || "";
|
|
my $endRental = shift || "0000-00-00";
|
|
my $ct_name = shift || "";
|
|
my $status = shift || "";
|
|
my $owner = shift || "";
|
|
my $sig_book = shift || {};
|
|
|
|
my $aa_station = $ct_station->{int42} || 0;
|
|
|
|
$ct_name = $ct->{barcode} if(!$ct_name);#artikelnr or bikenr
|
|
my $prefix = "";
|
|
$ct_name =~ s/S[1-9]X/SX/;#sig
|
|
$prefix = $1 if($ct_name =~ /^([A-Z]+)(\d+)$/i);
|
|
|
|
my $user_name = $ctadr->{txt01};
|
|
$user_name = $ctadr->{txt08} if(!$user_name || $user_name eq "no name");
|
|
my $staff = 0;
|
|
$staff = 1 if($ctadr->{txt18});#service staff (no sms message)
|
|
|
|
my $deviceId = $ct->{int13} || 0;
|
|
my $bike_charge = $ct->{int19} || 0;
|
|
my $trackon = $ct->{int25} || 0;
|
|
my $bike_type_id = $ct->{type_id} || 0;
|
|
my $from_main_id = $ct->{main_id} || 0;
|
|
my $from_template_id = $ct->{template_id} || 0;
|
|
my $station = $ct->{int04} || 0;
|
|
my $rabatt = 0;
|
|
|
|
my $unit_price = $ct->{int02} || 0;#article price
|
|
my $unit_price1 = 0;
|
|
my $unit_price2 = 0;
|
|
my $start_price = 0;
|
|
my $daymax_price = 0;
|
|
my $startup_price = 0;
|
|
my $abo_price = 0;#not used
|
|
my $unit_time = "00:00";
|
|
my $free_time = "00:00";
|
|
|
|
my $tariff_nr = 0;
|
|
my $tariff_desc;
|
|
my $free_hours = 0;#old
|
|
my $sharing_type = 0;
|
|
my $menge = 0;
|
|
if(ref($ct_tariff) eq "HASH" && $ct_tariff->{barcode}){
|
|
$rabatt = $ctadr->{int07} || 0;
|
|
$unit_price = $ct_tariff->{int02} || 0;#old and should in future not used by rental
|
|
$unit_price1 = $ct_tariff->{int35} || 0;
|
|
$unit_price2 = $ct_tariff->{int36} || 0;
|
|
$start_price = $ct_tariff->{int37} || 0;
|
|
$abo_price = $ct_tariff->{int15} || 0;#not used
|
|
$free_hours = $ct_tariff->{int16} || 0;#old
|
|
$daymax_price = $ct_tariff->{int17} || 0;
|
|
$tariff_nr = $ct_tariff->{barcode} || 0;
|
|
$tariff_desc = $ct_tariff->{ct_name};
|
|
$unit_time = $ct_tariff->{time01} || "00:00";
|
|
$free_time = $ct_tariff->{time02} || "00:00";
|
|
$sharing_type = $ct_tariff->{int18} || 0;
|
|
}
|
|
|
|
my $sth;
|
|
#Verleihräder
|
|
if($ct->{template_id} && $ct->{template_id} == 205){#Leihrad_list
|
|
$sth = $dbh->prepare("INSERT INTO contenttranspos (ct_id,cc_id,ca_id,ct_name,barcode,txt01,txt08,txt02,txt09,txt12,itime,start_time,end_time,int01,int02,int03,int06,int04,txt05,txt06,txt07,int10,int12,template_id,int13,owner,int07,txt04,int09,int17,int15,int16,int11,int18,int19,txt17,txt18,int20,int25,int29,int34,txt22,txt11,int35,int36,int37,int42,time01,time02) VALUES ('$ctt_id','$ct->{c_id}','$ctadr->{c_id}','$ct_name','$ct->{barcode}','$ct->{txt01}','$user_name','$ct->{txt02}','$ctadr->{txt09}','$prefix',now(),now(),'$endRental','1','$unit_price','$menge','$station','$station','$ct->{txt06}','$ct->{txt06}','$ct->{txt07}','$status','$from_main_id','$from_template_id','$deviceId','$owner','$rabatt','$tariff_desc','$tariff_nr','$daymax_price','$abo_price','$free_hours','$ct->{int11}','$sharing_type','$bike_charge','$ct->{txt17}','$ct->{txt18}','1','$trackon','$bike_type_id','$staff','$sig_book->{bikeId}','$sig_book->{rentalId}','$unit_price1','$unit_price2','$start_price','$aa_station','$unit_time','$free_time') RETURNING c_id");
|
|
}else{
|
|
$sth = $dbh->prepare("INSERT INTO contenttranspos (ct_id,cc_id,ca_id,ct_name,barcode,txt08,txt09,itime,int01,int02,int03,txt01,txt06,txt07,int10,int12,template_id,owner) VALUES ('$ctt_id','$ct->{c_id}','$ctadr->{c_id}','$ct_name','$ct->{barcode}','$user_name','$ctadr->{txt09}',now(),'1','$unit_price','1','$ct->{txt01}','$ct->{txt06}','$ct->{txt07}','0','$from_main_id','$from_template_id','$owner') RETURNING c_id");
|
|
}
|
|
my $rows = $sth->execute();
|
|
my $last_id;
|
|
$sth->bind_columns(\$last_id);
|
|
my $c_id = $sth->fetchrow_array();
|
|
|
|
if($c_id && $status){
|
|
#update Leihräder in Stammdaten
|
|
my $set2 = "owner=$owner" if($owner);
|
|
$set2 .= ",int10='$status'" if($status);
|
|
$set2 .= ",mtime='now()'";
|
|
my $sth2 = $dbh->prepare("UPDATE content SET $set2 where c_id='$ct->{c_id}'");
|
|
my $rows2 = $sth2->execute();
|
|
}
|
|
|
|
return $c_id;
|
|
}
|
|
|
|
# insert contenttrans
|
|
sub insert_contenttrans(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $ctadr = shift;
|
|
my $main_id = shift;
|
|
my $tpl_id = shift;
|
|
my $invoice_nr = shift || "----";
|
|
my $owner = shift || 0;
|
|
|
|
$owner="199" if(!$owner);
|
|
my $sth = $dbh->prepare("INSERT INTO contenttrans (ct_name,txt00,int10,int03,txt02,txt01,txt03,txt06,txt07,txt08,txt09,txt15,txt17,txt18,txt19,owner,itime) VALUES('$invoice_nr','Rechnung','$ctadr->{c_id}','$ctadr->{int03}','$ctadr->{txt02}','$ctadr->{txt01}','$ctadr->{txt03}','$ctadr->{txt06}','$ctadr->{txt07}','$ctadr->{txt08}','$ctadr->{txt09}','$ctadr->{txt15}','$ctadr->{txt17}','$ctadr->{txt18}','$ctadr->{txt19}','$owner','now()') RETURNING c_id");
|
|
|
|
my $rows = $sth->execute();
|
|
my $last_id;
|
|
$sth->bind_columns(\$last_id);
|
|
my $c_id = $sth->fetchrow_array();
|
|
|
|
my $sth3 = $dbh->prepare("INSERT INTO relation (ca_id,main_id,content_id,template_id,change) VALUES('$ctadr->{c_id}','$main_id','$c_id','$tpl_id','now()')");
|
|
$sth3->execute();
|
|
return $c_id;
|
|
}
|
|
|
|
#compute amount of wawi content
|
|
sub update_content4comp(){
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
my $c_id = shift || 0;
|
|
my $op = shift;
|
|
my $amount = shift;
|
|
|
|
my $where = "c_id=$c_id";
|
|
my $ct_set = "int03=(int03 $op $amount)";
|
|
my $sth = $dbh->prepare("UPDATE content SET $ct_set where $where");
|
|
my $rows = $sth->execute();
|
|
return $rows;
|
|
}
|
|
|
|
#should be in DB
|
|
sub evaluationsfragen {
|
|
my $self = shift;
|
|
my $dbh = shift || $dbh_intern;
|
|
|
|
my $user_miniquery = {
|
|
title => "Bitte unterstützen Sie unsere Begleitforschung",
|
|
subtitle => "Ihre drei Antworten werden anonym gespeichert.",
|
|
footer => "Herzlichen Dank und viel Spaß bei der nächsten Fahrt!",
|
|
questions => {
|
|
q1 => {
|
|
type => "check_one",
|
|
quest_text => "1. Frage: Was war der Hauptzweck dieser Ausleihe?",
|
|
query => {
|
|
opt1 => "1. Einkauf",
|
|
opt2 => "2. Kinderbeförderung",
|
|
opt3 => "3. Freizeitaktivitäten, wie Ausflüge",
|
|
opt4 => "4. Nutzung ohne Lastentransport",
|
|
opt5 => "5. Gewerbliche Zwecke",
|
|
opt6 => "6. Ausprobieren",
|
|
opt7 => "7. Sonstiger Zweck"
|
|
}
|
|
},
|
|
q2 => {
|
|
type => "check_one",
|
|
quest_text => "2. Frage: Welches Verkehrsmittel hätten Sie ohne Mietlastenrad für diese Fahrt genutzt?",
|
|
query => {
|
|
opt1 => "1. Fahrrad",
|
|
opt2 => "2. Auto",
|
|
opt3 => "3. Zu Fuß",
|
|
opt4 => "4. Bus/Bahn",
|
|
opt5 => "5. Anderes Lastenrad",
|
|
opt6 => "6. Motorad/-roller",
|
|
opt7 => "7. Keins (ich hätte den Weg nicht gemacht)",
|
|
opt7 => "8. Sonstige"
|
|
}
|
|
},
|
|
q3 => {
|
|
type => "text",
|
|
quest_text => "3. Haben Sie Anmerkungen oder Anregungen?",
|
|
query => {
|
|
opt1 => ""
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
return $user_miniquery;
|
|
}
|
|
|
|
1;
|