sharee.bike/copri4/main/src/Mod/APIfunc.pm

3411 lines
138 KiB
Perl
Executable file

package APIfunc;
#
# SPDX-License-Identifier: AGPL-3.0-or-later
# Copyright (c) Rainer Gümpelein, TeilRad GmbH
#
#Server methods for sharee API
#
#perl -cw
#use lib qw(/var/www/copri-bike/shareeapp-operator/src);
#
use strict;
use warnings;
use POSIX;
use CGI; # only for debugging
use JSON;
use Digest::MD5 qw(md5 md5_hex);
use Digest::SHA qw(sha256_base64);
use Scalar::Util qw(looks_like_number);
use DateTime;
use DateTime::Format::Pg;
use URI::Encode;
use Config::General;
use Lib::Config;
use Mod::Libenz;
use Mod::DBtank;
use Mod::Callib;
use Mod::Basework;
use Mod::Pricing;
use Mod::Payment;
use Mod::MailTransport;
use Data::Dumper;
use Sys::Hostname;
my $json = JSON->new->allow_nonref;
my $cf = new Config;
my $lb = new Libenz;
my $dbt = new DBtank;
my $cal = new Callib;
my $bw = new Basework;
my $pri = new Pricing;
my $pay = new Payment;
my $mailtrans = new MailTransport;
sub new {
my $class = shift;
my $self = {};
bless($self,$class);
return $self;
}
my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime;
my $now_date = strftime "%Y-%m-%d", localtime;
my $lang="de";
my $owner=188;#via API
my $dbh = "";
#fetch merchant_id by request or hostname
sub fetch_merchant {
my $self = shift;
my $q = shift;
my $varenv = shift;
my $req_coo = shift || "";
my $req_merchant_id = shift || "";
my $return = {
aowner => "",
merchant_id => "",
project_id => ""
};
my $merchanized = 0;
my $aowner = 0;
while ((my $merchant_conf, my $value) = each %{ $dbt->{merchant_ids}}) {
if($merchant_conf && (($req_coo && $req_coo =~ /$merchant_conf$/) || ($req_merchant_id && $req_merchant_id eq $merchant_conf))){
$merchanized = 1;
$aowner = $value->{id};
$return->{aowner} = $value->{id};
$return->{merchant_id} = $merchant_conf;
$return->{project_id} = $value->{project};
my $lat = "";
my $lng = "";
if($value->{initMap}){
$value->{initMap} =~ s/\s//g;
($lat,$lng) = split(/,/,$value->{initMap}) if($value->{initMap} && $value->{initMap} =~ /\d+,\d+/);
}
if($lat && $lng){
$return->{init_map}->{center}->{latitude} = $lat;
$return->{init_map}->{center}->{longitude} = $lng;
$return->{init_map}->{radius} = "2.9";
}
#$bw->log("===> merchant select by $return->{project_id} session-cookie OR authcookie OR merchant_id: if($merchant_conf && (($req_coo && $req_coo =~ /$merchant_conf/) || ($req_merchant_id && $req_merchant_id eq $merchant_conf))){",$return->{merchant_id},"");
#last;
}
}
if(!$merchanized){
if($varenv->{syshost} eq "shareeapp-primary" || $varenv->{syshost} eq "shareedms-primary"){
$aowner = $dbt->{primary}->{sharee_primary}->{owner};
$return->{aowner} = $dbt->{primary}->{sharee_primary}->{owner};
$return->{merchant_id} = $dbt->{primary}->{sharee_primary}->{merchant_id};
$return->{project_id} = $dbt->{primary}->{sharee_primary}->{project};
$merchanized = 1;
#$bw->log("===> merchant select by $return->{project_id} primary dbname: sharee_primary:",$return->{merchant_id},"");
}
elsif($varenv->{syshost} =~ /shareeapp-(\w+)/ || $varenv->{syshost} =~ /shareedms-(\w+)/){
$aowner = $dbt->{operator}->{$varenv->{dbname}}->{owner};
$return->{aowner} = $dbt->{operator}->{$varenv->{dbname}}->{owner};
$return->{merchant_id} = $dbt->{operator}->{$varenv->{dbname}}->{merchant_id};
$return->{project_id} = $dbt->{operator}->{$varenv->{dbname}}->{project};
$merchanized = 1;
#$bw->log("===> merchant select by $return->{project_id} operator dbname=$varenv->{dbname}:",$return->{merchant_id},"");
}
elsif($varenv->{syshost} =~ /shareeweb-/){
$aowner = $dbt->{website}->{$varenv->{syshost}}->{owner};
$return->{aowner} = $dbt->{website}->{$varenv->{syshost}}->{owner};
$return->{merchant_id} = $dbt->{website}->{$varenv->{syshost}}->{merchant_id};
$return->{project_id} = $dbt->{website}->{$varenv->{syshost}}->{project};
$merchanized = 1;
#$bw->log("===> merchant select by $return->{project_id} website syshost=$varenv->{syshost}:",$return->{merchant_id},"");
}
}
return ($aowner,$return);
}
#helper to get template
sub get_node_meta {
my $self = shift;
my $viewsel = shift;
my $ndesc = $dbt->get_node_meta($dbh,$viewsel);
return $ndesc;
}
#helper to get node
sub get_node {
my $self = shift;
my $main_id = shift;
my $ndesc = $dbt->get_node($dbh,$main_id);
return $ndesc;
}
#helper to get DMS users (used by servicetool)
sub select_dmsusers {
my $self = shift;
my $u_id = shift || 0;
my $sqlcon = shift || "";
my $users = $dbt->select_users($dbh,$u_id,$sqlcon);
return $users;
}
#node_select
sub template_select(){
my $self = shift;
my $node = shift;
my $return={};
#category means node.main_id.
#template_id from contentpos.template_id
#finally get tpl_order of contentpos
if(ref($node) eq "HASH"){
my $node_record = $dbt->fetch_rel4tpl4nd($dbh,$node);
my @tpl_order = split /,/,$node_record->{tpl_order};
foreach (@tpl_order){
my ($key,$val,$size,$interval) = split /=/,$_;
$return->{$key} = ["$val","$size","$interval"];
}
return ($return,$node_record);
}else{
return "Failure 4003: category OR template must be defined as integer";
}
}#end node_select
#Search one by key
sub service_work_search(){
my $self = shift;
my $bike = shift || "";
my $station = shift || "";
my $history = shift || 0;
my $search = shift || "";
my $bike_id = $1 if($bike =~ /(\d+)/);
my $station_id = $1 if($station =~ /(\d+)/);
my $dt1 = DateTime->now;
my $return={};
my $pref = {
table => "content",
table_pos => "contentpos",
fetch => "one",
catch => "content_contentpos",
keyfield => "c_id",
};
if(looks_like_number($bike_id)){
$pref->{barcode} = "=::" . $bike_id;
}
if(looks_like_number($station_id)){
$pref->{int04} = "=::" . $station_id;
}
$pref = { %$pref, mtime => ">=::(now() - interval '$history day')" } if($history > 0);
$pref = { %$pref, $search->{key} => "ilike::$search->{val}" } if(ref($search) eq "HASH" && $search->{key});
my $pos_record = $dbt->collect_post($dbh,$pref);
return $pos_record;
}
#service_select by service_id=service-c_id
sub service_select {
my $self = shift;
my $q = shift;
my $auth = shift;
my $service_id = shift || "";
my $interval = shift || "";
my $pos_record = {};
my $return = {};
my $bike = "";
my $station = "";
$bike = $1 if($q->param('bike') =~ /(\d+)/);
$station = $1 if($q->param('station') =~ /(\d+)/);
my $cpref = {};
my $c_table = "content";
my $pos_table = "contentpos";
my $template_id_pos = "";
#all this just get the right pos template_id
if($q->param('request') eq "service_done" || $q->param('request') eq "service_work" || $q->param('request') eq "bikes_all"){
if(looks_like_number($bike)){
$cpref = {
table => "$c_table",
fetch => "one",
template_id => "205",
barcode => "=::" . $q->escapeHTML($bike),
};
}
if(looks_like_number($station)){
$cpref = {
table => "$c_table",
fetch => "one",
template_id => "225",
int04 => "=::" . $q->escapeHTML($station),
};
}
if($q->param('request') eq "bikes_all"){
$cpref = {
table => "$c_table",
fetch => "one",
template_id => "205",
};
}
if($q->param('request') eq "bikes_all" && looks_like_number($station)){
$cpref = {
table => "$c_table",
fetch => "one",
template_id => "205",
};
}
}
elsif($q->param('request') eq "user_feedback"){
$c_table = "contentadr";
$pos_table = "contentadrpos";
$template_id_pos = 601;#feedback template_id
$cpref = {
table => "$c_table",
fetch => "one",
template_id => "202",
c_id => "$auth->{c_id}",
};
}
elsif($q->param('request') eq "user_minianswer"){
$c_table = "contentadr";
$pos_table = "contentadrpos";
$template_id_pos = 602;#miniquery answer template_id
$cpref = {
table => "$c_table",
fetch => "one",
template_id => "202",
c_id => "$auth->{c_id}",
};
}
#get real pos.template_id by parent_id=$crecord->{main_id}
my $crecord = $dbt->fetch_record($dbh,$cpref);
#will be only done if article (bike or station) exists in DB
if(ref($crecord) eq "HASH" && $crecord->{c_id} && $crecord->{main_id}){
my $subrelnode = $dbt->get_subrelnode($dbh,$crecord->{main_id},$template_id_pos);
#get service template to return template formated contentpos
my ($tpl_order,$node_template) = $self->template_select($subrelnode);
my @tpl_order = split /,/,$node_template->{tpl_order};
#only used by serviceapp
if($q->param('request') ne "user_feedback" && $q->param('request') ne "user_minianswer"){
my $pref = {
table => "$c_table",
table_pos => "$pos_table",
fetch => "all",
catch => "content_contentpos",
keyfield => "c_id",
};
#Because of different contentpos.template_id in Flot Service we use it only on all others else bikes_all requests
if($q->param('request') ne "bikes_all"){
$pref->{template_id} = "$node_template->{template_id}";
}
if(looks_like_number($q->param('service_id')) && $q->param('request') ne "service_done"){
$pref->{c_id} = "=::" . $q->escapeHTML($q->param('service_id'));
}elsif(looks_like_number($service_id) && $q->param('request') ne "service_done"){
$pref->{c_id} = "=::" . $service_id;
}elsif(looks_like_number($bike)){
$pref->{barcode} = "=::" . $q->escapeHTML($bike);
}elsif(looks_like_number($station)){
$pref->{int04} = "=::" . $q->escapeHTML($station);
}
if($cal->checkdate_time($q->param('timestamp'))){
$pref->{mtime} = "<=::" . $q->escapeHTML($q->param('timestamp'));
}
if(looks_like_number($interval) && $interval > 0){
if($interval == 30){
#get timestamp from 10. Aufgaben
$pref->{txt01} = "cp.txt01 like '%' and cp.txt01 != 'NaN'";
$bw->log("service_select collect_post to get timestamp of tenth Aufgabe",$pref,"");
my $pos_record10 = $dbt->collect_post($dbh,$pref,"10");
foreach my $id (sort { $pos_record10->{$b}->{c_id} <=> $pos_record10->{$a}->{c_id} } keys (%$pos_record10)){
$pref->{mtime} = ">=::$pos_record10->{$id}->{mtime}";
}
delete $pref->{txt01};
}else{
$pref->{mtime} = ">=::(now() - interval '$interval day')";
}
#if service saved by servicetool fetch user saved services <= 1day
if($q->param('request') eq "service_done"){
$pref->{owner} = $auth->{c_id};
}
}
$bw->log("service_select collect_post with interval $interval",$pref,"");
$pos_record = $dbt->collect_post($dbh,$pref);
my $pos_count = 0;
foreach my $id (sort { $pos_record->{$a}->{barcode} <=> $pos_record->{$b}->{barcode} } keys (%$pos_record)){
foreach (@tpl_order){
my ($key,$val,$size,$interval) = split /=/,$_;
$pos_count++ if($key =~ /mtime/ && $pos_record->{$id}->{$key});
$return->{$id}->{$key} = $pos_record->{$id}->{$key} || "";
}
}
#only used on service init
if($pos_table eq "contentpos" && !$pos_count){
foreach (@tpl_order){
my ($key,$val,$size,$interval) = split /=/,$_;
if($key eq "txt01"){
$return->{1}->{$key} = "::erledigt::";
$pos_record->{1}->{$key} = "::erledigt::";
}else{
$return->{1}->{$key} = "1";
$pos_record->{1}->{$key} = "1";
}
}
$return->{1}->{barcode} = "$bike";
$return->{1}->{cc_id} = "$crecord->{c_id}";
$return->{1}->{mtime} = "$crecord->{mtime}";
$return->{1}->{owner} = "$crecord->{owner}";
$return->{1}->{template_id} = "$node_template->{template_id}";
$pos_record->{1}->{barcode} = $bike;
$pos_record->{1}->{cc_id} = $crecord->{c_id};
$pos_record->{1}->{mtime} = $crecord->{mtime};
$pos_record->{1}->{owner} = $crecord->{owner};
$pos_record->{1}->{template_id} = $node_template->{template_id};
}
$bw->log("service_select with node_template: $node_template->{template_id} and pos_record:","","");
}
return ($return,$pos_record,$node_template,$crecord);
}#end if($crecord)
else{
return ("","","","");
}
}#end service_select
#service_insert
sub service_insert(){
my $self = shift;
my $q = shift;
my $auth = shift;
my $node_template = shift || "";
my $crecord = shift || {};
my $owner = shift || 0;
my $return={};
#insert pos with cc_id
my $c_id = 0;
if($q->param('request') eq "service_done" && ref($crecord) eq "HASH" && $crecord->{c_id} > 0){
my $insert = {
table => "contentpos",
cc_id => $crecord->{c_id},
barcode => $crecord->{barcode},
int04 => $crecord->{int04},
owner => $auth->{c_id},
template_id => $node_template->{template_id},
mtime => "now()",
};
$c_id = $dbt->insert_contentoid($dbh,$insert,"");
}
if($q->param('request') eq "user_feedback" && ref($crecord) eq "HASH" && $crecord->{c_id} > 0){
my $bike_id = "";
my $insert = {
table => "contentadrpos",
ca_id => $crecord->{c_id},
txt01 => $auth->{txt01},
txt08 => $auth->{txt08},
owner => $owner,
template_id => $node_template->{template_id},
mtime => "now()",
};
if($q->param('bike') =~ /(\d+)/){
my $bike = $q->escapeHTML($q->param('bike'));
my $bike_id = $bike;
$bike_id =~ s/S[1-9]X/SX/;
$bike_id = $1 if($bike_id =~ /(\d+)/);
$insert->{barcode} = $bike_id;
$c_id = $dbt->insert_contentoid($dbh,$insert,"");
#if bike_broken then also to contentpos
if(!$q->param('bike_broken')){
my $cpref = {
table => "content",
fetch => "one",
template_id => "205",
barcode => "$bike_id",
};
my $crecord_content = $dbt->fetch_record($dbh,$cpref);
if(ref($crecord_content) eq "HASH" && $crecord_content->{c_id} && $crecord_content->{main_id}){
my $subrelnode = $dbt->get_subrelnode($dbh,$crecord_content->{main_id},"");
my ($tpl_order,$node_template_contentpos) = $self->template_select($subrelnode);
my $insert_contentpos = {
table => "contentpos",
cc_id => $crecord_content->{c_id},
ct_name => $bike,
barcode => $crecord_content->{barcode},
int04 => $crecord_content->{int04},
owner => $owner,
template_id => $node_template_contentpos->{template_id},
mtime => "now()",
};
$insert_contentpos->{txt01} = $q->escapeHTML($q->param('message')) if($q->param('message'));
my $c_id_contentpos = $dbt->insert_contentoid($dbh,$insert_contentpos,"");
if($crecord_content->{fleed_email} && $crecord_content->{fleed_email} =~ /\w\@\w/){
$mailtrans->mail_feedback2garage($crecord_content,$insert_contentpos);
}
}
}
}
}
if($q->param('request') eq "user_minianswer" && ref($crecord) eq "HASH" && $crecord->{c_id} > 0){
my $insert = {
table => "contentadrpos",
#ca_id => $crecord->{c_id},#have to be anonym
owner => $owner,
template_id => $node_template->{template_id},
mtime => "now()",
};
$c_id = $dbt->insert_contentoid($dbh,$insert,"");
}
return $c_id;
}#end service_insert
#service_update
sub service_update(){
my $self = shift;
my $q = shift;
my $auth = shift;
my $node_template = shift;
my $c_id = shift || "";
my $action = shift || "";
my $return={};
my $update = {};
my $bike = $q->escapeHTML($q->param('bike')) || "";
my $bike_id = $bike;
$bike_id =~ s/S[1-9]X/SX/;
$bike_id = $1 if($bike_id =~ /(\d+)/);
my $pref = {
table => "contenttrans",
table_pos => "contenttranspos",
fetch => "one",
template_id => "218",#Mietjournal tpl_id
barcode => $bike_id,
ca_id => "$auth->{c_id}",
"ct.close_time" => "is::null",
int10 => "1",
end_time => ">=::(now() - interval '5 min')",
};
my $ctpos = { c_id => 0 };
if($q->param('request') eq "service_done"){
$c_id = $q->param('service_id') if($q->param('service_id'));
$update = {
table => "contentpos",
owner => $auth->{c_id},
mtime => "now()",
};
}elsif($q->param('request') eq "user_feedback"){
$update = {
table => "contentadrpos",
mtime => "now()",
int01 => 0,
};
$update->{int01} = 1 if($q->param('bike_broken'));
$update->{txt02} = $q->escapeHTML($q->param('message')) if($q->param('message'));
$ctpos = $dbt->collect_post($dbh,$pref) if($bike_id);
if($ctpos->{c_id} > 0){
my $update_pos = {
table => "contenttranspos",
mtime => "now()",
int27 => 1,#ok marker for rental end ack
};
#update sig int28 counter
$update_pos->{int28} = 2 if($ctpos->{int28} && $ctpos->{int28} == 3);
#update bike charge on pos and content
if(looks_like_number($q->param('charge_current_bars'))){
my $max_bars = 5;
my $current_percent = $bw->battery_percent($max_bars,$q->param('charge_current_bars'));
$update_pos->{int19} = $current_percent;
#NO, because of service_work should also be deleted if > 50%
#$self->service_automatic($q,$current_percent) if($current_percent <= 50);
#update also bike charge
my $update_bike = {
table => "content",
mtime => "now()",
int19 => "$update_pos->{int19}",
};
my $record_bike = { c_id => 0 };
$record_bike->{c_id} = $ctpos->{cc_id} if($ctpos->{cc_id});
$dbt->update_record($dbh,$update_bike,$record_bike) if($record_bike->{c_id} > 0);
}
$dbt->update_record($dbh,$update_pos,$ctpos);
}
}elsif($q->param('request') eq "user_minianswer"){
$update = {
table => "contentadrpos",
mtime => "now()",
};
$update->{txt01} = $q->escapeHTML($q->param('q1')) if($q->param('q1'));
$update->{txt02} = $q->escapeHTML($q->param('q2')) if($q->param('q2'));
$update->{txt03} = $q->escapeHTML($q->param('q3')) if($q->param('q3'));
#just a assumption
my $last_used_operator = $auth->{txt19};
if($last_used_operator){
my $dbh_operator = $dbt->dbconnect_extern("$last_used_operator");
my $postref = {
table => "contenttrans",
table_pos => "contenttranspos",
fetch => "one",
ca_id => "$auth->{c_id}",
end_time => ">=::(now() - interval '5 min')",
};
my $post_record = { c_id => 0 };
$post_record = $dbt->collect_post($dbh_operator,$postref);
$update->{int02} = $post_record->{int26} if($post_record->{int26});
$update->{txt10} = $dbt->{operator}->{$last_used_operator}->{oprefix};
#to update sig int28 counter
my $update_pos = {
table => "contenttranspos",
mtime => "now()",
int28 => "1",
};
$dbt->update_record($dbh_operator,$update_pos,$post_record) if($post_record->{c_id});
#user_miniquest_count on operator
#my $adref = {
# table => "contentadr",
# fetch => "one",
# template_id => "202",
# c_id => "$auth->{c_id}",
# };
#my $auth_op = $dbt->fetch_record($dbh_operator,$adref);
my $user_miniquest_count = $auth->{int23} || 0;
if($user_miniquest_count <= 3){
$user_miniquest_count++;
my $update23 = {
table => "contentadr",
int23 => $user_miniquest_count,
atime => "now()",
};
my $rows = $dbt->update_record($dbh,$update23,$auth);
}
}
}
my $record = { c_id => $c_id };
$node_template->{tpl_order} .= ",txt09=Wartungsarbeiten";
my @tpl_order = split /,/,$node_template->{tpl_order};
if($action){
my ($key,$val) = split /=/,$action;
$update->{$key} = $val if($key =~ /txt1\d/);#logging redistribution and charge service action
}elsif($q->param('work_id')){
foreach (@tpl_order){
my ($key,$val,$size) = split /=/,$_;
#key validation will be done by update_record
if($key eq "txt01" && $q->param('work_id') eq "$key" && $q->param('work_val') =~ /::erledigt::/){
my $pref_pos = {
table => "contentpos",
fetch => "one",
c_id => $c_id,
};
my $record_pos = $dbt->fetch_tablerecord($dbh,$pref_pos) if($c_id);
if($record_pos->{txt01} ne "NaN"){
$update->{$key} = $q->escapeHTML($q->param('work_val')) . " " . $record_pos->{txt01} if($record_pos->{txt01} !~ /::erledigt::/);
}else{
$update->{$key} = $q->escapeHTML($q->param('work_val'));
}
}
elsif($key eq "txt01" && $q->param('work_id') eq "$key" && $q->param('work_val') !~ /\w/){
$update->{$key} = "NaN";
}
elsif($q->param('work_id') eq "$key"){
$update->{$key} = $q->escapeHTML($q->param('work_val'));
}
}
}
my $rows = $dbt->update_record($dbh,$update,$record) if($record->{c_id} > 0);
return $rows;
}#end service_update
#bike_update for state update after servíce_work (cronjob) OR service_done
sub bikestate_update(){
my $self = shift;
my $auth = shift;
my $c_id = shift || "";
my $state = shift || "";
my $update_hash = shift || "";
my %varenv = $cf->envonline();
my $return={};
my $update = {
table => "content",
owner => $auth->{c_id},
mtime => "now()",
};
#set state only if defined
$update->{int10} = $state if($state);
#moving bike to station
if(ref($update_hash) eq "HASH" && looks_like_number($update_hash->{int04})){
$update->{int04} = "$update_hash->{int04}";
}
#set smartlock_battery_charge
if(ref($update_hash) eq "HASH" && looks_like_number($update_hash->{int14})){
$update->{int14} = "$update_hash->{int14}";
}
#set bike_battery_charge
if(ref($update_hash) eq "HASH" && looks_like_number($update_hash->{int19})){
$update->{int19} = "$update_hash->{int19}";
}
$bw->log("bikestate_update bike to state c_id $c_id | $update->{int04} | $state | auth:$auth->{c_id}",$update,"");
my $record = { c_id => $c_id };
my $rows = $dbt->update_record($dbh,$update,$record) if($record->{c_id} > 0);
return $rows;
}#bikestate_update
#feedback response --> obsolet
sub feedback_response {
my $self = shift;
my $pos_record = shift;
my $node_template = shift;
my %varenv = $cf->envonline();
my @tpl_order = split /,/,$node_template->{tpl_order};
my $return = {};
foreach my $id (sort { $pos_record->{$a}->{mtime} cmp $pos_record->{$b}->{mtime} } keys (%$pos_record)){
foreach (@tpl_order){
my ($key,$val,$size) = split /=/,$_;
$return->{feedback_id} = "$pos_record->{$id}->{c_id}" if($key eq "c_id");
$return->{bike} = "$dbt->{operator}->{$varenv{dbname}}->{oprefix}$pos_record->{$id}->{barcode}" if($key eq "barcode");
$return->{bike_broken} = "$pos_record->{$id}->{int01}" || "" if($key eq "int01");
$return->{message} = "$pos_record->{$id}->{txt02}" || "" if($key eq "txt02");
}
}
return $return;
}
#service_work copy from service_select
sub service_work {
my $self = shift;
my $pos_record = shift;
my $article_all = shift || "";
my $history = shift || 0;
my $node_template = shift || {};
my %varenv = $cf->envonline();
my $dt1 = DateTime->now;
my $return={};
my $users_map = $dbt->users_map($dbh,{ int09 => 1 });
my $channel_map = $dbt->channel_map();
my @tpl_order = ();
@tpl_order = split /,/,$node_template->{tpl_order} if(ref($node_template) eq "HASH" && $node_template->{tpl_order});
#because of different templates we need template grouping
#not safe, pos template_id have to be defined before any service has done!
#keep in mind, on pos tables there isn't any relation. That's because history pos.template_id will be selected
my $pref = { table => "content",
table_pos => "contentpos",
};
my $template_group = $dbt->pos_template_group($dbh,$pref);
#$bw->log(" template_group",$template_group,"");
my $node = {};
my $op_return = {};
foreach my $cid (sort { $article_all->{$a}->{barcode} <=> $article_all->{$b}->{barcode} } keys(%$article_all)){
my $i=0;
my $j=0;
my $article = $article_all->{$cid}->{barcode};
my $tpl_keyseen = "";
foreach my $id (sort { $pos_record->{$a}->{mtime} cmp $pos_record->{$b}->{mtime} } keys (%$pos_record)){
$i++;
if($article_all->{$cid}->{c_id} == $pos_record->{$id}->{cc_id}){
$article = $article_all->{$cid}->{barcode} if($article_all->{$cid}->{template_id} && $article_all->{$cid}->{template_id} == 205);# bike template_id
$article = $article_all->{$cid}->{int04} if($article_all->{$cid}->{template_id} && $article_all->{$cid}->{template_id} == 225);# station template_id
if(1==1){
if($pos_record->{$id}->{template_id} && $template_group->{$pos_record->{$id}->{template_id}}){
#$bw->log("$article --> service_work template on id: $id used:",$template_group->{$pos_record->{$id}->{template_id}}->{tpl_id},"");
@tpl_order = split /,/,$template_group->{$pos_record->{$id}->{template_id}}->{tpl_order};
$node->{template_id} = "$pos_record->{$id}->{template_id}";
}elsif(1==1){#on init use node tpl
#$bw->log("$article --> service_work template on id: $id used node_template:",$node->{template_id},"");
my $tpl = $dbt->get_tpl($dbh,$node_template->{template_id});
@tpl_order = split /,/,$tpl->{tpl_order};
$node->{template_id} = "$tpl->{tpl_id}";
}
foreach (@tpl_order){
my ($key,$val,$size,$interval,$service_type) = split /=/,$_;
$service_type = 0 if(!looks_like_number($service_type));
my $erledigt = 0;
$erledigt = 1 if(!$history && $pos_record->{$id}->{txt01} && $pos_record->{$id}->{txt01} !~ /::erledigt::/);
$erledigt = 1 if($history && $pos_record->{$id}->{txt01} && $pos_record->{$id}->{txt01} =~ /::erledigt::/);
#service integer collect
if($key =~ /int/ && looks_like_number($pos_record->{$id}->{$key})){
$tpl_keyseen .= "$key|";
my $u_name = $users_map->{$pos_record->{$id}->{owner}}->{txt01} || $channel_map->{$pos_record->{$id}->{owner}} || $pos_record->{$id}->{owner};
my $dt2 = DateTime::Format::Pg->parse_datetime($pos_record->{$id}->{mtime});
my $time_over = "0";
if(looks_like_number($interval) && $interval > 0){
my $dt2_over = $dt2->add( days => $interval );
$time_over = "1" if($dt1 > $dt2_over);
}
my $key_change = $key;
if($history && $history > 0){
my $dtstamp = $pos_record->{$id}->{mtime};
$dtstamp = $dt2->epoch();
$key_change .= "_" . $dtstamp;
}
$return->{$article}->{$key_change}->{service_id} = "$pos_record->{$id}->{c_id}";
$return->{$article}->{$key_change}->{work_id} = "$key";
$return->{$article}->{$key_change}->{work_name} = "$val";
$return->{$article}->{$key_change}->{interval} = "$interval";
$return->{$article}->{$key_change}->{time_over} = "$time_over";
$return->{$article}->{$key_change}->{service_type} = "$service_type";
$return->{$article}->{$key_change}->{work_val} = "$pos_record->{$id}->{$key}";
$return->{$article}->{$key_change}->{mtime} = "$pos_record->{$id}->{mtime}";
$return->{$article}->{$key_change}->{user_name} = "$u_name";
$return->{$article}->{$key_change}->{owner} = "$pos_record->{$id}->{owner}";
#servive multi todo collect
}elsif($key eq "txt01" && $pos_record->{$id}->{$key} && $pos_record->{$id}->{$key} ne "NaN" && $erledigt){
$j++;
$tpl_keyseen .= "$key|";
my $u_name = $users_map->{$pos_record->{$id}->{owner}}->{txt01} || $channel_map->{$pos_record->{$id}->{owner}} || $pos_record->{$id}->{owner};
my $dt2 = DateTime::Format::Pg->parse_datetime($pos_record->{$id}->{mtime});
my $time_over = "0";
if(looks_like_number($interval) && $interval > 0){
my $dt2_over = $dt2->add( days => $interval );
$time_over = "1" if($dt1 > $dt2_over);
}
my $key_change = $key;
if($history && $history > 0){
my $dtstamp = $pos_record->{$id}->{mtime};
$dtstamp = $dt2->epoch();
$key_change .= "_" . $dtstamp;
}elsif($j > 1){
#appending counter on multiple todos
$key_change .= "_" . $j;
}
my $work_val = "$pos_record->{$id}->{$key}";
$work_val = "" if($pos_record->{$id}->{$key} eq "::new_task::");
$return->{$article}->{$key_change}->{service_id} = "$pos_record->{$id}->{c_id}";
$return->{$article}->{$key_change}->{work_id} = "$key";
$return->{$article}->{$key_change}->{work_name} = "$val";
$return->{$article}->{$key_change}->{interval} = "$interval";
$return->{$article}->{$key_change}->{time_over} = "$time_over";
$return->{$article}->{$key_change}->{service_type} = "$service_type";
$return->{$article}->{$key_change}->{work_val} = "$work_val";
$return->{$article}->{$key_change}->{mtime} = "$pos_record->{$id}->{mtime}";
$return->{$article}->{$key_change}->{user_name} = "$u_name";
$return->{$article}->{$key_change}->{owner} = "$pos_record->{$id}->{owner}";
}
}
}
}
}
#set init values
if(!$history && scalar(@tpl_order) > 1){
$bw->log("set service init values by @tpl_order","","");
$bw->log("tpl_keyseen",$tpl_keyseen,"");
$tpl_keyseen =~ s/\|$//;
foreach (@tpl_order){
my ($key,$val,$size,$interval,$service_type) = split /=/,$_;
$service_type = 0 if(!looks_like_number($service_type));
if($key =~ /int|txt/ && (!$tpl_keyseen || $key !~ /$tpl_keyseen/)){
$return->{$article}->{$key}->{service_id} = "1";
$return->{$article}->{$key}->{work_id} = "$key";
$return->{$article}->{$key}->{work_name} = "$val";
$return->{$article}->{$key}->{interval} = "$interval";
$return->{$article}->{$key}->{time_over} = "1";#2021-06-23 if not seen then time_over
$return->{$article}->{$key}->{service_type} = "$service_type";
$return->{$article}->{$key}->{work_val} = "1" if($key =~ /int/);
$return->{$article}->{$key}->{work_val} = "::erledigt::" if($key =~ /txt/);
$return->{$article}->{$key}->{mtime} = "2023-02-16 00:00";
$return->{$article}->{$key}->{user_name} = "init";
$return->{$article}->{$key}->{owner} = "188";
}
}
#}else{
#$return->{response_state} = "Failure 3099: history to short OR template fails";
}
}
return ($return,$node);
}#end service_work
#bike reservation
sub booking_request(){
my $self = shift;
my $q = shift;
my $varenv = shift;
my $auth = shift;#app API auth
my $bike = shift || 0;#app API request
my $ct_bike = shift || {};
my $ct_tariff = shift || {};
my $sig_book = shift || {};
my $owner = shift || 0;
my $state = $q->escapeHTML($q->param('state')) || "";
my $lock_state = $q->escapeHTML($q->param('lock_state')) || "";
my $dbh = "";
my $pos_id="";
my $now_dt = strftime "%Y-%m-%d %H:%M", localtime;
my $response_state = "OK";
my $response_text = "";
#state and lock_state is only defined if requestes incl. occupied
$bw->log("log booking_request bike=$bike, auth=$auth->{c_id}, state=$state, lock_state=$lock_state, tarif=$ct_tariff->{barcode}",$auth->{txt08},"");
my $update_adr = {
table => "contentadr",
mtime => "now()",
owner => "$owner",
c_id => "$auth->{c_id}",
};
my $pref = {
table => "contenttrans",
fetch => "one",
main_id => 300008,
template_id => 218,
int10 => "$auth->{c_id}",
state => "null",
close_time => "is::null",
};
#if bike and tariff
if($ct_bike->{barcode} && $ct_tariff->{barcode}){
my $ctt = {};
my $rentable_check=0;
$rentable_check = $bw->isuser_rentable($auth,$varenv);
$bw->log("booking_request isuser_rentable:",$rentable_check,"");
if($rentable_check == 2){
#to get if station only for A-A journay
my $pref_station = {
table => "content",
fetch => "one",
template_id => "225",
int04 => $ct_bike->{int04},
};
my $ct_station = {};
$ct_station = $dbt->fetch_record($dbh,$pref_station) if($ct_bike->{int04});
#get invoice
$ctt = $dbt->fetch_record($dbh,$pref) if($auth->{c_id});
if(!$ctt->{c_id}){
my $ct_id = $dbt->insert_contenttrans($dbh,$auth,"300008","218","----","$owner");
$pref->{c_id} = $ct_id;
$ctt = $dbt->fetch_record($dbh,$pref) if($pref->{c_id});
}
$bw->log("booking_request used invoice c_id:",$ctt->{c_id},"");
#if invoice exist
if($ctt->{c_id}){
#if any OPOS then permit further rentals
my $ctt_opos = { c_id => 0 };
my $pref_opos = {
table => "contenttrans",
fetch => "one",
template_id => "IN::(209,218)",
int10 => $auth->{c_id},
state => "payment_fault",#selects Zahlungsausfall or int14 opos
};
$ctt_opos = $dbt->fetch_record($dbh,$pref_opos);
#if payment-type prepaid, then check whether balance positive
my $sum_balance = 0;
if($auth->{int03} && $auth->{int03} == 3){
my $dbh_primary = $dbt->dbconnect_extern($dbt->{primary}->{sharee_primary}->{database}->{dbname});
my $adref = {
table => "contentadr",
fetch => "one",
c_id => "$auth->{c_id}",
};
my $auth_prim = $dbt->fetch_tablerecord($dbh_primary,$adref);
#get prepaid balance, like in users App RentalData
#collects all open (not captured) positions incl. primary-prepaid to get saldo
my ($cttpos,$operator_hash) = $self->user_rentals_history($q,$auth_prim,0,1);
foreach my $id (keys(%$cttpos)){
if($cttpos->{$id}->{int35} && $cttpos->{$id}->{start_time} && $cttpos->{$id}->{end_time}){
my $pricing = { total_price => 0 };
($pricing, my $counting) = $pri->counting_rental($varenv,$cttpos->{$id});
$sum_balance += $pricing->{total_price};
}else{
my $total_price = 0;
($total_price,my $rabatt) = $pri->price2calc($cttpos->{$id});
#prepaid * -1
$total_price *= -1 if($cttpos->{$id}->{template_id} && $cttpos->{$id}->{template_id} == 219);
$sum_balance += $total_price;
}
}
$bw->log("booking_request prepaid balance sum: $sum_balance, userID: $auth->{c_id} ",$sum_balance,"");
}
#Rental is only permitted if sum_balance <= 1 (in primary prepaid context positive)
#Rental is only permitted if no invoice with payment_fault or opos
$bw->log("Rental is only permitted if no invoice with payment_fault or opos: $sum_balance <= 1 && !$ctt_opos->{c_id}, userID: $auth->{c_id} ",$sum_balance,"");
if($sum_balance <= 1 && !$ctt_opos->{c_id}){
#2 = "requested"
$pos_id = $dbt->insert_pos($dbh,$ctt->{c_id},$ct_bike,$ct_station,$auth,$ct_tariff,$now_dt,$bike,"2",$owner,$sig_book);
$bw->log("booking_request insert_pos:",$pos_id,"");
if($pos_id){
$response_state = "OK, bike " . $bike . " succesfully requested";
$response_text = "Rad $bike wurde erfolgreich für 15 Min. reserviert";
$bw->log("booking_request insert contenttranspos pos_id: $pos_id\n","","");
my $update_ctt = {
table => "contenttrans",
c_id => $ctt->{c_id},
};
$dbt->update_one($dbh,$update_ctt,"start_time='$now_dt'");
#BVB once auto-coupon until 2023-08-31
#disabled
if(1==2 && $varenv->{dbname} eq "sharee_bvb"){
#BVB 3-Stunden-Freifahrt
my $auto_coupon = "123";
my $pref_co = {
table => "content",
fetch => "one",
template_id => "224",
int03 => ">::0",
barcode => "$auto_coupon",
};
my $ct_co = { c_id => 0 };
$ct_co = $dbt->fetch_record($dbh,$pref_co);
$ct_co->{int02} *= -1 if($ct_co->{int02} > 0);#coupon price must be negate
my $pos_co = {
table => "contenttranspos",
fetch => "one",
ca_id => "$auth->{c_id}",
template_id => "224",
barcode => "$auto_coupon",
};
my $co_pos = { c_id => 0 };
$co_pos = $dbt->fetch_tablerecord($dbh,$pos_co);
if($ct_co->{c_id} && !$co_pos->{c_id}){
$pos_id = $dbt->insert_pos($dbh,$ctt->{c_id},$ct_co,"",$auth,"","","","0",$owner);
$dbt->update_content4comp($dbh,$ct_co->{c_id},"-","1");
}
}#end BVB auto-coupon
}else{
$response_state="Failure 1007: booking request fails";
$response_text="Entschuldigung, es ist ein Fehler aufgetreten. Bitte kontaktieren Sie unsere hotline damit wir das Problem lösen können";
}
}else{
if($ctt_opos->{c_id}){
$response_state="Failure 1593: rental is prohibited because of payment_fault invoice $ctt_opos->{ct_name}";
$response_text="Es existiert ein Problem mit einer Rechnung. Bitte melden Sie sich bei rechnung\@sharee.bike .";
}else{
$sum_balance = sprintf('%.2f',$sum_balance);
$sum_balance =~ s/\./,/;
$response_state="Failure 1594: rental is prohibited because of prepaid balance - $sum_balance";
$response_text="Bitte überprüfen Sie Ihren Prepaid/Vorkasse Kontostand, aktuell: - $sum_balance €. Nur bei positiven Kontostand können wir das Mietradsystem für Sie freischalten.";
}
}#end if $sum_balance
}
}elsif($rentable_check == 1){
$response_state="Failure 1006: rental is prohibited because of user profil";
$response_text="Bitte überprüfen Sie Ihre Profildaten auf Vollständigkeit, nur dann können wir das Mietradsystem für Sie freischalten";
}else{
my $vde = $auth->{int12} || 1;
$dbt->update_one($dbh,$update_adr,"int12=$vde");
$response_state="Failure 1005: user-account deactivated because of user profil";
$response_text="Bitte überprüfen Sie Ihre Profildaten auf Vollständigkeit, nur dann können wir das Mietradsystem für Sie freischalten";
}
}
my $return = {
bike => "$bike",
pos_id => "$pos_id",
state => "requested",
response_state => "$response_state",
response_text => "$response_text"
};
$bw->log("booking_request response_state:",$return,"");
return $return;
}
#booking_cancel changed to booking_update
sub booking_update(){
my $self = shift;
my $q = shift;
my $varenv = shift;
my $auth = shift;
my $owner = shift || 0;
my $sig_book = shift || {};
my $dbh = "";
my $state = $q->escapeHTML($q->param('state')) || "";
my $lock_state = $q->escapeHTML($q->param('lock_state')) || "";
my $rows = 0;
my $user_agent = $q->user_agent();
#my $bike = $q->param('bike');
#my $bike_id = $1 if($q->escapeHTML($q->param('bike')) =~ /(\d+)/);
my $bike = $q->escapeHTML($q->param('bike')) || "";
my $bike_id = $bike;
$bike_id =~ s/S[1-9]X/SX/;
$bike_id = $1 if($bike_id =~ /(\d+)/);
my $state_key = 0;
my $state_text = "";
while (my ($key, $value) = each %{ $dbt->{copri_conf}->{bike_state} }) {
if($state eq $value){
$state_key = $key;
$state_text = "beendet" if($state eq "available");
$state_text = "gestartet" if($state eq "occupied");
}
}
my $booking_values = {
bike => "$bike",
state => "",
lock_state => "",
#station_lock_state => "",
co2saving => "",
response_state => "OK 1017: No update",
response_text => "Der Mietstatus wurde nicht geändert.",
};
my $record_pos = { c_id => 0 };
my $booking_pos = {
table => "contenttranspos",
fetch => "one",
barcode => $bike_id,
ca_id => $auth->{c_id},
int10 => "IN::('3','2')",
};
$record_pos = $dbt->fetch_tablerecord($dbh,$booking_pos) if($bike_id > 0 && $auth->{c_id} > 0);
if(!$record_pos->{c_id}){
$booking_values->{response_state} = "Failure 758: Can not find bike " . $q->param('bike') . " rental or reservation on varenv-dbname: $varenv->{dbname}";
$booking_values->{response_text} = "Keine Miete oder Reservierung zu Rad " . $q->param('bike') . " gefunden.";
}
my $pref_cc = {
table => "content",
fetch => "one",
template_id => "205",
barcode => $bike_id,
};
my $record_cc = { c_id => 0 };
$record_cc = $dbt->fetch_record($dbh,$pref_cc) if($q->param('bike'));
my $update_cc = {
table => "content",
mtime => "now()",
owner => "$owner",
};
my $gps_data = {
gps => "",
latitude => "",
longitude => "",
gps_age_minutes => 60,
gps_accuracy => 0,
geo_distance => 1000000,
};
#old
if($q->param('gps')){
my $gps_input = $q->param('gps');
$gps_input =~ s/\s//g;
$gps_data->{latitude} = $q->escapeHTML($1) if($gps_input =~ /^(\d+\.\d+),\d+/);
$gps_data->{longitude} = $q->escapeHTML($1) if($gps_input =~ /\d+,(\d+\.\d+)$/);
$gps_data->{gps} = "$gps_data->{latitude},$gps_data->{longitude}" if($gps_data->{latitude} && $gps_data->{longitude});
}
#new
if($q->param('latitude') && $q->param('longitude')){
my $latitude_in = $q->param('latitude');
my $longitude_in = $q->param('longitude');
$gps_data->{latitude} = $1 if($latitude_in =~ /(\d+\.\d+)/);
$gps_data->{longitude} = $1 if($longitude_in =~ /(\d+\.\d+)/);
$gps_data->{gps} = "$gps_data->{latitude},$gps_data->{longitude}" if($gps_data->{latitude} && $gps_data->{longitude});
}
my $gps_age = 0;
$gps_age = $1 if($q->param('gps_age') && $q->param('gps_age') =~ /^(\d+)/);#in milisec
$gps_data->{gps_age_minutes} = $gps_age / 1000 / 60 if($gps_age);
$gps_data->{gps_accuracy} = $1 if($q->param('gps_accuracy') && $q->param('gps_accuracy') =~ /^(\d+)/);#in meters
my $update_pos = {
table => "contenttranspos",
mtime => "now()",
};
my $lock_charge = $q->param('voltage') || "";
my $gps_age_minutes = "";
$gps_age_minutes = $gps_data->{gps_age_minutes} if($q->param('gps_age'));
my $logvalues = "pos_id=$record_pos->{c_id}, state=$state, lock_state=$lock_state, lock_charge=$lock_charge, gps=$gps_data->{gps}, gps_age_minutes=$gps_age_minutes";
my $logging = "log booking_update bike=$bike, userID=$auth->{c_id}, $logvalues";
$bw->log("$logging",$auth->{c_id},"");
my $log_stamp = strftime "%d.%m.%Y %H:%M:%S", localtime;
$update_pos->{txt24} = $record_pos->{txt24} . "\n- $log_stamp $logvalues";
$dbt->update_record($dbh,$update_pos,$record_pos);
my $Ilockit_GUID = "";
$Ilockit_GUID = $q->escapeHTML($q->param('Ilockit_GUID')) if($q->param('Ilockit_GUID') && $q->param('Ilockit_GUID') =~ /\w+-\w+-\w+-\w+$/);
#$update_pos->{txt17} = $Ilockit_GUID if($Ilockit_GUID);
$update_cc->{txt17} = $Ilockit_GUID if($Ilockit_GUID);
#2022-10-02 manage lock_state before state
if($lock_state && $lock_state =~ /locking|locked|unlocking|unlocked/ && $record_pos->{cc_id} && $record_pos->{cc_id} > 0){
$booking_values = $self->smartlock($q,$varenv,$auth,$owner,$record_pos,$record_cc,$gps_data,$booking_values);
my $booking_pos = {
table => "contenttranspos",
fetch => "one",
c_id => "$record_pos->{c_id}",
};
$record_pos = $dbt->fetch_tablerecord($dbh,$booking_pos);
my $if_gps = $gps_data->{gps} || "";
$bw->log("log smartlock lock_state=$bike $lock_state, int10=$record_pos->{int10}, int20=$record_pos->{int20}, if_gps=$if_gps",$booking_values,"");
}
#6 = "canceled"|3 = "occupied"|1 = "available"
if($state_key && ($state_key == 6 || $state_key == 3 || $state_key == 1) && $record_pos->{cc_id} && $record_pos->{cc_id} > 0){
#set rent state if lock_system 2=Ilockit || 3=sigo
if($record_pos->{int11} && ($record_pos->{int11} == 2 || $record_pos->{int11} == 3)){
if($user_agent && $user_agent !~ /axios/){#keep device info if sig push
$update_pos->{txt21} = $q->escapeHTML($q->param('user_device')) if($q->param('user_device'));
$update_pos->{txt26} = $q->escapeHTML($user_agent) if($user_agent);
$update_pos->{txt27} = $q->escapeHTML($q->param('app_debug')) if($q->param('app_debug'));
}
#if($state eq canceled && $record_pos.state eq requested && $record_pos.lock_state eq locked)
if($state_key == 6 && $record_pos->{int10} == 2 && $record_pos->{int20} == 1){
$rows = $dbt->delete_content($dbh,"contenttranspos",$record_pos->{c_id});
if($rows > 0){
$update_cc->{int10} = 1 if($record_cc->{int10} == 2);#only if still requested
$booking_values->{response_state} = "OK: canceled bike " . $q->param('bike');
$booking_values->{response_text} = "Rad " . $q->param('bike') . " wurde erfolgreich storniert";
$booking_values->{state} = "available";
}else{
$booking_values->{response_state} = "Failure 2002: cancel bike " . $q->param('bike') . " fails, bike not requested";
$booking_values->{response_text} = "Keine Reservierung zu Rad " . $q->param('bike') . " gefunden.";
}
}else{
#prevent reset occupied values OR only if genkey defined
#if(($state eq "occupied" && $record_pos->{txt10} =~ /requested/) || ($state eq "occupied" && $record_pos->{txt10} =~ /occupied/ && $q->param('genkey') eq "1"))
if(($state_key == 3 && $record_pos->{int10} == 2) || ($state_key == 3 && $record_pos->{int10} == 3 && $q->param('genkey') eq "1")){
$update_pos->{start_time} = "now()";
$update_pos->{end_time} = "now()";
$update_pos->{txt05} = "$record_cc->{txt06}";#pos start GPS from content end GPS
$update_pos->{int06} = "$record_cc->{int04}";#pos start station from content station
$update_pos->{txt12} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}";#pos start station prefix
$update_pos->{int21} = $gps_data->{gps_age_minutes};
$update_pos->{int22} = $gps_data->{gps_accuracy};
$update_pos->{owner} = "$owner";
$update_pos->{int10} = 3;
$update_pos->{txt11} = "$sig_book->{rentalId}" if($sig_book->{rentalId});
$update_pos->{txt22} = "$sig_book->{bikeId}" if($sig_book->{bikeId});
$rows = $dbt->update_record($dbh,$update_pos,$record_pos);
if($rows > 0){
$booking_values->{response_state} = "OK: occupied bike " . $q->param('bike');
$booking_values->{response_text} = "Rad " . $q->param('bike') . " Miete gestartet. ";
$update_cc->{int10} = 3;
#$update_cc->{int04} = "null";#Because of servicetool, we hav to be keep the station
}
#fraud_rental sms_message
if($auth->{txt29} && $auth->{txt29} =~ /Betrug/){
$bw->log("$varenv->{basedir}/src/scripts/sms_message.pl $varenv->{syshost} fraud_rental '' $record_pos->{c_id}",$record_pos->{c_id},"");
system("$varenv->{basedir}/src/scripts/sms_message.pl $varenv->{syshost} fraud_rental '' $record_pos->{c_id} &");
}
#rental end only if locked
#if(state eq available && $record_pos.lock_state eq locked and pos-state 2=requested or 3=occupied
}elsif($state_key == 1 && $record_pos->{int20} == 1 && ($record_pos->{int10} == 2 || $record_pos->{int10} == 3)){
#client GPS must have. sigo ist done without client gps
if(($gps_data->{gps} && $gps_data->{gps_age_minutes} <= 3) || ($record_pos->{int11} == 3)){
#geofencing for Ilockit
my $geo_distance_next = 100000;
my $station_next = 0;
my $geo_debug="";
my $rows_end = 0;
my ($stations,$stations_raw) = $self->stations_available($q,$varenv,$auth,$record_pos,"");
foreach my $id (sort { $stations_raw->{$a}->{barcode} <=> $stations_raw->{$b}->{barcode} } keys (%$stations_raw)){
my $latitude_station = $1 if($stations_raw->{$id}->{txt06} =~ /^(\d+\.\d+)/);
my $longitude_station = $1 if($stations_raw->{$id}->{txt06} =~ /(\d+\.\d+)$/);
if((!looks_like_number($gps_data->{latitude}) || !looks_like_number($gps_data->{longitude})) && ($record_pos->{int11} != 3)){
$geo_debug .= "ERROR no user GPS: $stations_raw->{$id}->{int04}|$gps_data->{latitude},$gps_data->{longitude},$latitude_station,$longitude_station --> $gps_data->{geo_distance} Meter\n";
}elsif((looks_like_number($gps_data->{latitude}) && looks_like_number($gps_data->{longitude}) && looks_like_number($latitude_station) && looks_like_number($longitude_station)) || ($record_pos->{int11} == 3)){
$update_pos->{owner_end} = "$owner";
$update_pos->{end_time} = "now()";
$gps_data->{geo_distance} = $lb->geo_fencing($gps_data->{latitude},$gps_data->{longitude},$latitude_station,$longitude_station);
#sigo development workaround without geofence
if(($gps_data->{geo_distance} <= $stations_raw->{$id}->{int06}) || ($record_pos->{int11} == 3)){
$geo_distance_next = $gps_data->{geo_distance};
#end-Station
$update_pos->{int04} = $stations_raw->{$id}->{int04};
$update_cc->{int04} = $stations_raw->{$id}->{int04};
$update_pos->{int10} = 1;
$update_pos->{txt11} = "$sig_book->{rentalId}" if($sig_book->{rentalId});
$update_cc->{txt06} = "$gps_data->{gps}";#end content coordinates
$update_pos->{txt06} = "$gps_data->{gps}";#end pos coordinates
$update_pos->{int21} = $gps_data->{gps_age_minutes};
$update_pos->{int22} = $gps_data->{gps_accuracy};
$update_pos->{int23} = $gps_data->{geo_distance};
$update_pos->{int26} = "$sig_book->{distance}" if($sig_book->{distance});
$update_pos->{int28} = "$sig_book->{station_lock_state}" if($sig_book->{station_lock_state});
#end-Station prefix
$update_pos->{txt13} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}";
$update_cc->{txt13} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}";
#return after booking_update
#in real, we know freed accountable rentals only on rental end's
my $adjust_freedtime = 1;
$pri->count_freedrental($q,$varenv,$auth->{c_id},$record_pos,$adjust_freedtime);
my ($pricing,$counting) = $pri->counting_rental($varenv,$record_pos);
#int03 only used for tarif counting backwards compatibility
$update_pos->{int03} = "$pricing->{computed_hours}" if(looks_like_number($pricing->{computed_hours}));
$update_pos->{int38} = "$counting->{int38}" if(looks_like_number($counting->{int38}));
$update_pos->{int39} = "$counting->{int39}" if(looks_like_number($counting->{int39}));
$update_pos->{int40} = "$counting->{int40}" if(looks_like_number($counting->{int40}));
$update_pos->{int41} = "$counting->{int41}" if(looks_like_number($counting->{int41}));
$rows_end = $dbt->update_record($dbh,$update_pos,$record_pos);
if($rows_end > 0){
$update_cc->{int10} = 1;
$booking_values->{response_state} = "OK: available bike " . $q->param('bike');
$booking_values->{response_text} = "Danke! Die Miete Rad " . $q->param('bike') . " wurde beendet.";
}
$geo_debug .= "Matching station: $stations_raw->{$id}->{barcode}|$gps_data->{latitude},$gps_data->{longitude},$latitude_station,$longitude_station --> $gps_data->{geo_distance} Meter\n";
last;
}
#out of geofence
else{
if($gps_data->{geo_distance} <= $geo_distance_next){
$geo_distance_next = $gps_data->{geo_distance};
$station_next = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$stations_raw->{$id}->{int04}";
}
#2021-10-13 changed to save last gps @all
$update_cc->{txt06} = "$gps_data->{gps}";#end content coordinates
$update_pos->{txt06} = "$gps_data->{gps}";#end pos coordinates
$update_pos->{int21} = $gps_data->{gps_age_minutes};
$update_pos->{int22} = $gps_data->{gps_accuracy};
$update_pos->{int23} = $gps_data->{geo_distance};
#end-Station prefix
$update_pos->{txt13} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}";
$update_cc->{txt13} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}";
#return after booking_update
my ($pricing,$counting) = $pri->counting_rental($varenv,$record_pos);
#int03 only used for tarif counting backwards compatibility
$update_pos->{int03} = "$pricing->{computed_hours}" if(looks_like_number($pricing->{computed_hours}));
$update_pos->{int38} = "$counting->{int38}" if(looks_like_number($counting->{int38}));
$update_pos->{int39} = "$counting->{int39}" if(looks_like_number($counting->{int39}));
$update_pos->{int40} = "$counting->{int40}" if(looks_like_number($counting->{int40}));
$update_pos->{int41} = "$counting->{int41}" if(looks_like_number($counting->{int41}));
$rows_end = $dbt->update_record($dbh,$update_pos,$record_pos);
$geo_debug .= "Out of station distance: $stations_raw->{$id}->{int04}|rows_end:$rows_end|$gps_data->{latitude},$gps_data->{longitude},$latitude_station,$longitude_station --> $geo_distance_next Meter ($geo_distance_next <= $gps_data->{geo_distance}) station_next: $station_next\n";
if($record_pos->{int42} == 1){
$booking_values->{response_state} = "Failure 2179: bike " . $q->param('bike') . " out of GEO fencing. $geo_distance_next meter distance to A-A station $station_next .";
$booking_values->{response_text} = "Achtung! Dieses Mietrad darf nur an der Station zurück gegeben werden an der es ausgeliehen wurde. Die Miete zu Rad " . $q->param('bike') . " kann nicht $state_text werden. $geo_distance_next Meter Entfernung zur A-A Station $station_next . Falls Sie sich doch an der Station befinden, dann wiederholen Sie \"Miete beenden\".";
}else{
$booking_values->{response_state} = "Failure 2178: bike " . $q->param('bike') . " out of GEO fencing. $geo_distance_next meter distance to next station $station_next .";
$booking_values->{response_text} = "Achtung! Ihr aktueller Standort liegt außerhalb einer für das Mietende freigegebenen Radstation. Die Miete zu Rad " . $q->param('bike') . " kann nicht $state_text werden. $geo_distance_next Meter Entfernung zur nächsten Station $station_next . Falls Sie sich doch an einer Station befinden, dann wiederholen Sie \"Miete beenden\".";
}
}
}else{
$geo_debug .= "ERROR no station GPS: $stations_raw->{$id}->{int04}|$gps_data->{latitude},$gps_data->{longitude},$latitude_station,$longitude_station --> $gps_data->{geo_distance} Meter\n";
}
}
$booking_values->{geo_distance} = "$geo_distance_next";
#print "$geo_debug\n";
$bw->log("GEOfencing geo_debug:$geo_debug",$q,"");
#end if gps && gps_age <= 3 and not sigo
}elsif($record_pos->{int11} != 3){
if(!$gps_data->{gps}){
$booking_values->{response_state} = "Failure 2245: No GPS data, state change forbidden.";
$booking_values->{response_text} = "Fehler! Keine GPS Standortdaten, Die Miete Rad " . $q->param('bike') . " kann wegen fehlendem GPS nicht $state_text werden. Bitte aktivieren Sie das GPS.";
}else{
$booking_values->{response_state} = "Failure 2246: GPS age with $gps_data->{gps_age_minutes} minutes too old, state change forbidden.";
$booking_values->{response_text} = "Fehler! GPS Daten sind mit $gps_data->{gps_age_minutes} Minuten zu alt. Die Miete Rad " . $q->param('bike') . " kann aufgrund nicht aktueller GPS nicht $state_text werden. Bitte aktivieren Sie das GPS.";
}
}
#end if($state eq "available" && $record_pos.state eq occupied || $record_pos.lock_state ne locked
}elsif($state_key == 6 && ($record_pos->{int10} == 3 || $record_pos->{int20} != 1)){
$booking_values->{response_state} = "Failure 2012: occupied bike " . $q->param('bike') . " cannot be state $state and $lock_state";
$booking_values->{response_text} = "Rad " . $q->param('bike') . " ist in Benutzung und kann somit nicht storniert werden.";
}elsif($state_key == 3 && $record_pos->{int10} == 1){
$booking_values->{response_state} = "Failure 2016: available bike " . $q->param('bike') . " have to be at first reserved, thats because cannot be $state";
$booking_values->{response_text} = "Rad " . $q->param('bike') . " wurde nicht reserviert und kann somit nicht gemietet werden.";
}else{
$booking_values->{response_state} = "Failure 2035: bike " . $q->param('bike') . " state change to state $state and $lock_state not possible.";
$booking_values->{response_text} = "Fehler! Der Mietstatus zu Rad " . $q->param('bike') . " kann mit dem vorhandenen Status \"state:$state and lock_state:$lock_state\" nicht geändert werden.";
}
#contenttrans
my $update_ct = {
table => "contenttrans",
mtime => "now()",
owner => "$owner",
};
my $record_ct->{c_id} = $record_pos->{ct_id};
$dbt->update_record($dbh,$update_ct,$record_ct);
}
#end Ilockit || sigo
}else{
$bw->log("smartlock type not defined, int11:",$record_pos->{int11},"");
}
#update bike content
$bw->log("check ct_state on update_cc 2.",$update_cc,"");
$dbt->update_record($dbh,$update_cc,$record_cc);
}#end if $state =~ /canceled|occupied|available/
#fetch final booking state after request
if($record_pos->{c_id} && $record_pos->{c_id} > 0){
my $booking_pos = {
table => "contenttranspos",
fetch => "one",
c_id => "$record_pos->{c_id}",
};
my $booking = $dbt->fetch_tablerecord($dbh,$booking_pos);
if(ref($booking) eq "HASH" && $booking->{ct_name}){
#deprecated
$booking_values->{bike} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$booking->{barcode}";
$booking_values->{state} = "$dbt->{copri_conf}->{bike_state}->{$booking->{int10}}";
$booking_values->{lock_state} = "$dbt->{copri_conf}->{lock_state}->{$booking->{int20}}";
#new object after rental end
$booking_values->{bike_returned} = {};
if($booking->{int10} == 1){
$booking_values->{bike_returned}->{bike} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$booking->{barcode}";
$booking_values->{bike_returned}->{station} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$booking->{int04}";
$booking_values->{bike_returned}->{state} = "$dbt->{copri_conf}->{bike_state}->{$booking->{int10}}";
$booking_values->{bike_returned}->{lock_state} = "$dbt->{copri_conf}->{lock_state}->{$booking->{int20}}";
my ($pricing,$counting) = $pri->counting_rental($varenv,$booking);
if($pricing->{real_clock} && $pricing->{real_clock} =~ /[1-9]/){
my $time_unit = $dbt->time_format($varenv,$pricing->{real_clock});
$booking_values->{bike_returned}->{real_clock} = "$time_unit";#2023-09-12
}
if($pricing->{total_price} && $pricing->{total_price} > 0){
$pricing->{total_price} =~ s/\./,/ if($lang eq "de");
$booking_values->{bike_returned}->{total_price} = "$pricing->{total_price} €";#2023-09-12
}
#fetch tracking distance on Ilockit cloud by summary trip if(tracking && deviceId && available)
if($booking->{int25} == 1){
$bw->log("get co2saving",$booking->{c_id},"");
#if system=ilockit && clouid
if($record_pos->{int11} == 2 && $booking->{int13}){
sleep 2;#hopefully get distance in 2 sec.
system("$varenv->{basedir}/src/scripts/Ilockit_trackingcloud.pl $varenv->{syshost} get_tripsum $booking->{c_id}");
$booking = $dbt->fetch_tablerecord($dbh,$booking_pos);
#try it again with 20sec sleep
if(!$booking->{int26}){
$bw->log("$varenv->{basedir}/src/scripts/Ilockit_trackingcloud.pl $varenv->{syshost} get_tripsum $booking->{c_id} 20",$booking->{c_id},"");
system("$varenv->{basedir}/src/scripts/Ilockit_trackingcloud.pl $varenv->{syshost} get_tripsum $booking->{c_id} 20 &");
$booking = $dbt->fetch_tablerecord($dbh,$booking_pos);
}
}
my $co2saving = "";
$booking->{int26} = 10 if(!$booking->{int26} && ($auth->{c_id} == 5781 || $auth->{c_id} == 38883 || $auth->{c_id} == 37974));#10 km test
if($booking->{int26}){
$co2saving = "Einsparung: ";
my $co2diff = $pri->co2calc($booking);
#my $sprit_price = $pri->sprit2calc($booking);
$co2saving .= "$co2diff kg CO2, ";
#$co2saving .= "$sprit_price EUR " if($sprit_price !~ /-/);
$booking->{int26} =~ s/\./,/;
$co2saving .= "bei einer Strecke von $booking->{int26} KM";
$booking_values->{co2saving} = $co2saving;
$booking_values->{bike_returned}->{distance} = "$booking->{int26} km";#2023-09-12
$booking_values->{bike_returned}->{co2saving} = "$co2diff kg CO2";#2023-09-12
}
}
}
#user_miniquest_count on operator
my $dbh_primary = $dbt->dbconnect_extern($dbt->{primary}->{sharee_primary}->{database}->{dbname});
my $adref = {
table => "contentadr",
fetch => "one",
template_id => "202",
c_id => "$auth->{c_id}",
};
my $auth_prim = $dbt->fetch_record($dbh_primary,$adref);
if($booking->{int10} == 1 && $dbt->{operator}->{$varenv->{dbname}}->{project} eq "Bayern" && $auth_prim->{int23} < 4){
$bw->log("user_miniquery user ID $auth_prim->{c_id} exist count:",$auth_prim->{int23},"");
$booking_values->{user_miniquery} = $dbt->evaluationsfragen($dbh);
#user_miniquest_count
my $user_miniquest_count = $auth_prim->{int23} || 0;
if($user_miniquest_count <= 3){
$user_miniquest_count++;
my $update23 = {
table => "contentadr",
int23 => $user_miniquest_count,
atime => "now()",
};
$rows = $dbt->update_record($dbh,$update23,$auth_prim) if($auth_prim->{c_id} && !$dbt->{copri_conf}->{betau_id}->{$auth_prim->{c_id}});
}
}#end mini_quest
#reponse-log
if($booking_values->{response_text}){
my $response_log = $booking->{txt29} . "\n- $log_stamp $booking_values->{response_text}";
$dbt->update_one($dbh,$booking_pos,"txt29='$response_log'");
}
}
}
return ($rows,$booking_values);
}
#end booking_update
#
#smartlock state on request update
sub smartlock {
my $self = shift;
my $q = shift;
my $varenv = shift;
my $auth = shift;
my $owner = shift || 0;
my $record_pos = shift || {};
my $record_cc = shift || {};
my $gps_data = shift || {};
my $booking_values = shift || {};
my $user_agent = $q->user_agent();
my $dbh = "";
#content
my $update_cc = {
table => "content",
mtime => "now()",
owner => "$owner",
};
$update_cc->{txt28} = $q->escapeHTML($q->param('firmware')) if($q->param('firmware'));
#only by system=Ilockit
if($record_pos->{int11} eq "2" && $q->param('voltage') && $q->param('voltage') =~ /(\d+)/){
$update_cc->{int14} = $1;
$self->service_automatic($q,$varenv,"") if($1 <= 60);
}
my $update_pos = {
table => "contenttranspos",
mtime => "now()",
int24 => 0,
};
if($user_agent && $user_agent !~ /axios/){#keep device info if sig push
$update_pos->{int14} = $q->escapeHTML($q->param('voltage')) if($q->param('voltage'));
$update_pos->{txt21} = $q->escapeHTML($q->param('user_device')) if($q->param('user_device'));
$update_pos->{txt26} = $q->escapeHTML($user_agent) if($user_agent);
$update_pos->{txt27} = $q->escapeHTML($q->param('app_debug')) if($q->param('app_debug'));
$update_pos->{txt28} = $q->escapeHTML($q->param('firmware')) if($q->param('firmware'));
}
my $lock_value = 0;
if($q->param('lock_state') eq "locked"){
$lock_value = 1;
$update_cc->{int20} = "$lock_value";
$update_pos->{int20} = "$lock_value";
$update_pos->{end_time} = "now()";
$update_cc->{txt06} = $gps_data->{gps};#end content coordinates
$update_pos->{txt06} = $gps_data->{gps};#end pos coordinates
$update_pos->{int21} = $gps_data->{gps_age_minutes};
$update_pos->{int22} = $gps_data->{gps_accuracy};
$update_pos->{int23} = "null";# only computed on rental-end
$booking_values->{response_state} = "OK: bike " . $q->param('bike') . " locked confirmed. ";
$booking_values->{response_text} = "Schloss schließen von Rad " . $q->param('bike') . " bestätigt. ";
}elsif($q->param('lock_state') eq "unlocked"){
$lock_value = 2;
$update_cc->{int20} = "$lock_value";
$update_pos->{int20} = "$lock_value";
$booking_values->{response_state} = "OK: bike " . $q->param('bike') . " unlocked confirmed. ";
$booking_values->{response_text} = "Schloss öffnen von Rad " . $q->param('bike') . " bestätigt. ";
}elsif($q->param('lock_state') eq "locking"){
$lock_value = 3;
$update_cc->{int20} = "$lock_value";
$update_pos->{int20} = "$lock_value";
$booking_values->{response_state} = "OK: bike " . $q->param('bike') . " locking in progress. ";
$booking_values->{response_text} = "Schloss schließen von Rad " . $q->param('bike') . " ist im Prozess. Bitte warten bis das smartlock vollständig geschlossen wurde und das Schloss schließen bestätigt wird. ";
if($varenv->{dbname} ne "sharee_lv" && !$record_pos->{int32}){
$bw->log("$varenv->{basedir}/src/scripts/sms_message.pl $varenv->{syshost} locking_progress $auth->{c_id} $record_pos->{c_id}",$record_pos->{c_id},"");
system("$varenv->{basedir}/src/scripts/sms_message.pl $varenv->{syshost} locking_progress $auth->{c_id} $record_pos->{c_id} &");
}
$update_pos->{int32} = $record_pos->{int32} + 1;#sms_message sent marker
}elsif($q->param('lock_state') eq "unlocking"){
$lock_value = 4;
$update_cc->{int20} = "$lock_value";
$update_pos->{int20} = "$lock_value";
$booking_values->{response_state} = "OK: bike " . $q->param('bike') . " unlocking in progress. ";
$booking_values->{response_text} = "Schloss öffnen von Rad " . $q->param('bike') . " ist im Prozess. ";
}
$dbt->update_record($dbh,$update_pos,$record_pos);
$dbt->update_record($dbh,$update_cc,$record_cc);
return $booking_values;
}#end smartlock
#
#dedicated service insert automatic
sub service_automatic {
my $self = shift;
my $q = shift || "";
my $varenv = shift;
my $current_percent = shift || 0;
my $station_id = "";
my $bike_id = "";
$station_id = $1 if($q->param('station') =~ /(\d+)/);#could be also 0
$bike_id = $1 if($q->param('bike') && $q->param('bike') =~ /(\d+)/);
my $authraw = { c_id => $owner };#default sys API
my $charge = "";
if(looks_like_number($q->param('voltage'))){
$charge = "Achtung, Schloss-Akku Ladung " . $q->param('voltage') . "%";
}
if(looks_like_number($q->param('charge_current_bars'))){
$charge = "Achtung, Fahr-Akku Ladung " . $current_percent . "%";
}
my $response = {};
if(looks_like_number($bike_id) || looks_like_number($station_id)){
$q->param(-name=>'request',-value=>"service_done");
$q->param(-name=>'work_id',-value=>"txt01");
$q->param(-name=>'work_val',-value=>"$charge");
my $article = looks_like_number($bike_id) || looks_like_number($station_id);
#insert only new dataset if mtime > 10 days
(my $xresponse->{$article}, my $pos_record, my $node_template, my $crecord) = $self->service_select($q,$authraw,"","10");
my $service_id = "";
foreach my $id (sort { $pos_record->{$a}->{barcode} <=> $pos_record->{$b}->{barcode} } keys (%$pos_record)){
$service_id = $pos_record->{$id}->{c_id} if($pos_record->{$id}->{c_id} > 1);
}
if(!$service_id){
$crecord->{int04} = "null";#empty station
($response->{service_id}) = $self->service_insert($q,$authraw,$node_template,$crecord);
$bw->log("service_automatic insert ($response->{service_id}) ",$response,"");
my $rows = $self->service_update($q,$authraw,$node_template,$response->{service_id});
}elsif($service_id){
my $rows = $self->service_update($q,$authraw,$node_template,$service_id);
}
}
}
#user rentals_history
sub user_rentals_history(){
my $self = shift;
my $q = shift || "";
my $auth = shift;
my $daily = shift || 0;
my $allop = shift || 0;
my %varenv = $cf->envonline();
my $today = strftime("%Y-%m-%d",localtime(time));
my %operator_hash = ();
my $record_all = {};
if($auth->{c_id}){
my $pref = {
table => "contenttrans",
table_pos => "contenttranspos",
fetch => "all",
keyfield => "c_id",
ca_id => "$auth->{c_id}",
};
if($daily > 0){
$pref->{start_time} = ">=::$today";
}elsif(looks_like_number($q->param('month')) && $q->param('month') > 0){
my $month = $q->param('month');
$pref->{mtime} = ">=::(now() - interval '$month month')";
}else{
#2024-01-08 list not succesfully captured positions by also using ct.int14 >= 1
$pref->{'ct.state'} = "is::null";# ct.int04 is null OR ct.int14 >= 1
#$pref->{'ct.int14'} = "is::null";
}
if($allop || $varenv{dbname} eq $dbt->{primary}->{sharee_primary}->{database}->{dbname}){
#$bw->log("user_rentals_history userID: $auth->{c_id} with operators",$auth->{txt17},"");
if($auth->{txt17}){
if($auth->{txt17} =~ /\w\s\w/){
%operator_hash = map { $_ => "$dbt->{operator}{$_}->{operatorApp}" } split(/\s+/,$auth->{txt17});
}else{
$operator_hash{$auth->{txt17}} = "$dbt->{operator}{$auth->{txt17}}->{operatorApp}";
}
#adding primary to get prepaid
$operator_hash{sharee_primary} = "$dbt->{primary}{sharee_primary}->{primaryApp}" if($allop);
foreach my $sharee_operator (keys (%operator_hash)){
#$bw->log("operator_hash sharee_operator: $sharee_operator",$sharee_operator,"");
my $dbh_operator = "";
$dbh_operator = $dbt->dbconnect_extern("$sharee_operator");
if($dbh_operator){
my $cttpos = $dbt->collect_post($dbh_operator,$pref);
$record_all = { %$record_all, %$cttpos };
}
}
}
}else{
$record_all = $dbt->collect_post($dbh,$pref);
}
}
return ($record_all,\%operator_hash);
}#end user_rental_history
#last used rental to feedback
sub rental_to_feedback{
my $self = shift;
my $varenv = shift;
my $auth = shift;
my $dbh = "";
my $pref = {
table => "contenttrans",
table_pos => "contenttranspos",
fetch => "one",
template_id => "218",
ca_id => "$auth->{c_id}",
"ct.close_time" => "is::null",
int10 => "1",
int11 => "3",#sig system
int28 => "3",#set count on sig rental_end
end_time => ">=::(now() - interval '5 min')",
};
my $ctpos = { c_id => 0 };
$ctpos = $dbt->collect_post($dbh,$pref);
my $show_dialog = {};
if($dbt->{operator}->{$varenv->{dbname}}->{project} eq "Bayern"){
my $dbh_primary = $dbt->dbconnect_extern($dbt->{primary}->{sharee_primary}->{database}->{dbname});
my $adref = {
table => "contentadr",
fetch => "one",
template_id => "202",
c_id => "$auth->{c_id}",
};
my $auth_prim = $dbt->fetch_record($dbh_primary,$adref);
if(!$auth_prim->{int23} || $auth_prim->{int23} < 4){
$bw->log("user_miniquery via user ID $auth_prim->{c_id} exist count:",$auth_prim->{int23},"");
$show_dialog->{user_miniquery} = $dbt->evaluationsfragen($dbh);
}
$show_dialog->{co2saving} = "";
$ctpos->{int26} = 10 if(!$ctpos->{int26} && ($auth->{c_id} == 5781 || $auth->{c_id} == 38883));#10 km test
if($ctpos->{int26}){
my $co2saving = "Einsparung: ";
my $co2diff = $pri->co2calc($ctpos);
#my $sprit_price = $pri->sprit2calc($ctpos);
$co2saving .= "$co2diff kg CO2, ";
#$co2saving .= "$sprit_price EUR " if($sprit_price !~ /-/);
$ctpos->{int26} =~ s/\./,/;
$co2saving .= "bei einer Strecke von $ctpos->{int26} KM";
$show_dialog->{co2saving} = $co2saving;
}
}
return ($ctpos,$show_dialog);
}#end rental_to_feedback
#user bikes occupied
sub user_bikes_occupied {
my $self = shift;
my $dbh = shift;
my $auth = shift;
my $show_dialog = shift || "";
my $station = shift || "";
my $pref = {
table => "contenttrans",
table_pos => "contenttranspos",
fetch => "all",
template_id => "218",#Faktura tpl_id
keyfield => "c_id",
ca_id => "$auth->{c_id}",
int10 => "IN::('3','2')",
"ct.close_time" => "is::null",
};
$pref->{int06} = $station if($station);#pos start-station
my $record = {};
$record = $dbt->collect_post($dbh,$pref) if($auth->{c_id});
return $record;
}#end user_bikes_occupied
#rentals
#called by user_bikes_occupied (bikes_occupied object)
sub rentals(){
my $self = shift;
my $varenv_prim = shift;
my $record = shift;
my $auth = shift || "";
my $withkey = shift || 0;
my %varenv = $cf->envonline();
my $today4db = strftime("%Y-%m-%d %H:%M:%S",localtime(time));
my $return = {};
foreach my $id (sort { $record->{$a}->{end_time} cmp $record->{$b}->{end_time} } keys (%$record)){
my $pricing->{$id} = {};
my $counting = {};
#adjusting freed time rental by called bikes_occupied
#further_freedtime_available will be 0 if no further freed_time
my $adjust_freedtime = 1;
my $further_freedtime_available = 1;
$further_freedtime_available = $pri->count_freedrental("rentals by user_bikes_occupied",\%varenv,$auth->{c_id},$record->{$id},$adjust_freedtime);
$return->{$id}->{further_freedtime_available} = "$further_freedtime_available";
($pricing->{$id}, $counting) = $pri->counting_rental(\%varenv,$record->{$id});
#$bw->log("rentals-rentalog",$pricing->{$id}->{rentalog},"");
$pricing->{$id}->{rentalog} = "";#just for debuggiog, removed to reduce data in json
my $return_feed->{$id} = $pri->fetch_rentalfeed($varenv_prim,\%varenv,$record->{$id},$pricing->{$id},$further_freedtime_available);
$return->{$id} = { %{ $pricing->{$id} }, %{ $return_feed->{$id} } };
my $bike_id = $return->{$id}->{bike};
$bike_id = $1 if($bike_id =~ /(\d+)/);
#generate always new ilockit keys.
if($withkey && $record->{$id}->{int11} && $record->{$id}->{int11} == 2){
my @K_select = ();
@K_select = `cd /var/www/copri4/main/src/scripts && export CLASSPATH='.:/usr/share/java:/usr/share/java/postgresql.jar' && java Ilockauth $varenv{dbname} $bike_id`;
$bw->log("rentals java Ilockauth $bike_id | syshost:$varenv{syshost}",\@K_select,"");
foreach(@K_select){
my ($K_key,$K_val) = split(/ = /, $_);
$K_val =~ s/\n//g;
$return->{$id}->{K_seed} = "$K_val" if($K_key eq "K_seed");
$return->{$id}->{K_a} = "$K_val" if($K_key eq "K_a" && $auth->{int19} && $auth->{int19} == 1);
$return->{$id}->{K_u} = "$K_val" if($K_key eq "K_u");
}
}
$bw->log("user_bikes_occupied rentals bike $return->{$id}->{bike} | station $return->{$id}->{station} | state $return->{$id}->{state}, auth:$auth->{c_id}",$return->{$id}->{c_id},"");
}
return $return;
}#end rentals
#bikes_available
sub bikes_available(){
my $self = shift;
my $q = shift;
my $varenv_prim = shift;
my $varenv = shift;
my $auth = shift;
my $authed = 0;
my $lang = "de";
my $station = $q->escapeHTML($q->param('station')) || "";
my $station_id = "";
$station_id = $1 if($station =~ /(\d+)$/);
#to get A-A key for text
my $pref_st = {
table => "content",
fetch => "all",
keyfield => "int04",
template_id => "225",
int10 => "1",
};
my $record_st = {};
$pref_st->{int04} = "$station_id" if($station_id);
$record_st = $dbt->fetch_record($dbh,$pref_st);
my $bike = $q->escapeHTML($q->param('bike')) || "";
my $bike_id = $bike;
$bike_id =~ s/S[1-9]X/SX/;
$bike_id = $1 if($bike_id =~ /(\d+)/);
#my $users_serviceapp = $dbt->select_users($dbh,$auth->{c_id},"and int09=1");
my $return={};
my $pref = {
table => "content",
fetch => "all",
keyfield => "barcode",
template_id => "205",
int10 => "1",#1 = "available"
};
my $tariff_content = {};
my $adrtarif_hash = {};
$authed = 1 if(ref($auth) eq "HASH" && $auth->{c_id} > 0);
(my $bike_group,my $bike_node,my $user_tour,$tariff_content,$adrtarif_hash) = $self->fetch_tariff($varenv->{dbname},$auth,$q->param('authcookie'));
$bw->log("$varenv->{dbname} bikes_available bike_group:",$bike_group,"");
#print Dumper($bike_group);
#print Dumper($bike_node);
my $main_ids = join(",",@{$bike_node});
$main_ids =~ s/[a-z_-]+//ig;#should work also without Trenner
$pref = { %$pref, main_id => "IN::($main_ids)" };
if(looks_like_number($station_id)){
$pref = { %$pref, int04 => "=::" . $station_id };
}
if(looks_like_number($bike_id)){
$pref = { %$pref, barcode => "=::" . $bike_id };
}
my $record = {};
$record = $dbt->fetch_record($dbh,$pref) if(ref($bike_node) eq "ARRAY" && @{$bike_node}[0]);
my $op_return = {};
my $td_template = $dbt->rental_description_template($varenv_prim);
#return list of occupied/requested bikes
my $adjust_freedtime = 0;
my $further_freedtime_available = 1;
my ($cttpos,$operator_hash) = $self->user_rentals_history($q,$auth,1,0);
foreach my $id (sort { lc($cttpos->{$b}->{itime}) cmp lc($cttpos->{$a}->{itime}) } keys(%$cttpos)){
$further_freedtime_available = $pri->count_freedrental("rentals by bikes_available",$varenv,$auth->{c_id},$cttpos->{$id},$adjust_freedtime);
}
foreach my $id (sort { $record->{$a}->{barcode} <=> $record->{$b}->{barcode} } keys (%$record)){
$return->{$id}->{authed} = "$authed";
$return->{$id}->{station} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$record->{$id}->{int04}";
$return->{$id}->{aa_ride} = "0";
$return->{$id}->{aa_ride} = "1" if($record_st->{$record->{$id}->{int04}}->{int42});
$return->{$id}->{uri_operator} = "$dbt->{operator}->{$varenv->{dbname}}->{operatorApp}";
($return->{$id}->{gps}->{latitude},$return->{$id}->{gps}->{longitude}) = split(/,/,$record->{$id}->{txt06});
$return->{$id}->{bike} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$record->{$id}->{barcode}";
my $description = $q->unescapeHTML($record->{$id}->{txt01}) || "";
$return->{$id}->{description} = "$description";
#$return->{$id}->{description} = Encode::encode('utf-8', Encode::decode('iso-8859-1', $description));
$return->{$id}->{state} = "$dbt->{copri_conf}->{bike_state}->{$record->{$id}->{int10}}";
$return->{$id}->{lock_state} = "$dbt->{copri_conf}->{lock_state}->{$record->{$id}->{int20}}";
#defaults
$return->{$id}->{bike_group} = [];
$return->{$id}->{bike_type}->{category} = "city";
$return->{$id}->{bike_type}->{wheels} = "2";
#for station_type_id mapping
if($record->{$id}->{type_id}){
$return->{$id}->{bike_group} = ["$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$record->{$id}->{type_id}"];
if($record->{$id}->{type_id} == 300101){
$return->{$id}->{bike_type}->{category} = "cargo";
$return->{$id}->{bike_type}->{wheels} = "2";
$return->{$id}->{bike_type}->{wheels} = "3" if($record->{$id}->{txt01} =~ /drei|trike/i);
if($record->{$id}->{energy_id}){
$return->{$id}->{bike_type}->{engine}->{manufacturer} = "dummy";
my $max_bars = 5;
my $current_bars = 0;
my $charge_view_hidden = 0;#0=view charge
$charge_view_hidden = 1 if($record->{$id}->{battery_hidden});#1=hide charge view
my $backend_accessible = 0;#0=user has edit load
$backend_accessible = 1 if($record->{$id}->{battery_accessible});#1=charge from backend
$return->{$id}->{bike_type}->{battery}->{charge_max_bars} = "$max_bars";
$return->{$id}->{bike_type}->{battery}->{charge_current_bars} = "$current_bars";
$return->{$id}->{bike_type}->{battery}->{charge_current_percent} = "0";
$return->{$id}->{bike_type}->{battery}->{hidden} = "$charge_view_hidden";
$return->{$id}->{bike_type}->{battery}->{backend_accessible} = "$backend_accessible";
if($record->{$id}->{int19}){
$current_bars = $bw->battery_bars($max_bars,$record->{$id}->{int19});
$return->{$id}->{bike_type}->{battery}->{charge_current_bars} = "$current_bars";
$return->{$id}->{bike_type}->{battery}->{charge_current_percent} = "$record->{$id}->{int19}";
}
}
}
}
if($record->{$id}->{int11} eq "2"){
$return->{$id}->{system} = "Ilockit";
$return->{$id}->{Ilockit_GUID} = "$record->{$id}->{txt17}";
$return->{$id}->{Ilockit_ID} = "$record->{$id}->{txt18}";
}elsif($record->{$id}->{int11} eq "3"){
$return->{$id}->{system} = "sigo";
}
#2022-12-29 smartlock_type
$return->{$id}->{smartlock_type}->{engine}->{manufacturer} = "$dbt->{copri_conf}->{lock_system}->{$record->{$id}->{int11}}";
$return->{$id}->{smartlock_type}->{battery}->{charge_current_percent} = "$record->{$id}->{int14}";
if(ref($tariff_content) eq "HASH"){
foreach my $tid (sort { $tariff_content->{$a}->{barcode} <=> $tariff_content->{$b}->{barcode} } keys (%$tariff_content)){
my $unit_price1 = $tariff_content->{$tid}->{int35};
my $unit_price2 = $tariff_content->{$tid}->{int36};
my $max_fee = $tariff_content->{$tid}->{int17};
my $unit_time = $tariff_content->{$tid}->{time01};
my $free_time = $tariff_content->{$tid}->{time02};
if($lang eq "de"){
$unit_price1 =~ s/\./,/ if(looks_like_number($unit_price1));
$unit_price2 =~ s/\./,/ if(looks_like_number($unit_price2));
$max_fee =~ s/\./,/ if(looks_like_number($max_fee));
}
foreach my $atid (keys (%$adrtarif_hash)){
#print "if($record->{$id}->{main_id} == $tariff_content->{$tid}->{int12} && $atid == $tariff_content->{$tid}->{barcode}){\n";
if($record->{$id}->{main_id} == $tariff_content->{$tid}->{int12} && $atid == $tariff_content->{$tid}->{barcode}){
$bw->log("bikes_available for user c_id: $auth->{c_id} if($record->{$id}->{main_id} == $tariff_content->{$tid}->{int12} && $atid == $tariff_content->{$tid}->{barcode}) on BIKE:",$return->{$id}->{bike},"");
$return->{$id}->{rental_description}->{name} = "$tariff_content->{$tid}->{ct_name}";
$return->{$id}->{rental_description}->{id} = "$tariff_content->{$tid}->{barcode}";
$return->{$id}->{rental_description}->{tarif_type} = "$adrtarif_hash->{$tariff_content->{$tid}->{barcode}}";
$return->{$id}->{rental_description}->{reserve_timerange} = "15";
$return->{$id}->{rental_description}->{reserve_timerange} = "30" if($record->{$id}->{int11} == 3);#sig timeout time
$return->{$id}->{rental_description}->{rental_info}->{1} = ["Tracking","$varenv_prim->{cms}->{'info-tracking-degree'}->{txt}"] if($record->{$id}->{int25});
$return->{$id}->{rental_description}->{rental_info}->{2} = ["AAFahrten","$varenv_prim->{cms}->{'info-aa-ride'}->{txt}"] if($record_st->{$record->{$id}->{int04}}->{int42});
#$return->{$id}->{rental_description}->{rental_info}->{3} = ["Lowcharge","Die Akkukapazität war zuletzt niedrig. Bitte überprüfen sie vor der Fahrt die Ladung am Fahrraddisplay. Die Miete kann innerhalb 5 Minuten kostenlos abgebrochen werden."] if($record->{$id}->{energy_id} && (!$record->{$id}->{int19} || $record->{$id}->{int19} < 20));
my $i = 0;
foreach my $td (sort keys (%$td_template)){
my $time_unit = "Min";
#print "$tid|$tariff_content->{$tid}->{barcode}|$tariff_content->{$tid}->{int35}|$tariff_content->{$tid}->{time02}\n";
if($td_template->{$td}->{int35} && looks_like_number($tariff_content->{$tid}->{int35})){
$time_unit = $dbt->time_format($varenv_prim,$tariff_content->{$tid}->{time01}) if($tariff_content->{$tid}->{time01} =~ /[1-9]/);
$return->{$id}->{rental_description}->{tarif_elements}->{$td} = ["$td_template->{$td}->{int35}","$unit_price1 € / $time_unit"];
}elsif($td_template->{$td}->{int36} && $tariff_content->{$tid}->{int36} && $tariff_content->{$tid}->{int36} > 0){
$time_unit = $dbt->time_format($varenv_prim,$tariff_content->{$tid}->{time01}) if($tariff_content->{$tid}->{time01} =~ /[1-9]/);
$return->{$id}->{rental_description}->{tarif_elements}->{$td} = ["$td_template->{$td}->{int36}", "$unit_price2 € / $time_unit"];
}elsif($td_template->{$td}->{int17} && $tariff_content->{$tid}->{int17} && $tariff_content->{$tid}->{int17} > 0){
$return->{$id}->{rental_description}->{tarif_elements}->{$td} = ["$td_template->{$td}->{int17}","$max_fee € / 24 $varenv_prim->{cms}->{'unit-hour'}->{txt}"];
}elsif($td_template->{$td}->{time02}){
if($tariff_content->{$tid}->{time02} =~ /[1-9]/){
if($further_freedtime_available == 1 || !$auth->{c_id}){
$time_unit = $dbt->time_format($varenv_prim,$tariff_content->{$tid}->{time02});
$time_unit .= " / $varenv_prim->{cms}->{'unit-day'}->{txt}" if($dbt->{operator}->{$varenv->{dbname}}->{project} ne "Konstanz");
$return->{$id}->{rental_description}->{tarif_elements}->{$td} = ["$td_template->{$td}->{time02}","$time_unit"];
}
}else{
delete $return->{$id}->{rental_description}->{tarif_elements}->{$td};
}
}
}#end foreach my $td (sort keys (%$td_template))
}
}#end foreach my $atid (keys (%$adrtarif_hash))
}
}
$op_return->{$dbt->{operator}->{$varenv->{dbname}}->{oprefix} . $id} = $return->{$id};
}
return $op_return;
}#end bikes_available
#bikes_all
sub bikes_all(){
my $self = shift;
my $q = shift;
my $varenv = shift;
my $auth = shift || {};
my $stations_allraw = shift || "";
#my $users_serviceapp = $dbt->select_users($dbh,$auth->{c_id},"and int09=1");
my $return={};
my $pref = {
table => "content",
fetch => "all",
keyfield => "barcode",
template_id => "205",
};
my ($bike_group,$bike_node,$user_tour,$tariff_content,$adrtarif_hash) = $self->fetch_tariff($varenv->{dbname},$auth,$q->param('authcookie'));
my $main_ids = join(",",@{$bike_node});
$main_ids =~ s/[a-z_]+//ig;
$pref->{main_id} = "IN::($main_ids)";
my $station_id = "";
my $bike_id = "";
#$station_id = $1 if($q->param('station') && $q->param('station') =~ /(\d+)/);#doesn't get 0
$station_id = $1 if($q->param('station') =~ /(\d+)/);
$bike_id = $1 if($q->param('bike') && $q->param('bike') =~ /(\d+)/);
$pref->{int04} = "=::$station_id" if(looks_like_number($station_id));
if(looks_like_number($bike_id)){
$pref->{ barcode} = "=::$bike_id";
#2022-12-02 not select occupied bikes in servicetool by direct select-bike
$pref->{int10} = "!=::3";
#}else{
#2023-05-23 not select requested and occupied bikes in servicetool by list-bikes?
#$pref->{int10} = "IN::(1,4,5,6)";
}
my $record = {};
#on servicetool only stations on user_tour
#$bw->log("stations_service_tour of adr c_id: $auth->{c_id}",$stations_allraw,"");
my @stations_service_tour = ();
#shareetool
if(!$pref->{int04} && $q->param('authcookie') && $dbt->{merchant_ids}->{$varenv->{merchant_id}}->{id} && $dbt->{merchant_ids}->{$varenv->{merchant_id}}->{id} == 187){
my $stations = "";
if(ref($stations_allraw) eq "HASH" && scalar(@{$user_tour} >= 1)){
foreach my $id (sort { $stations_allraw->{$a}->{int04} <=> $stations_allraw->{$b}->{int04} } keys (%$stations_allraw)){
push(@stations_service_tour, $stations_allraw->{$id}->{int04}) if(looks_like_number($stations_allraw->{$id}->{int04}));
}
$stations = join(",",@stations_service_tour);
$stations =~ s/[a-z_]+//ig;
$pref->{int04} = "IN::($stations)" if($stations || $stations eq "0");
}
}
$bw->log("sub bikes_all with user_tour ($station_id) @stations_service_tour",$pref,"");
$record = $dbt->fetch_record($dbh,$pref) if(ref($bike_node) eq "ARRAY" && @{$bike_node}[0]);
my $bikes_on_station = {};
my $op_return = {};
foreach my $id (sort { $record->{$a}->{barcode} <=> $record->{$b}->{barcode} } keys (%$record)){
if(1==1){
$bikes_on_station->{$record->{$id}->{int04}}->{bike_ist} += 1;
$return->{$id}->{uri_operator} = "$dbt->{operator}->{$varenv->{dbname}}->{operatorApp}";
$return->{$id}->{station} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$record->{$id}->{int04}";
($return->{$id}->{gps}->{latitude},$return->{$id}->{gps}->{longitude}) = split(/,/,$record->{$id}->{txt06});
$return->{$id}->{bike} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$record->{$id}->{barcode}";
my $description = $q->unescapeHTML($record->{$id}->{txt01}) || "";
$return->{$id}->{description} = "$description";
#$return->{$id}->{description} = Encode::encode('utf-8', Encode::decode('iso-8859-1', $description));
$return->{$id}->{state} = "$dbt->{copri_conf}->{bike_state}->{$record->{$id}->{int10}}";
$return->{$id}->{service_state} = "0";
$return->{$id}->{lock_state} = "$dbt->{copri_conf}->{lock_state}->{$record->{$id}->{int20}}";
#defaults
$return->{$id}->{bike_group} = [];
$return->{$id}->{bike_type}->{category} = "city";
$return->{$id}->{bike_type}->{wheels} = "2";
#for station_type_id mapping
if($record->{$id}->{type_id}){
$return->{$id}->{bike_group} = ["$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$record->{$id}->{type_id}"];
if($record->{$id}->{type_id} == 300101){
$return->{$id}->{bike_type}->{category} = "cargo";
$return->{$id}->{bike_type}->{wheels} = "2";
$return->{$id}->{bike_type}->{wheels} = "3" if($record->{$id}->{txt01} =~ /drei|trike/i);
if($record->{$id}->{energy_id}){
$return->{$id}->{bike_type}->{engine}->{manufacturer} = "dummy";
my $max_bars = 5;
my $current_bars = 0;
my $charge_view_hidden = 0;
$charge_view_hidden = 1 if($record->{$id}->{battery_hidden});#1=hide charge view
my $backend_accessible = 0;
$backend_accessible = 1 if($record->{$id}->{battery_accessible});#1=charge from backend
$return->{$id}->{bike_type}->{battery}->{charge_max_bars} = "$max_bars";
$return->{$id}->{bike_type}->{battery}->{charge_current_bars} = "$current_bars";
$return->{$id}->{bike_type}->{battery}->{charge_current_percent} = "0";
$return->{$id}->{bike_type}->{battery}->{hidden} = "$charge_view_hidden";
$return->{$id}->{bike_type}->{battery}->{backend_accessible} = "$backend_accessible";
if($record->{$id}->{int19}){
$current_bars = $bw->battery_bars($max_bars,$record->{$id}->{int19});
$return->{$id}->{bike_type}->{battery}->{charge_current_bars} = "$current_bars";
$return->{$id}->{bike_type}->{battery}->{charge_current_percent} = "$record->{$id}->{int19}";
}
}
}
}
if($record->{$id}->{int11} eq "2"){
$return->{$id}->{system} = "Ilockit";
$return->{$id}->{Ilockit_GUID} = "$record->{$id}->{txt17}";
$return->{$id}->{Ilockit_ID} = "$record->{$id}->{txt18}";
#shareetool servicetool
#if($q->param('authcookie') && $dbt->{merchant_ids}->{$varenv->{merchant_id}}->{id} && $dbt->{merchant_ids}->{$varenv->{merchant_id}}->{id} == 187 && scalar(@{$user_tour} >= 1)){
if($q->param('authcookie') && $varenv->{merchant_id} && $varenv->{merchant_id} eq $dbt->{appsframe}->{shareetool}->{merchant_id} && scalar(@{$user_tour} >= 1)){
#2023-01-18 temporarly for Konstanz deactivated
if(${$user_tour}[0] !~ /KN\d/){
my @service_code = split(/\s/,$record->{$id}->{txt23});
$return->{$id}->{service_code} = [@service_code];
}
}
}elsif($record->{$id}->{int11} eq "3"){
$return->{$id}->{system} = "sigo";
}
#2022-12-29 smartlock_type
$return->{$id}->{smartlock_type}->{engine}->{manufacturer} = "$dbt->{copri_conf}->{lock_system}->{$record->{$id}->{int11}}";
$return->{$id}->{smartlock_type}->{battery}->{charge_current_percent} = "$record->{$id}->{int14}";
$op_return->{$dbt->{operator}->{$varenv->{dbname}}->{oprefix} . $id} = $return->{$id};
}
}
return ($op_return,$record,$bikes_on_station);
}#end bikes_all
#station cache for each tarif
sub stations_caching {
my $self = shift;
my $q = shift || "";
my $varenv = shift;
my $auth = shift || "";
my $tariff = {
table => "content",
fetch => "all",
keyfield => "barcode",
template_id => "210",#Tariff tpl_id
};
my $tariff_all = $dbt->fetch_record($dbh,$tariff);
if(ref($tariff_all) eq "HASH"){
foreach my $cachme (keys (%$tariff_all)){
$self->stations_available($q,$varenv,$auth,"",$cachme);
}
}
return;
}
#stations_available
sub stations_available(){
my $self = shift;
my $q = shift || "";
my $varenv = shift;
my $auth = shift || "";
my $record_pos = shift || {};
my $cachme = shift || 0;
my $authed = 0;
$authed = 1 if(ref($auth) eq "HASH" && $auth->{c_id});
my $authcookie = $q->param('authcookie') || $q->cookie('domcookie') || "";
my ($bike_group,$bike_node,$user_tour,$tariff_content,$adrtarif_hash) = $self->fetch_tariff($varenv->{dbname},$auth,$authcookie,$cachme);
#$bw->log("fetch_tariff adrtarif_hash from $varenv->{dbname}\n",$adrtarif_hash,"");
#station_group and bike_group alias bike nodes.type_id
my $station_group = "";
$station_group = $record_pos->{int29} if(ref($record_pos) eq "HASH" && $record_pos->{int29});
#station_bike_node and bike_node alias bike nodes.main_id
my $station_bike_node = "";
$station_bike_node = $record_pos->{int12} if(ref($record_pos) eq "HASH" && $record_pos->{int12});
#for AA rentals take end- from start-station.
my $aa_station = 0;
$aa_station = $record_pos->{int06} if(ref($record_pos) eq "HASH" && $record_pos->{int06} && $record_pos->{int42});
my $return = {};
my $pref = {
table => "content",
fetch => "all",
keyfield => "int04",
template_id => "225",
int10 => "1",#1 = "available"
};
#select by bike.type_id bike-group on booking update, to get available stations on bike return by filter logic
my $pref_sql = "";
if(ref($record_pos) eq "HASH" && $record_pos->{int29}){
foreach my $type_id (@{$bike_group}){
#service user can redistribute to all
if($auth->{int09} && !$dbt->{copri_conf}->{betau_id}->{$auth->{c_id}}){
$pref_sql = "";
}
#A-A rental
#on rental-end select only station which is the same as on start and A-A
elsif($station_group && $type_id =~ /(\d+)/ && $aa_station){
my $group_id = $1;
if($group_id == $station_group){
$pref_sql = " and ct.int04 = $aa_station and ct.int42=1";
}
}
#A-B rental
#on rental-end select only stations which are in ststion_group and be A-B
elsif($station_group && $type_id =~ /(\d+)/){
my $group_id = $1;
if($group_id == $station_group){
$pref_sql = " and ct.txt25 like '%$group_id%' and (ct.int42=0 OR ct.int42 is null)";
}
}
}
}
#select by bike.main_id Flot only if no booking update, to keep private/hidden Tarif logic
else{
$pref_sql .= " and (";
foreach my $main_id (@{$bike_node}){
if($main_id =~ /(\d+)/){
my $node_id = $1;
$pref_sql .= " ct.txt24 like '%$node_id%' OR";
}
}
$pref_sql =~ s/OR$//;
$pref_sql .= ")";
}
$pref_sql = "" if($pref_sql !~ /\d/);
$bw->log("stations_available --> rental station_bike_node:$station_bike_node|rental aa_station:$aa_station|user has access to bike_node:@{$bike_node}|user has access to bike_group:@{$bike_group}|!$auth->{int09} && !$dbt->{copri_conf}->{betau_id}->{$auth->{c_id}}|pref_sql:\n",$pref_sql,"");
my $record = {};
$record = $dbt->fetch_record($dbh,$pref,$pref_sql) if(ref($bike_node) eq "ARRAY" && @{$bike_node}[0]);
#bike_count
my $bpref = {
table => "content",
fetch => "all",
keyfield => "barcode",
template_id => "205",
int10 => "1",
};
my $record_bikes = {};
$record_bikes = $dbt->fetch_record($dbh,$bpref,"");
my $hotline_hash = {
table => "contentuser",
fetch => "one",
template_id => 197,
c_id => "1",
};
my $hotline_data = {
txt01 => "",
txt84 => "",
txt07 => "",
txt08 => "",
};
$hotline_data = $dbt->fetch_record($dbh,$hotline_hash);
my $op_return = {};
foreach my $id (sort { $record->{$a}->{barcode} <=> $record->{$b}->{barcode} } keys (%$record)){
$record->{$id}->{txt06} =~ s/\s//g if($record->{$id}->{txt06});
if($record->{$id}->{txt06} && $record->{$id}->{txt06} =~ /\d+\.\d+\,\d+\.\d+/){
my $fleed = {
name => "",
hours => "",
phone => "",
email => "",
};
my $bike_count = 0;
my @bike_ids = ();
foreach my $b_id (keys (%$record_bikes)){
if($record->{$id}->{int04} == $record_bikes->{$b_id}->{int04}){
push @bike_ids,$dbt->{operator}->{$varenv->{dbname}}->{oprefix} . $record_bikes->{$b_id}->{barcode};
$bike_count++;
$fleed = {
name => "$record_bikes->{$b_id}->{fleed_name}",
hours => "$record_bikes->{$b_id}->{fleed_hours}",
phone => "$record_bikes->{$b_id}->{fleed_phone}",
email => "$record_bikes->{$b_id}->{fleed_email}",
};
}
}
$return->{$id}->{bike_count} = "$bike_count";
$return->{$id}->{bike_ids} = [@bike_ids];
$return->{$id}->{authed} = "$authed";
$return->{$id}->{capacity} = "$record->{$id}->{int05}" || "1";
$return->{$id}->{station} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$record->{$id}->{int04}";
$return->{$id}->{uri_operator} = "$dbt->{operator}->{$varenv->{dbname}}->{operatorApp}";
($return->{$id}->{gps}->{latitude},$return->{$id}->{gps}->{longitude}) = split(/,/,$record->{$id}->{txt06});
my $description = $q->unescapeHTML($record->{$id}->{txt01}) || "";
$return->{$id}->{description} = "$description";
$return->{$id}->{state} = "$dbt->{copri_conf}->{bike_state}->{$record->{$id}->{int10}}";
$return->{$id}->{gps_radius} = "$record->{$id}->{int06}";
#new station category
#defaults
$return->{$id}->{station_type} = {};
my @station_group = ();
if($record->{$id}->{txt25} && $record->{$id}->{txt25} =~ /\d\s\d/){
@station_group = split(/\s/,$record->{$id}->{txt25});
}elsif($record->{$id}->{txt25}){
@station_group = ("$record->{$id}->{txt25}");
}
foreach(@station_group){
if($_ && $dbt->{copri_conf}->{type_id}->{$_}){
$return->{$id}->{station_type}->{$dbt->{copri_conf}->{type_id}->{$_}}->{bike_group} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$_";
my $bike_count2 = 0;
foreach my $b_id (keys (%$record_bikes)){
if($record->{$id}->{int04} == $record_bikes->{$b_id}->{int04}){
$bike_count2++ if($_ == $record_bikes->{$b_id}->{type_id});
}
}
$return->{$id}->{station_type}->{$dbt->{copri_conf}->{type_id}->{$_}}->{bike_count} = "$bike_count2";
}
}
#deprecated
$return->{$id}->{station_group} = "";
if($record->{$id}->{txt25}){
$record->{$id}->{txt25} =~ s/(\d+)/$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$1/g;
my @station_group = split(/\s/,$record->{$id}->{txt25});
$return->{$id}->{station_group} = [@station_group];
}
if($fleed->{email} && $fleed->{phone}){
$return->{$id}->{operator_data} = {
operator_name => $fleed->{name},
operator_hours => $fleed->{hours},
operator_phone => $fleed->{phone},
operator_email => $fleed->{email},
};
}else{
$return->{$id}->{operator_data} = {
operator_name => $hotline_data->{txt01},
operator_hours => $hotline_data->{txt84},
operator_phone => $hotline_data->{txt07},
operator_email => $hotline_data->{txt08},
};
}
#not desired 2024-02-15
if(1==2){
$return->{$id}->{contact_data} = {
software => {
company_name => "$hotline_data->{txt01}",
opening_hours => "$hotline_data->{txt84}",
phone => "$hotline_data->{txt07}",
email => "$hotline_data->{txt08}"
},
hardware => {
company_name => "$fleed->{name}",
opening_hours => "$fleed->{hours}",
phone => "$fleed->{phone}",
email => "$fleed->{email}"
}
};
}
$return->{$id}->{cached} = "0";
$return->{$id}->{withpub} = "0";
if($dbt->{operator}->{$varenv->{dbname}}->{cache_station} == 1 && $cachme){
$return->{$id}->{cached} = "1";
foreach my $tarif_key (keys(%$adrtarif_hash)){
$return->{$id}->{withpub}= "1" if($adrtarif_hash->{$tarif_key} == 2);
}
}
$op_return->{$dbt->{operator}->{$varenv->{dbname}}->{oprefix} . $id} = $return->{$id};
}
}
#json caching
if($dbt->{operator}->{$varenv->{dbname}}->{cache_station} == 1 && $cachme){
#order by sharing_type
foreach my $tarif_key (keys(%$adrtarif_hash)){
my $stationsout = $json->pretty->encode($op_return);
if($cachme){
#not public
if($adrtarif_hash->{$tarif_key} == 3 || $adrtarif_hash->{$tarif_key} == 4){
$bw->log("tarif_key: $tarif_key, sharing_type: $adrtarif_hash->{$tarif_key} Trigger json-caching stations-$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$tarif_key.json by cachme:$cachme","","");
open(CACHE,">$dbt->{copri_conf}->{basedir}/$dbt->{operator}->{$varenv->{dbname}}->{dir_app}/json/stations-$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$tarif_key.json");
print CACHE $stationsout;
close(CACHE);
}
#public
else{
$bw->log("tarif_key: $tarif_key, sharing_type: $adrtarif_hash->{$tarif_key} Trigger json-caching stations-$dbt->{operator}->{$varenv->{dbname}}->{oprefix}.json by cachme:$cachme","","");
open(CACHE,">$dbt->{copri_conf}->{basedir}/$dbt->{operator}->{$varenv->{dbname}}->{dir_app}/json/stations-$dbt->{operator}->{$varenv->{dbname}}->{oprefix}.json");
print CACHE $stationsout;
close(CACHE);
}
}
}
}#end caching
return ($op_return, $record);
}#end stations_available
#stations_all (should only called by shareetool)
sub stations_all(){
my $self = shift;
my $q = shift || "";
my $varenv = shift;
my $bikes_on_station = shift || {};
my $auth = shift || "";
my $authed = 0;
$authed = 1 if(ref($auth) eq "HASH" && $auth->{c_id});
my ($bike_group,$bike_node,$user_tour,$tariff_content,$adrtarif_hash) = $self->fetch_tariff($varenv->{dbname},$auth,$q->param('authcookie'));
my $return={};
my $pref = {
table => "content",
fetch => "all",
keyfield => "int04",
template_id => "225",#Station_liste
};
my $station_id = "";
my $work_val_id = "";
$station_id = $1 if($q->param('station') =~ /(\d+)/);#could be also 0
$work_val_id = $1 if($q->param('work_val') && $q->param('work_val') =~ /(\d+)/);
if(looks_like_number($station_id)){
$pref->{int04} = "=::$station_id";
}elsif($q->param('work_id') && $q->param('work_id') eq "int04" && $work_val_id){
$pref->{int04} = "=::$work_val_id";
}
#if not shareetool then only available stations
$pref->{int10} = 1 if(!$q->param('authcookie') || !$varenv->{merchant_id} || !$dbt->{merchant_ids}->{$varenv->{merchant_id}}->{id} || $dbt->{merchant_ids}->{$varenv->{merchant_id}}->{id} != 187);
my $pref_sql = "";
$pref_sql .= " and (";
foreach(@{$bike_node}){
if($_ =~ /(\d+)/){
$pref_sql .= " ct.txt24 like '%$1%' OR";
}
}
$pref_sql =~ s/OR$//;
$pref_sql .= ")";
$pref_sql = "" if($pref_sql !~ /\d/);
my $record = {};
my $op_return = {};
my %user_tour = ();
#on servicetool only stations on user_tour
#shareetool
#$bw->log("stations user_tour by merchant id $dbt->{merchant_ids}->{$varenv->{merchant_id}}->{id} on $varenv->{dbname}",$user_tour,"");
if($q->param('authcookie') && $dbt->{merchant_ids}->{$varenv->{merchant_id}}->{id} && $dbt->{merchant_ids}->{$varenv->{merchant_id}}->{id} == 187){
if(scalar(@{$user_tour}) >= 1){
$pref_sql .= " AND (";
foreach(@{$user_tour}){
if($_ =~ /(\d+)/){
#$pref_sql .= " ct.int07=$1 OR";
$user_tour{$1} = 1;
$pref_sql .= " ct.txt07 like '%$1%' OR";
}
}
$pref_sql =~ s/OR$//;
$pref_sql .= ")";
$record = $dbt->fetch_record($dbh,$pref,$pref_sql) if(ref($bike_node) eq "ARRAY" && @{$bike_node}[0]);
}
}
#only nececarry if amount of available bikes lower then bike_soll (like konrad)
my $bike_ist_factor = 1;
#($bike_ist_factor,my $bikes_all_onstation,my $bike_soll_all) = $self->bikes_soll($record,$bikes_on_station);
#$bike_ist_factor = 1 if(!$bike_ist_factor || $bike_ist_factor > 1);
foreach my $id (sort { $record->{$a}->{barcode} <=> $record->{$b}->{barcode} } keys (%$record)){
my $bike_soll = $record->{$id}->{int05} || 0;# * $bike_ist_factor;
#my $bike_soll = $record->{$id}->{int05} * $bike_ist_factor;
#$bike_soll = $lb->round_half($bike_soll);
#$bike_soll =~ s/\.\d+//;#rounded integer
#$return->{$id}->{bike_ist_faktor} = "$bike_ist_factor|$bikes_all_onstation|$bike_soll_all";#debug
#"bike_ist_faktor" : "1.14|217|190", 2023-11-24 there are more bikes on station then soll
$return->{$id}->{authed} = "$authed";
$return->{$id}->{station} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$record->{$id}->{int04}";
$return->{$id}->{service_tour} = "";
#hashed because of one station can have multi station tour
#there is a restriction in servicetool because of service_tour assignment (can keep only one value)
#keep in mind to select only users user_tour which in service_tour,
#because there can only one station assignmemt. Should be array, also in shareetool!
my %station_tour = ();
if($record->{$id}->{txt07} && $record->{$id}->{txt07} =~ /\d\s\d/){
%station_tour = map { $_ => 1 } split(/\s+/,$record->{$id}->{txt07});
}elsif($record->{$id}->{txt07}){
$station_tour{$record->{$id}->{txt07}} = 1;
}
#if multi station tour defined then last numerical will assigend
foreach my $stour (sort { $a <=> $b }keys (%user_tour)){
if($station_tour{$stour}){
$return->{$id}->{service_tour} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$stour";
}
}
$return->{$id}->{uri_operator} = "$dbt->{operator}->{$varenv->{dbname}}->{operatorApp}";
($return->{$id}->{gps}->{latitude},$return->{$id}->{gps}->{longitude}) = split(/,/,$record->{$id}->{txt06});
if($record->{$id}->{description}){
my $description = $q->unescapeHTML($record->{$id}->{txt01}) || "";
$return->{$id}->{description} = "$description";
#$return->{$id}->{description} = Encode::encode('utf-8', Encode::decode('iso-8859-1', $description));
}else{
$return->{$id}->{description} = "---";
}
$return->{$id}->{state} = "$dbt->{copri_conf}->{bike_state}->{$record->{$id}->{int10}}";
$return->{$id}->{bike_soll} = "$bike_soll" || "0";
$return->{$id}->{bike_ist} = "$bikes_on_station->{$id}->{bike_ist}" || "0";
$return->{$id}->{station_group} = "";
$return->{$id}->{gps_radius} = "$record->{$id}->{int06}";
if($record->{$id}->{txt25}){
$record->{$id}->{txt25} =~ s/(\d+)/$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$1/g;
my @station_group = split(/\s/,$record->{$id}->{txt25});
$return->{$id}->{station_group} = [@station_group];
}
$op_return->{$dbt->{operator}->{$varenv->{dbname}}->{oprefix} . $id} = $return->{$id};
}
return ($op_return,$record);
}#end stations_all
#collect all bike_ist
sub bikes_soll(){
my $self = shift;
my $record = shift;
my $bikes_on_station = shift;
my $bike_soll_all = 0;
foreach my $id (sort { $record->{$a}->{barcode} <=> $record->{$b}->{barcode} } keys (%$record)){
$bike_soll_all += $record->{$id}->{int05};
}
#my $bikes_on_station_ist->{bikes_all} = '0';
my $bikes_on_station_ist->{bikes_all_onstation} = '0';
if(ref($bikes_on_station) eq "HASH"){
foreach my $st (keys(%$bikes_on_station)){
#$bikes_on_station_ist->{bikes_all} += $bikes_on_station->{$st}->{bike_ist};#incl st.0
$bikes_on_station_ist->{bikes_all_onstation} += $bikes_on_station->{$st}->{bike_ist} if($st > 0);
}
}
my $bike_ist_factor = 1;
if(looks_like_number($bikes_on_station_ist->{bikes_all_onstation}) && $bikes_on_station_ist->{bikes_all_onstation} > 0 && looks_like_number($bike_soll_all) && $bike_soll_all > 0){
$bike_ist_factor = sprintf('%.2f',$bikes_on_station_ist->{bikes_all_onstation} / $bike_soll_all);
}
return ($bike_ist_factor,$bikes_on_station_ist->{bikes_all_onstation},$bike_soll_all);
}
#Collect Tarif to get users bike access ----------------------
sub fetch_tariff(){
my $self = shift;
my $dbname = shift;
my $adr = shift || {};
my $authcookie = shift || "";
my $cachme = shift || 0;
my $merchant_id = "";
$merchant_id = $1 if($authcookie && $authcookie =~ /\w+_(\w+)$/);
my $tariff_all = "";
my @user_tour = ();
my $auth_operator = { c_id => 0, txt30 => "" };
#int18
#<sharing_type>
# 2 = "public"
# 3 = "private"
# 4 = "hidden-lv"
# 5 = "public-bonus"
#</sharing_type>
my $tariff = {
table => "content",
fetch => "all",
keyfield => "barcode",
template_id => "210",#Tariff tpl_id
};
my ($nodes,$rows) = $dbt->collect_node($dbh,$dbt->{shareedms_conf}->{waren});
#public caching
if($cachme eq "public"){
$tariff->{int18} = 2;
$tariff_all = $dbt->fetch_record($dbh,$tariff);
$bw->log("$dbname $cachme Tariff type for No operator registered user by int18:$tariff->{int18} select 1:",$tariff->{barcode},"");
}
elsif(looks_like_number($cachme) && $cachme > 0){
$tariff->{barcode} = $cachme;
$tariff_all = $dbt->fetch_record($dbh,$tariff);
if($tariff_all->{$cachme}->{int18} == 2 || $tariff_all->{$cachme}->{int18} == 5){
delete $tariff->{barcode};
$tariff->{int18} = 2;
$tariff_all = $dbt->fetch_record($dbh,$tariff);
}else{
$auth_operator = { txt30 => "$cachme" };
}
$bw->log("$dbname $cachme Tariff type for No operator registered user by barcode:$tariff->{barcode} OR int18: $tariff->{int18} select 2:",$tariff->{barcode},"");
}
#if no primary address then only 2=public
elsif((ref($adr) ne "HASH" || !$adr->{c_id}) && ($dbname ne "sharee_lv")){
$tariff->{int18} = 2;
$tariff_all = $dbt->fetch_record($dbh,$tariff);
$bw->log("$dbname Tariff type for No operator registered user by int18:$tariff->{int18} select 3:",$tariff->{barcode},"");
}
#select operators address to get users tarifnr array in txt30
elsif(ref($adr) eq "HASH" && $adr->{c_id}){
delete $tariff->{int18} if($tariff->{int18});
my $authref = {
table => "contentadr",
fetch => "one",
template_id => "202",
c_id => "=::$adr->{c_id}",
};
$auth_operator = $dbt->fetch_record($dbh,$authref);
#shareetool user_tour
if($auth_operator->{c_id} && $merchant_id && $dbt->{merchant_ids}->{$merchant_id}->{id} && $dbt->{merchant_ids}->{$merchant_id}->{id} == 187){
my $users_serviceapp = $dbt->select_users($dbh,$auth_operator->{c_id},"and int09=1");
if($users_serviceapp->{int09} && $users_serviceapp->{txt12}){
$users_serviceapp->{txt12} =~ s/(\d+)/$dbt->{operator}->{$dbname}->{oprefix}$1/g;
@user_tour = ($users_serviceapp->{txt12});
@user_tour = split(/\s/,$users_serviceapp->{txt12}) if($users_serviceapp->{txt12} =~ /\s/);
}
}#end user_tour
#4=hidden
if($dbname eq "sharee_lv"){
if($auth_operator->{txt30}){
$tariff->{int18} = 4;
}else{
$tariff->{int18} = 9;#disables because not defined
}
}
#else select all available user tarif entries
$tariff_all = $dbt->fetch_record($dbh,$tariff);
$bw->log("$dbname Tariff type for operator registered user with Tarif in txt30:$auth_operator->{txt30} with s-type int18:$tariff->{int18} select 4:",$auth_operator->{txt30},"");
}
#end operators address
else{
$bw->log("$dbname Tariff type NO tariff_all 4:","","");
}
my $oprefix = "";
$oprefix = "$dbt->{operator}->{$dbname}->{oprefix}" if($dbt->{operator}->{$dbname}->{oprefix});
#2023-03-13, just hash all tarif_type by tarif-Nr
#collect setted user tarifs and available public tarifs
my %tarif_hash = ();
my %adrtarif_hash = ();
my %bike_node = ();
my %bike_group = ();
if($auth_operator->{txt30} && $auth_operator->{txt30} =~ /\d\s\d/){
%tarif_hash = map { $_ => 1 } split(/\s+/,$auth_operator->{txt30});
}elsif($auth_operator->{txt30} && $auth_operator->{txt30} =~ /(\d+)/){
$tarif_hash{$1} = 1;
}
if(ref($tariff_all) eq "HASH"){
foreach my $rid (keys (%$tariff_all)){
#$bw->log("$dbname Tariff hash $auth_operator->{txt30}|$tariff_all->{$rid}->{barcode} --> $tarif_hash{$tariff_all->{$rid}->{barcode}}",\%tarif_hash,"");
if(ref(\%tarif_hash) eq "HASH" && $tarif_hash{$tariff_all->{$rid}->{barcode}}){
foreach my $tk (keys(%tarif_hash)){
$bw->log("Tarif FOUND condition: $tk && $rid && $tariff_all->{$rid}->{barcode} == $tk","","");
if($tk && $rid && $tariff_all->{$rid}->{barcode} == $tk){
$adrtarif_hash{$tariff_all->{$rid}->{barcode}} = $tariff_all->{$rid}->{int18} if($tariff_all->{$rid}->{int18});
$bw->log("Tarif FOUND with merchant $merchant_id with user-id $auth_operator->{c_id} if($tariff_all->{$rid}->{int12}) (s-type:$tariff_all->{$rid}->{int18})",$tariff_all->{$rid}->{barcode},"");
$bike_node{$oprefix . $tariff_all->{$rid}->{int12}} = 1;#sharee bike_node.main_id
my $type_id = $nodes->{$tariff_all->{$rid}->{int12}}->{type_id} || "";
$bike_group{$oprefix . $type_id} = 1 if($type_id);#sharee bike_node.type_id
}
}
}elsif($tariff_all->{$rid}->{int18} == 2){
$adrtarif_hash{$tariff_all->{$rid}->{barcode}} = $tariff_all->{$rid}->{int18};
$bw->log("Tarif FOUND with merchant $merchant_id without user-id! if($tariff_all->{$rid}->{int12}) (s-type:$tariff_all->{$rid}->{int18})",$tariff_all->{$rid}->{barcode},"");
$bike_node{$oprefix . $tariff_all->{$rid}->{int12}} = 1;#sharee bike_node.main_id
my $type_id = $nodes->{$tariff_all->{$rid}->{int12}}->{type_id} || "";
$bike_group{$oprefix . $type_id} = 1 if($type_id);#sharee bike_node.type_id
}
}
}
my @tarifnr = ();
my @bike_node = ();
my @bike_group = ();
@tarifnr = keys %adrtarif_hash;
@bike_node = keys %bike_node;
@bike_group = keys %bike_group;
$bw->log("Tarif FOUND FETCHED_Tarif by dbname:$dbname with merchant $merchant_id and optional userID $adr->{c_id} | bike_node:@bike_node | bike_group:@bike_group | user_tour:@user_tour | tarifnr: @tarifnr",\%adrtarif_hash,"");
return (\@bike_group,\@bike_node,\@user_tour,$tariff_all,\%adrtarif_hash);
}#end fetch_tariff
#check and set user-bike rental tarif
sub fetch_bike_tariff {
my $self = shift;
my $varenv = shift;
my $auth = shift;
my $bike = shift;
my $owner = shift;
my $bike_id = $bike || "";
$bike_id =~ s/S[1-9]X/SX/;
$bike_id = $1 if($bike_id =~ /(\d+)/);
my $main_ids = "";
my ($bike_group,$bike_node,$user_tour,$tariff_content,$adrtarif_hash) = $self->fetch_tariff($varenv->{dbname},$auth,"");
$main_ids = join(",",@{$bike_node});
$main_ids =~ s/[a-z_]+//ig;
my $ct_bike = {};
my $pref_cc = {
table => "content",
fetch => "one",
main_id => "IN::($main_ids)",
barcode => $bike_id,
template_id => 205,
#int10 => 1,
};
$ct_bike = $dbt->fetch_record($dbh,$pref_cc) if($main_ids);
#$tariff_nr in contentadr are saved by copri or user tarif-select!!!
my $tariff_nr = "";
my @adr_tariff = ();
if($auth->{txt30}){
@adr_tariff = ("$auth->{txt30}");
@adr_tariff = split(/\s+/,$auth->{txt30}) if($auth->{txt30} =~ /\w\s+\w/);
}
#This is the automatic user tariff setter
if(ref($ct_bike) eq "HASH" && $ct_bike->{main_id}){
foreach my $id (keys (%$tariff_content)){
foreach(@adr_tariff){
$bw->log("booking_request adr_tariff array form $auth->{txt30}",$_,"");
if($tariff_content->{$id}->{int12} && $tariff_content->{$id}->{int12} == $ct_bike->{main_id} && $tariff_content->{$id}->{barcode} && $_ == $tariff_content->{$id}->{barcode}){
$bw->log("booking_request tariff loop matches:",$tariff_content->{$id}->{barcode},"");
$tariff_nr = $tariff_content->{$id}->{barcode};
}
}
}
#if no tarif then update user account to fallback default public or private or hidden tarif
if(!$tariff_nr){
my $update_adr = {
table => "contentadr",
mtime => "now()",
owner => "$owner",
c_id => "$auth->{c_id}",
};
my @txt30 = ();
foreach my $id (keys (%$tariff_content)){
#</sharing_type>
if($tariff_content->{$id}->{int18} && ($tariff_content->{$id}->{int18} == 2 || $tariff_content->{$id}->{int18} == 3 || $tariff_content->{$id}->{int18} == 4)){
#auto set tarif if requested bike matches flot
if($tariff_content->{$id}->{int12} && $tariff_content->{$id}->{int12} == $ct_bike->{main_id} && $tariff_content->{$id}->{barcode}){
$bw->log("booking_request tariff loop matches:",$tariff_content->{$id}->{barcode},"");
$tariff_nr = $tariff_content->{$id}->{barcode};
push(@txt30, "$tariff_content->{$id}->{barcode}");
}
#add also other public tarif
elsif($tariff_content->{$id}->{int18} && $tariff_content->{$id}->{int18} == 2 && $tariff_content->{$id}->{int12} && $tariff_content->{$id}->{barcode}){
push(@txt30, "$tariff_content->{$id}->{barcode}");
}
#add private tarif for dmsuser
elsif($tariff_content->{$id}->{int18} && $tariff_content->{$id}->{int18} == 3 && $tariff_content->{$id}->{int12} && $tariff_content->{$id}->{barcode} && $auth->{int09}){
push(@txt30, "$tariff_content->{$id}->{barcode}");
}
}
}
$bw->log("booking_request NO user tariff defined, update user account to fallback default public or private or hidden",\@txt30,"");
$dbt->update_one($dbh,$update_adr,"txt30='@txt30'");
}else{
$bw->log("booking_request user tariff selected",$tariff_nr,"");
}
}
$bw->log("booking_request fetch_bike_tariff result ---> bike $ct_bike->{barcode} matching by bike_node: @{$bike_node} main_ids:$main_ids | bike_group by type_id:@{$bike_group} | Tarif selected: $tariff_nr",$tariff_content->{$tariff_nr}->{ct_name},"");
return ($ct_bike,$tariff_content->{$tariff_nr});
}#fetch_bike_tariff
#authout
sub authout(){
my $self = shift;
my $q = shift;
my $coo = shift || "";
my %varenv = $cf->envonline();
my $dbh = "";
my $record = { c_id => 0 };#if fails
my $return = { authcookie => "" };#if fails
my $cgi_authcookie = $q->param('authcookie') || $coo || "";
#$bw->log("authout coo:$cgi_authcookie",$q,"");
if($cgi_authcookie && length($cgi_authcookie) > 20){
my $authref = {
table => "contentadr",
fetch => "one",
#keyfield => "c_id",
template_id => "202",
txt05 => "like::" . "%" . $q->escapeHTML($cgi_authcookie) . "%",
};
$record = $dbt->fetch_record($dbh,$authref);
if ($record->{c_id} > 0 && length($record->{txt05}) > 20){
my $all_authcookie = $record->{txt05};
my @check_cookies = split(/\|/,$record->{txt05});
foreach(@check_cookies){
#if(length($_) > 20 && $_ eq $cgi_authcookie){
if(length($_) > 20 && $_ =~ /$cgi_authcookie/){
$return = { authcookie => $_ };
$all_authcookie =~ s/$_//g;#delete authcookie if available
$all_authcookie =~ s/\|$//;
$all_authcookie =~ s/\|\|/\|/g;
my $update = {
table => "contentadr",
txt05 => $all_authcookie,
};
#print Dumper($update);
my $rows = 0;
$rows = $dbt->update_record($dbh,$update,$record);
if($varenv{dbname} ne $dbt->{primary}->{sharee_primary}->{database}->{dbname}){
my $dbh_prim = $dbt->dbconnect_extern($dbt->{primary}->{sharee_primary}->{database}->{dbname});
$rows = $dbt->update_record($dbh_prim,$update,$record);
}
if($rows == 1){
$return = { authcookie => "1",
user_id => "$record->{txt08}",
user_group => [],
};
$return = { %$return, debuglevel => "$record->{int11}" } if($record->{int11});
$return = { %$return, Ilockit_admin => "$record->{int19}" } if($record->{int19});
}
}
}
}
}
return $return;
}#end authout
#auth_verify
sub auth_verify(){
my $self = shift;
my $q = shift;
my $coo = shift || "";
my $userc_id = shift || "";
my $simple_op = shift || "";
my $cgi_authcookie = $q->param('authcookie') || $q->param('sessionid') || $coo;
my $session_log = $q->param('sessionid') || "";
my $user_agent = $q->user_agent();
my $clientIP = $q->remote_addr();
my %varenv = ();
$varenv{dbname} = "";
%varenv = $cf->envonline();
my $record = { c_id => 0 };#if fails
my $return = { authcookie => "",
merchant_id => "",
user_tour => [],
user_group => []
};
my $bike_group = "";
my $bike_node = "";
my $user_tour = "";
my $tariff_content = "";
my $adrtarif_hash = "";
$return->{merchant_id} = $1 if($cgi_authcookie && $cgi_authcookie =~ /\w+_(\w+)$/);
my $netloc = $q->url(-base=>1);
$bw->log("--> auth_verify on dbname $varenv{dbname},\n Starting with authcookie: $cgi_authcookie",$netloc,"");
my $debug=0;
my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime;
open(FILE,">>$varenv{logdir}/authcookie.log") if($debug);
print FILE "\n*-->$now_dt $netloc | $varenv{dbname} | $cgi_authcookie\n" if($debug);
if($cgi_authcookie && length($cgi_authcookie) > 30){
my $authref = {
table => "contentadr",
fetch => "one",
template_id => "202",
txt05 => "like::" . "%" . $q->escapeHTML($cgi_authcookie) . "%",
};
my $auth_primary = { c_id => 0 };
my $auth_operator = { c_id => 0 };
$auth_operator = $dbt->fetch_record($dbh,$authref);
$record = $auth_operator;
#$bw->log("auth_verified on operator $varenv{dbname} anchor 1",$auth_operator->{c_id},"");
#just part of operator-routing (sharee account management)
if(!$simple_op && $varenv{dbname} ne $dbt->{primary}->{sharee_primary}->{database}->{dbname}){
#primary select
my $dbh_primary = $dbt->dbconnect_extern($dbt->{primary}->{sharee_primary}->{database}->{dbname});
$auth_primary = $dbt->fetch_record($dbh_primary,$authref);
if($auth_primary->{c_id} && $auth_primary->{c_id} > 0){
#$bw->log("auth_verified on primary anchor 2 by dbname $varenv{dbname}",$auth_primary->{c_id},"");
print FILE "auth_verified on primary anchor 2 by dbname $varenv{dbname} | pri $auth_primary->{c_id}\n" if($debug);
#On booking_request, user must be authenticated and addr must exist
#At first insert/update Operator dbname array on primary
if($q->param('request') && $q->param('request') eq "booking_request"){
#first, save operator array which are used
my %operator_hash = ();#local DB
$bw->log("booking_request auth_verified by dbname $varenv{dbname}",$auth_primary->{c_id},"");
print FILE "booking_request auth_verified by dbname $varenv{dbname} | pri $auth_primary->{c_id}\n" if($debug);
if($auth_primary->{txt17} && $auth_primary->{txt17} =~ /\w\s\w/){#append DB's
%operator_hash = map { $_ => 1 } split(/\s+/,$auth_primary->{txt17});
}elsif($auth_primary->{txt17}){
$operator_hash{$auth_primary->{txt17}} = 1;
}
$operator_hash{$varenv{dbname}} = 1;
my @operator_array = keys %operator_hash;
#$bw->log("auth_verified update operator keys by array: @operator_array",\%operator_hash,"");
print FILE "auth_verified update operator keys by array: @operator_array | pri $auth_primary->{c_id}\n" if($debug);
my $update_primary = {
table => "contentadr",
txt17 => "@operator_array",#operator ids
txt19 => "$varenv{dbname}",
atime => "now()",
owner => "198",#update initiated by primary
};
#if user_device
if ($auth_primary->{c_id} > 0 && $q->param('user_device')){
$update_primary->{txt14} = $q->escapeHTML($session_log) if($session_log);
$update_primary->{txt21} = $q->escapeHTML($q->param('user_device')) if($q->param('user_device'));
$update_primary->{txt25} = $q->escapeHTML($clientIP) if($clientIP);
$update_primary->{txt26} = $q->escapeHTML($user_agent) if($user_agent);
}
#first prepaid account check (not save because without rental history)
if($auth_primary->{int03} == 3){
my $prepaidhash = { prepaid_total => 0 };
$prepaidhash = $pay->collect_prepaid($dbh_primary,$auth_primary) if($auth_primary->{c_id});
if(!$prepaidhash->{prepaid_total} || $prepaidhash->{prepaid_total} < 0){
my $vde = $auth_primary->{int12} || 1;
$update_primary->{int12} = $vde;
}
$bw->log("auth_verify booking_request prepaid check",$update_primary,"");
}
my $rows = $dbt->update_record($dbh_primary,$update_primary,$auth_primary);
$auth_primary = $dbt->fetch_record($dbh_primary,$authref);
}
#if user on operator not able to authenticate because of adr authcookie does not exist
if(!$auth_operator->{c_id} || $auth_operator->{c_id} == 0 && $cgi_authcookie && length($cgi_authcookie) > 30){
#my $uid = 0;
#($uid,my $sec,my $merchant) = split(/_/,$cgi_authcookie);
$authref = {
table => "contentadr",
fetch => "one",
template_id => "202",
c_id => "=::$auth_primary->{c_id}",
#c_id => "=::$uid",
#txt05 => "like::" . "%" . $q->escapeHTML($cgi_authcookie) . "%"
};
my $auth_operator3 = { c_id => 0 };
$auth_operator3 = $dbt->fetch_record($dbh,$authref);# if($uid);
#$bw->log("auth_verified on operator anchor 3 by dbname $varenv{dbname}",$auth_operator3->{c_id},"");
print FILE "auth_verified on operator anchor 3 by dbname $varenv{dbname} | op3 $auth_operator3->{c_id}\n" if($debug);
#if user on operator available by userid c_id, then update authcookie
if($auth_operator3->{c_id} && $auth_operator3->{c_id} > 0){
my $authcookies = $auth_operator3->{txt05} . "|" . $cgi_authcookie;
#$bw->log("UPDATE adr on operator by dbname $varenv{dbname}",$auth_operator3->{c_id},"");
print FILE "UPDATE adr on operator by dbname $varenv{dbname} | op3 $auth_operator3->{c_id}\n" if($debug);
my $update = {
table => "contentadr",
#txt05 => "$authcookies",#authcookies
txt05 => "$auth_primary->{txt05}",#authcookies
atime => "now()",
#mtime => "now()",#only set mtime on real user-data change
owner => "198",#update initiated by primary
};
my $rows = $dbt->update_record($dbh,$update,$auth_operator3);
#else insert authenticated user from primary to operator
#
}elsif($auth_primary->{txt17} && $auth_primary->{txt17} =~ /$varenv{dbname}/){
#insert
my $c_id = 0;
if($auth_primary->{c_id} > 0){
$bw->log("INSERT adr from record_primary to operator by dbname $varenv{dbname}",$auth_primary->{c_id},"");
print FILE "INSERT adr from record_primary to operator by dbname $varenv{dbname} | pri $auth_primary->{c_id}\n" if($debug);
my $insert = {
%$auth_primary,
table => "contentadr",
mtime => 'now()',
owner => "198",
};
$c_id = $dbt->insert_contentoid($dbh,$insert,"reset_adropkeys");
}
}else{
#$bw->log("auth_verified on operator anchor 3 FAILS by dbname $varenv{dbname}. user seem not be activated",$auth_operator->{c_id},"");
print FILE "auth_verified on operator anchor 3 FAILS by dbname $varenv{dbname}. user seem not be activated | op $auth_operator->{c_id}\n" if($debug);
}
}
$auth_operator = $dbt->fetch_record($dbh,$authref);
if($auth_operator->{c_id} && $auth_operator->{c_id} > 0){
$record = $auth_operator;#At first try using operator to get Tarif
#$bw->log("auth_verified on operator anchor 2.2 by dbname $varenv{dbname}",$auth_operator->{c_id},"");
print FILE "auth_verified on operator anchor 2.2 by dbname $varenv{dbname} | op $auth_operator->{c_id}\n" if($debug);
}else{
$record = $auth_primary;
#$bw->log("auth_verified on primary anchor 2.3 by dbname $varenv{dbname}",$auth_primary->{c_id},"");
print FILE "auth_verified on primary anchor 2.3 by dbname $varenv{dbname} | pri $auth_primary->{c_id}\n" if($debug);
}
}else{# if($auth_primary->{c_id}) fails
#$bw->log("auth_verified on primary anchor 4 FAILS by dbname $varenv{dbname}.",$auth_primary->{c_id},"");
print FILE "auth_verified on primary anchor 4 FAILS by dbname $varenv{dbname} | pri $auth_primary->{c_id}\n" if($debug);
}
}elsif($varenv{dbname} eq $dbt->{primary}->{sharee_primary}->{database}->{dbname}){
$auth_primary = $dbt->fetch_record($dbh,$authref);
#$bw->log("auth_verified on operator anchor 4 by dbname $varenv{dbname}",$auth_primary->{c_id},"");
print FILE "auth_verified on operator anchor 4 by dbname $varenv{dbname} | pri $auth_primary->{c_id}\n" if($debug);
$record = $auth_primary;
}#end if($varenv{dbname} ne $dbt->{primary}->{sharee_primary}->{database}->{dbname})
if($varenv{dbname} ne $dbt->{primary}->{sharee_primary}->{database}->{dbname}){
($bike_group,$bike_node,$user_tour,$tariff_content,$adrtarif_hash) = $self->fetch_tariff($varenv{dbname},$record,$q->param('authcookie'));
}
if($record->{c_id} > 0 && length($record->{txt05}) > 30){
my @check_cookies = split(/\|/,$record->{txt05});
foreach(@check_cookies){
if(length($_) > 30 && $_ =~ /$cgi_authcookie/){
$return->{authcookie} = $cgi_authcookie;
$return->{user_id} = $record->{txt08};
$return->{user_group} = $bike_group;#yes, but deprecated
$return->{user_tour} = $user_tour;
$return->{debuglevel} = "$record->{int11}" if($record->{int11});
$return->{Ilockit_admin} = "$record->{int19}" if($record->{int19});
}
}
}
}elsif($userc_id && looks_like_number($userc_id) && length($userc_id) >= 4){
my $authref = {
table => "contentadr",
fetch => "one",
template_id => "202",
c_id => "=::$userc_id",
};
$record = $dbt->fetch_record($dbh,$authref);
($bike_group,$bike_node,$user_tour,$tariff_content,$adrtarif_hash) = $self->fetch_tariff($varenv{dbname},$record,$q->param('authcookie'));
#maybe there isnt't any authcookie still available on confirm
if ($record->{c_id} > 0){
$return->{user_id} = $record->{txt08};
$return->{user_group} = $bike_group;#yes, but deprecated
$return->{user_tour} = $user_tour;
$return->{debuglevel} = "$record->{int11}" if($record->{int11});
$return->{Ilockit_admin} = "$record->{int19}" if($record->{int19});
}
}else{
#$bw->log("auth_verified on operator anchor FAILS by dbname $varenv{dbname}, no authcookie, dump \$q",$q,"");
print FILE "auth_verified on operator anchor FAILS by dbname $varenv{dbname}, no authcookie\n" if($debug);
}
$return->{agb_checked} = "0";
$return->{agb_checked} = "1" if($record->{int14});#sharee AGB global
my $last_used_operator = $record->{txt19};#check if this is primary and/or useable
#$bw->log("last_used_operator selected by txt19:",$last_used_operator,"");
if($last_used_operator){
my $dbh_operator = $dbt->dbconnect_extern("$last_used_operator","iso-8859-1");
my $hotline_hash = {
table => "contentuser",
fetch => "one",
template_id => 197,
c_id => "1",
};
my $hotline_data = $dbt->fetch_record($dbh_operator,$hotline_hash);
$return->{last_used_operator} = {
"operator_name" => "",
"operator_hours" => "",
"operator_phone" => "",
"operator_email" => "",
};
$return->{last_used_operator}->{operator_name} = Encode::encode('utf-8', Encode::decode('iso-8859-1',$hotline_data->{txt01})) if($hotline_data->{txt01});
$return->{last_used_operator}->{operator_hours} = Encode::encode('utf-8', Encode::decode('iso-8859-1',$hotline_data->{txt84})) if($hotline_data->{txt84});
$return->{last_used_operator}->{operator_phone} = $hotline_data->{txt07} if($hotline_data->{txt07});
$return->{last_used_operator}->{operator_email} = $hotline_data->{txt08} if($hotline_data->{txt08});
}
#$bw->log("auth_verify done on txt05 authcookies by dbname $varenv{dbname}:",$record->{txt05},"");
#Servicetool only users with users.int09=1
#shareetool
if($varenv{dbname} ne $dbt->{primary}->{sharee_primary}->{database}->{dbname} && $return->{merchant_id} && $dbt->{merchant_ids}->{$return->{merchant_id}}->{id} && $dbt->{merchant_ids}->{$return->{merchant_id}}->{id} == 187){
my $users_serviceapp = { u_id => 0 };
$users_serviceapp = $dbt->select_users($dbh,$record->{c_id},"and int09=1");
#$bw->log("users_serviceapp: $users_serviceapp->{u_id} && $varenv{dbname} && $return->{merchant_id} && $dbt->{merchant_ids}->{$return->{merchant_id}}->{id}","","");
if(!$users_serviceapp->{u_id} || $users_serviceapp->{u_id} == 0){
$record = { c_id => 0 };
$return = { c_id => 0 };
#$bw->log("reset auth_verify because of only Servicetool users access:",$record,"");
}
print FILE "users_serviceapp: $users_serviceapp->{u_id} | $return->{authcookie}\n" if($debug);
}
print FILE "final return: $return->{authcookie}\n" if($debug);
close(FILE) if($debug);
return ($return,$record);
}#end auth_verify
#authorization
sub authorization(){
my $self = shift;
my $q = shift;
my $merchant_id = shift || $q->param('merchant_id') || "";
my $hw_id = shift || $q->param('hw_id') || "";
my $lang = shift || "";
my $aowner = shift || 0;
$dbh = "";
my %varenv = $cf->envonline();
my $user_id = $q->param('user_id') || $q->param('txt08');
my $user_pw = $q->param('user_pw') || $q->param('txt04');
#print "user_pw:" . $q->param('user_pw') . "|txt04:" . $q->param('txt04') . "|user_pw:" . $q->param('user_pw');
my $pw_length = 8;
my $record = { c_id => 0 };#if fails
my $return = { authcookie => "" };#if fails
#print "$hw_id | $merchant_id | $user_id | $user_pw\n";exit;
if($user_id && length($user_id) >= 4 && $user_pw && length($user_pw) >= $pw_length && length($hw_id) >= 10 && length($merchant_id) >= 8){
my $authref = {
table => "contentadr",
fetch => "one",
template_id => "202",
txt08 => "ilike::" . $q->escapeHTML($user_id),
int05 => "1",
};
my $pass_name = $q->escapeHTML($user_pw);
$pass_name =~ s/\s//g;
my $pwmd5=md5_hex($pass_name) || "";
my $pwsha256=sha256_base64($pwmd5) || "";
$authref->{txt04} = "$pwsha256";
#Servicetool, only users with users.int09=1
#shareetool
if($varenv{dbname} ne $dbt->{primary}->{sharee_primary}->{database}->{dbname} && $aowner && $aowner eq "187"){
my $users_serviceapp = { u_id => 0 };
$users_serviceapp = $dbt->select_users($dbh,$record->{c_id},"and int09=1");
$record = { c_id => 0 } if(!$users_serviceapp->{u_id});
}else{
#2021-10-13 because of keep DMS authcookie
#2021-12-23 user must always be registered on sharee_primary
$dbh = $dbt->dbconnect_extern($dbt->{primary}->{sharee_primary}->{database}->{dbname}) if($varenv{dbname} ne $dbt->{primary}->{sharee_primary}->{database}->{dbname});
$record = $dbt->fetch_record($dbh,$authref);
}
$return = $self->authcookie_manager($dbh,$q,$record,$merchant_id,$hw_id,$lang,$aowner);
}else{
$bw->log("authorization fails because of failing condition: if($user_id && length($user_id) >= 4 && length($user_pw) >= $pw_length && length($hw_id) >= 10 && length($merchant_id) >= 8)","","");
}
return $return;
}#end authorization
#manage authcookie
sub authcookie_manager {
my $self = shift;
$dbh = shift;
my $q = shift;
my $record = shift || {};
my $merchant_id = shift || "";
my $hw_id = shift || "";
my $lang = shift || "";
my $aowner = shift || 0;
my $user_agent = $q->user_agent();
my $clientIP = $q->remote_addr();
my $return = { authcookie => "" };#if fails
my %varenv = $cf->envonline();
my $authcookie=md5_hex($record->{txt08}.$q->escapeHTML($hw_id));
$bw->log("generating authcookie with input: $record->{txt08}.$hw_id",$authcookie,"");
$authcookie = $record->{c_id} . "_" . $authcookie . "_" . $q->escapeHTML($merchant_id);
#if user_id && user_pw matched
if ($record->{c_id} > 0 && length($authcookie) > 20){
my $update = {
table => "contentadr",
atime => "now()",
int15 => "$aowner",#update on access
#mtime => "now()",
#owner => "198",#update initiated by primary
};
$update->{txt11} = $q->escapeHTML($lang) if($lang);
$update->{txt21} = $q->escapeHTML($q->param('user_device')) if($q->param('user_device'));
$update->{txt25} = $q->escapeHTML($clientIP) if($clientIP);
$update->{txt26} = $q->escapeHTML($user_agent) if($user_agent);
my @registered_cookies;
my $registered_cookies;
my @check_cookies = split(/\|/,$record->{txt05});
#$bw->log("check_cookies","@check_cookies","");
@check_cookies = reverse(@check_cookies);
my $i=0;
foreach(@check_cookies){
$i++;
#secure shortage cookies
if(length($_) > 20 && $i < 8){#max 8 clients
#$bw->log("$i < 8 cookies",$_,"");
push @registered_cookies,$_;
}
}
@registered_cookies = reverse(@registered_cookies);
foreach(@registered_cookies){
$registered_cookies .= "$_|" if(length($_) > 20);#secure shortage cookies
}
$registered_cookies =~ s/\|$//;
$bw->log("generated authcookie",$authcookie,"");
#return still existing authcookie
if($registered_cookies && $registered_cookies =~ /$authcookie/){
my $rows = $dbt->update_record($dbh,$update,$record);
$return = { authcookie => "$authcookie",
new_authcoo => "0",
user_id => "$record->{txt08}",
};
#return new generated authcookie
}else{
my $all_authcookie = $authcookie;
$all_authcookie = $registered_cookies . "|" . $authcookie if($registered_cookies);
$update->{txt05} = $all_authcookie;
my $rows = $dbt->update_record($dbh,$update,$record);
#update also operator cookies
if($varenv{dbname} eq $dbt->{primary}->{sharee_primary}->{database}->{dbname} && $record->{txt17}){
my $auth_primary = $record;
my %operator_hash = ();
if($auth_primary->{txt17} =~ /\w\s\w/){
%operator_hash = map { $_ => 1 } split(/\s+/,$auth_primary->{txt17});
}else{
$operator_hash{$auth_primary->{txt17}} = 1;
}
foreach my $sharee_operator (keys (%operator_hash)){
my $dbh_operator = $dbt->dbconnect_extern("$sharee_operator");
my $authref = {
table => "contentadr",
fetch => "one",
template_id => "202",
c_id => "$auth_primary->{c_id}",
};
my $auth_operator = { c_id => 0 };
$auth_operator = $dbt->fetch_record($dbh_operator,$authref);
#if user on operator available by userid c_id, then update authcookie
if($auth_operator->{c_id}){
$bw->log("update adr from record_primary to operator \"$sharee_operator\" after new new_authcoo",$update,"");
my $rows = $dbt->update_record($dbh_operator,$update,$auth_operator);
}
}
}
#end update operator cookies
if($rows == 1){
$return = { authcookie => "$authcookie",
new_authcoo => "1",
user_id => "$record->{txt08}",
};
}
}
}
$return->{debuglevel} = "$record->{int11}" if($record->{int11});
$return->{Ilockit_admin} = "$record->{int19}" if($record->{int19});
$return->{agb_checked} = "0";
$return->{agb_checked} = "1" if($record->{int14});#sharee AGB global
return $return;
}
1;