diff --git a/copri4/main/js/rentalator.js b/copri4/main/js/rentalator.js new file mode 100644 index 0000000..83d6aae --- /dev/null +++ b/copri4/main/js/rentalator.js @@ -0,0 +1,84 @@ + +function rental_request(url,bikeID,bookingID) { + console.log('getURL: ' + url); + console.log('bike: ' + bikeID); + console.log('pos_id: ' + bookingID); + if(bookingID){ + bikeID = bookingID; + console.log('Take bikeID from requesting bookinID: ' + bikeID); + } + const button_reserv = document.querySelector('#button_reserv_' + bikeID); + const button_cancel = document.querySelector('#button_cancel_' + bikeID); + const return_state = document.querySelector('#return_state_' + bikeID); + const reserved_bikes = document.querySelector('#reserved_bikes'); + + $.getJSON( url, function( data ) { + console.log('state=' + data.shareejson.state + '|bike: ' + data.shareejson.bike + '==' + bikeID + '| bookingID: ' + data.shareejson.pos_id + '==' + bookingID); + + var DID = data.shareejson.bike; + if(data.shareejson.pos_id && bookingID){ + DID = data.shareejson.pos_id; + console.log('Take DID from responsing pos_id: ' + DID); + } + + if(data.shareejson.response_state.match(/Failure/)){ + return_state.style = 'color:red'; + } + + if(data.shareejson.state == 'requested' && DID == bikeID){ + return_state.textContent = data.shareejson.response_text; + button_reserv.style.display = 'none'; + button_cancel.style.display = 'block'; + } + else if(data.shareejson.state == 'reserved' && DID == bikeID){ + return_state.textContent = data.shareejson.response_text; + button_reserv.style.display = 'none'; + button_cancel.style.display = 'block'; + } + else if(data.shareejson.state == 'available' && DID == bikeID){ + return_state.textContent = data.shareejson.response_text; + button_cancel.style.display = 'none'; + button_reserv.style.display = 'block'; + } + else { + return_state.style = 'color:red'; + return_state.textContent = data.shareejson.response_text; + } + + if(1 == 2){ + for (const key in data.shareejson.bikes_occupied) { + console.log(key + ':' + data.shareejson.bikes_occupied[key].bike); + reserved_bikes.textContent = data.shareejson.bikes_occupied[key].bike; + } + } + + }); +} +var acc = document.getElementsByClassName("accordion"); +var i; + +for (i = 0; i < acc.length; i++) { + acc[i].addEventListener("click", function() { + this.classList.toggle("active"); + var panel = this.nextElementSibling; + if (panel.style.maxHeight) { + panel.style.maxHeight = null; + } else { + panel.style.maxHeight = panel.scrollHeight + "px"; + } + }); +} + +var scrollToTopBtn = document.getElementById("scroll-top-wrapper"); +var rootElement = document.documentElement; + +function scrollToTop() { + // Scroll to top logic + rootElement.scrollTo({ + top: 0, + behavior: "smooth" + }); +} +scrollToTopBtn.addEventListener("click", scrollToTop); + + diff --git a/copri4/main/src/Mod/APIfunc.pm b/copri4/main/src/Mod/APIfunc.pm index 5dfd8dc..657759b 100755 --- a/copri4/main/src/Mod/APIfunc.pm +++ b/copri4/main/src/Mod/APIfunc.pm @@ -17,6 +17,7 @@ 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::Strptime; use DateTime::Format::Pg; use URI::Encode; use Config::General; @@ -50,6 +51,13 @@ sub new { my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime; my $now_date = strftime "%Y-%m-%d", localtime; +my $strp = DateTime::Format::Strptime->new( + pattern => '%Y-%m-%dT%H:%M:%S', + locale => 'de_DE', + time_zone => 'Europe/Berlin', + on_error => 'croak', +); + my $lang="de"; my $owner=188;#via API my $dbh = ""; @@ -60,7 +68,7 @@ sub fetch_merchant { my $q = shift; my $varenv = shift; my $req_coo = shift || ""; - my $req_merchant_id = shift || ""; + my $req_merchant_id = shift || "$dbt->{appsframe}->{'sharee.bike'}->{merchant_id}";#defaults to sharee.bike my $return = { aowner => "", @@ -885,7 +893,7 @@ sub service_work { }#end service_work -#bike reservation +#bike adhock booking sub booking_request(){ my $self = shift; my $q = shift; @@ -900,9 +908,18 @@ sub booking_request(){ my $state = $q->escapeHTML($q->param('state')) || ""; my $lock_state = $q->escapeHTML($q->param('lock_state')) || ""; + my $now_dt = DateTime->now( time_zone => "Europe/Berlin" ); + my $reserv_starttime = $q->escapeHTML($q->param('reserv_starttime')) || $now_dt; + my $reserv_endtime = $q->escapeHTML($q->param('reserv_endtime')) || $now_dt; + my $calreserv = $q->escapeHTML($q->param('calreserv')) || 0; + + my $request_para = { + start_time => $reserv_starttime, + end_time => $reserv_endtime, + }; + my $dbh = ""; my $pos_id=""; - my $now_dt = strftime "%Y-%m-%d %H:%M", localtime; my $response_state = "OK"; my $response_text = ""; @@ -1001,21 +1018,61 @@ sub booking_request(){ #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,""); + my $booking_state = 2; + $booking_state = 7 if($calreserv); + my $timestamp = DateTime->now( time_zone => "Europe/Berlin" ); + my $now_time = $strp->parse_datetime($timestamp); + + my $dtstart = $strp->parse_datetime($reserv_starttime); + my $dtend = $strp->parse_datetime($reserv_endtime); + + my $start_loc = $dtstart->strftime("%d.%m.%Y %H:%M"); + my $end_loc = $dtend->strftime("%d.%m.%Y %H:%M"); + + if($dtend >= $now_time){ + my $until_time = $now_time->add( weeks => 4 ); + #max allowed future rental + if($dtend > $until_time){ + $response_state = "Failure 4261, 4 weeks reserv timerange"; + $response_text = "Abbruch, Reservierungen sind maximal 4 Wochen im voraus erlaubt"; + }else{ + $pos_id = $dbt->insert_pos($dbh,$ctt->{c_id},$ct_bike,$ct_station,$auth,$ct_tariff,$request_para,$bike,$booking_state,$owner,$sig_book); + $bw->log("booking_request insert_pos:",$pos_id,""); + } + }else{ + $response_state = "Failure 4260, reserv timerange"; + $response_text = "Abbruch, die Mietzeit liegt in der Vergangenheit"; + } 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}, + mtime => "now()", + owner => $owner, }; $dbt->update_one($dbh,$update_ctt,"start_time='$now_dt'"); + # state=7 meens reserved, prevents auto available after 15min + if($calreserv){ + $response_state = "OK, bike " . $bike . " succesfully reserved"; + $response_text = "Erfolgreiche Buchung: $start_loc - $end_loc."; + } + #update waren bike state only if adhock booking + elsif(!$calreserv){ + my $update_ct = { + table => "content", + c_id => $ct_bike->{c_id}, + mtime => "now()", + owner => $owner, + }; + $response_state = "OK, bike " . $bike . " succesfully adhock requested"; + $response_text = "Rad $bike wurde erfolgreich für 15 Min. adhock reserviert"; + } + + #BVB once auto-coupon until 2023-08-31 #disabled if(1==2 && $varenv->{dbname} eq "sharee_bvb"){ @@ -1048,7 +1105,7 @@ sub booking_request(){ } }#end BVB auto-coupon - }else{ + }elsif($response_state !~ /Failure/){ $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"; } @@ -1089,7 +1146,7 @@ sub booking_request(){ } #booking_cancel changed to booking_update -sub booking_update(){ +sub booking_update { my $self = shift; my $q = shift; my $varenv = shift; @@ -1097,13 +1154,15 @@ sub booking_update(){ my $owner = shift || 0; my $sig_book = shift || {}; my $dbh = ""; + my $rows = 0; + my $user_agent = $q->user_agent(); 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 $pos_id = $q->escapeHTML($q->param('pos_id')) || 0; + my $reserv_starttime = $q->escapeHTML($q->param('reserv_starttime')) || ""; + my $reserv_endtime = $q->escapeHTML($q->param('reserv_endtime')) || ""; + my $bike = $q->escapeHTML($q->param('bike')) || ""; my $bike_id = $bike; $bike_id =~ s/S[1-9]X/SX/; @@ -1137,9 +1196,26 @@ sub booking_update(){ fetch => "one", barcode => $bike_id, ca_id => $auth->{c_id}, - int10 => "IN::('3','2')", + int10 => "IN::('2','3')", }; + if($pos_id){ + $booking_pos->{c_id} = $pos_id; + $booking_pos->{int10} = 7; + }elsif($reserv_starttime && $reserv_endtime){ + $booking_pos->{start_time} = $reserv_starttime; + $booking_pos->{end_time} = $reserv_endtime; + $booking_pos->{int10} = 7; + } $record_pos = $dbt->fetch_tablerecord($dbh,$booking_pos) if($bike_id > 0 && $auth->{c_id} > 0); + #trying to get reserved in timerange + if($state eq "occupied" && !$record_pos->{c_id}){ + $booking_pos->{int10} = 7; + $booking_pos->{start_time} = "<=::now()"; + $booking_pos->{end_time} = ">=::now()"; + $record_pos = $dbt->fetch_tablerecord($dbh,$booking_pos) if($bike_id > 0 && $auth->{c_id} > 0); + } + $booking_values->{pos_id} = $record_pos->{c_id} || ""; + 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."; @@ -1238,27 +1314,49 @@ sub booking_update(){ $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){ + #if($state eq canceled && $record_pos.lock_state eq locked && $record_pos.state eq requested) + if($state_key == 6 && $record_pos->{int20} == 1 && $record_pos->{int10} == 2){ $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."; + $booking_values->{response_text} = "Keine adhock Reservierung zu Rad " . $q->param('bike') . " gefunden."; } - }else{ + } + #canceled reserved + elsif($state_key == 6 && $record_pos->{int20} == 1 && $record_pos->{int10} == 7){ + my $timestamp = DateTime->now( time_zone => "Europe/Berlin" ); + my $now_time = $strp->parse_datetime($timestamp); + my $reserv_starttime = DateTime::Format::Pg->parse_datetime($record_pos->{start_time}); + + #TODO define minmax hours before cancel reservation + if($now_time < $reserv_starttime){ + $rows = $dbt->delete_content($dbh,"contenttranspos",$record_pos->{c_id}); + if($rows > 0){ + $booking_values->{response_state} = "OK: canceled reserved bike " . $q->param('bike'); + $booking_values->{response_text} = "Gebuchtes Rad " . $q->param('bike') . " wurde erfolgreich storniert"; + $booking_values->{state} = "available"; + }else{ + $booking_values->{response_state} = "Failure 2082: cancel reserved bike " . $q->param('bike') . " fails, bike not reserved"; + $booking_values->{response_text} = "Keine Buchung zu Rad " . $q->param('bike') . " gefunden."; + } + }else{ + $booking_values->{response_state} = "Failure 2092: cancel reserved bike " . $q->param('bike') . " fails, too late"; + $booking_values->{response_text} = "Reservierung " . $q->param('bike') . " kann max. 1 Stunde vor Buchungsstart storniert werden."; + } + } + 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")){ + if(($state_key == 3 && ($record_pos->{int10} == 2 || $record_pos->{int10} == 7)) || ($state_key == 3 && $record_pos->{int10} == 3 && $q->param('genkey') eq "1")){ $update_pos->{start_time} = "now()"; - $update_pos->{end_time} = "now()"; + #$update_pos->{end_time} = "now()";#don't set anymore because of revserv time $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 @@ -1292,12 +1390,16 @@ sub booking_update(){ #client GPS must have. sigo ist done without client gps - if(($gps_data->{gps} && $gps_data->{gps_age_minutes} <= 3) || ($record_pos->{int11} == 3)){ + #if(($gps_data->{gps} && $gps_data->{gps_age_minutes} <= 3) || ($record_pos->{int11} == 3)){ + #2024-03-15 app secures gps_age, we don't need it + if($gps_data->{gps} || $record_pos->{int11} == 3){ #geofencing for Ilockit my $geo_distance_next = 100000; my $station_next = 0; my $geo_debug=""; my $rows_end = 0; + + #TODO stations_available on A-A out-of-geofence have to be checked 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)){ @@ -1415,8 +1517,8 @@ sub booking_update(){ $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."; + $booking_values->{response_state} = "Failure 2016: available bike " . $q->param('bike') . " have to be at first requested, thats because cannot be $state"; + $booking_values->{response_text} = "Rad " . $q->param('bike') . " wurde nicht requested 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."; @@ -1600,15 +1702,15 @@ sub smartlock { $lock_value = 1; $update_cc->{int20} = "$lock_value"; $update_pos->{int20} = "$lock_value"; - $update_pos->{end_time} = "now()"; + #$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. "; + $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; @@ -1810,9 +1912,43 @@ sub rental_to_feedback{ }#end rental_to_feedback +#blocked bikes, reserved from now until +4 weeks +sub bikes_reserved { + my $self = shift; + my $q = shift; + my $dbh = shift; + + my $timestamp = DateTime->now( time_zone => "Europe/Berlin" ); + my $start_time = $timestamp->strftime("%Y-%m-%d %H:%M"); + my $now_time = $strp->parse_datetime($timestamp); + my $until_time = $now_time->add( weeks => 4 ); + my $end_time = $until_time->strftime("%Y-%m-%d %H:%M"); + + if($q->param('request') eq "booking_request" && $q->param('reserv_starttime') && $q->param('reserv_endtime')){ + $start_time = $q->escapeHTML($q->param('reserv_starttime')); + $end_time = $q->escapeHTML($q->param('reserv_endtime')); + } + + my $pref = { + table_pos => "contenttranspos", + fetch => "all", + keyfield => "c_id", + int10 => "IN::('2','3','7')", + template_id => 205, + start_date_time => $start_time, + end_date_time => $end_time, + }; + + my $record = {}; + $record = $dbt->collect_transpos($dbh,$pref); + + return $record; +} + #user bikes occupied sub user_bikes_occupied { my $self = shift; + my $q = shift; my $dbh = shift; my $auth = shift; my $show_dialog = shift || ""; @@ -1825,9 +1961,20 @@ sub user_bikes_occupied { template_id => "218",#Faktura tpl_id keyfield => "c_id", ca_id => "$auth->{c_id}", - int10 => "IN::('3','2')", + int10 => "IN::('2','3')", "ct.close_time" => "is::null", }; + + if($q->param('calreserv')){ + $pref->{int10} = "IN::('2','3','7')"; + $pref->{end_time} = ">=::now()"; + } + + if($q->param('request') eq "booking_request"){ + $pref->{int10} = "IN::('2','3','7')"; + $pref->{start_time} = ">=::now()"; + } + $pref->{int06} = $station if($station);#pos start-station my $record = {}; @@ -1887,7 +2034,7 @@ sub rentals(){ #bikes_available -sub bikes_available(){ +sub bikes_available { my $self = shift; my $q = shift; my $varenv_prim = shift; @@ -1899,6 +2046,9 @@ sub bikes_available(){ my $station = $q->escapeHTML($q->param('station')) || ""; my $station_id = ""; $station_id = $1 if($station =~ /(\d+)$/); + my $station_gps = ""; + $station_gps = $q->escapeHTML($q->param('Lat')) || ""; + $station_gps .= ", " . $q->escapeHTML($q->param('Lng')) || "";#TOD check space after , #to get A-A key for text my $pref_st = { @@ -1910,6 +2060,7 @@ sub bikes_available(){ }; my $record_st = {}; $pref_st->{int04} = "$station_id" if($station_id); + $pref_st->{txt06} = "$station_gps" if($station_gps); $record_st = $dbt->fetch_record($dbh,$pref_st); my $bike = $q->escapeHTML($q->param('bike')) || ""; @@ -1926,6 +2077,8 @@ sub bikes_available(){ template_id => "205", int10 => "1",#1 = "available" }; + $pref->{int10} = "IN::('1','2','3')" if($q->param('calreserv'));#take all on calreserv + my $tariff_content = {}; my $adrtarif_hash = {}; $authed = 1 if(ref($auth) eq "HASH" && $auth->{c_id} > 0); @@ -1948,8 +2101,7 @@ sub bikes_available(){ 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); + my $td_template = $dbt->rental_description_template($varenv_prim); #return list of occupied/requested bikes my $adjust_freedtime = 0; @@ -1959,7 +2111,17 @@ sub bikes_available(){ $further_freedtime_available = $pri->count_freedrental("rentals by bikes_available",$varenv,$auth->{c_id},$cttpos->{$id},$adjust_freedtime); } + my $bikes_blocked = {}; + $bikes_blocked = $self->bikes_reserved($q,$dbh) if($R::calreserv); + foreach my $id (sort { $record->{$a}->{barcode} <=> $record->{$b}->{barcode} } keys (%$record)){ + #return all reserved bikes + foreach my $rid (sort { $bikes_blocked->{$a}->{barcode} <=> $bikes_blocked->{$b}->{barcode} } keys (%$bikes_blocked)){ + if($record->{$id}->{barcode} == $bikes_blocked->{$rid}->{barcode}){ + $return->{$id}->{blocked}->{$rid}->{start_time} = $bikes_blocked->{$rid}->{start_time}; + $return->{$id}->{blocked}->{$rid}->{end_time} = $bikes_blocked->{$rid}->{end_time}; + } + } $return->{$id}->{authed} = "$authed"; $return->{$id}->{station} = "$dbt->{operator}->{$varenv->{dbname}}->{oprefix}$record->{$id}->{int04}"; $return->{$id}->{aa_ride} = "0"; @@ -2113,10 +2275,7 @@ sub bikes_all(){ 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)"; + #$pref->{int10} = "!=::3";#restriction disabled } my $record = {}; @@ -2201,10 +2360,11 @@ sub bikes_all(){ #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/){ + #2024-04-08 activated + #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"; @@ -2368,12 +2528,14 @@ sub stations_available(){ 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 = { + if($record_bikes->{$b_id}->{fleed_phone} && $record_bikes->{$b_id}->{fleed_email}){ + $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}", - }; + }; + } } } @@ -2436,6 +2598,8 @@ sub stations_available(){ operator_email => $hotline_data->{txt08}, }; } + #$return->{$id}->{operator_data}->{operator_name} = Encode::encode('utf-8', Encode::decode('iso-8859-1',$return->{$id}->{operator_data}->{operator_name})) if($return->{$id}->{operator_data}->{operator_name}); + #$return->{$id}->{operator_data}->{operator_hours} = Encode::encode('utf-8', Encode::decode('iso-8859-1',$return->{$id}->{operator_data}->{operator_hours})) if($return->{$id}->{operator_data}->{operator_hours}); #not desired 2024-02-15 if(1==2){ @@ -3183,7 +3347,7 @@ sub auth_verify(){ 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 $dbh_operator = $dbt->dbconnect_extern("$last_used_operator",""); my $hotline_hash = { table => "contentuser", fetch => "one", @@ -3198,8 +3362,10 @@ sub auth_verify(){ "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_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_name} = $hotline_data->{txt01} if($hotline_data->{txt01}); + $return->{last_used_operator}->{operator_hours} = $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}); } diff --git a/copri4/main/src/Mod/APIjsonclient.pm b/copri4/main/src/Mod/APIjsonclient.pm index e5ac995..2b31dbd 100755 --- a/copri4/main/src/Mod/APIjsonclient.pm +++ b/copri4/main/src/Mod/APIjsonclient.pm @@ -84,7 +84,10 @@ sub loop_sharees { $bw->log("shareetool select_users $return_merchant->{aowner} on $op_name->{database}->{dbname} $authraw->{c_id} $authraw->{txt17}",$users_serviceapp->{u_id},""); } #every sharee client must have a merchant_id which associate a project - if($op_name->{operatorApp} && ($users_serviceapp->{u_id} || $return_merchant->{merchant_id} eq $globalconf{website}->{'shareeweb-sharee'}->{merchant_id} || ($return_merchant->{project_id} eq $op_name->{project}))){ + #shareeweb gets all ($return_merchant->{merchant_id} eq $globalconf{website}->{'shareeweb-sharee'}->{merchant_id) + #sharee.bike gets also Bayern + #print $bw->log("Operator getter if($op_name->{operatorApp} && ($users_serviceapp->{u_id} || $return_merchant->{merchant_id} eq $globalconf{website}->{'shareeweb-sharee'}->{merchant_id} || ($return_merchant->{project_id} eq $op_name->{project}))){","",""); + if($op_name->{operatorApp} && ($users_serviceapp->{u_id} || $return_merchant->{merchant_id} eq $globalconf{website}->{'shareeweb-sharee'}->{merchant_id} || ($return_merchant->{project_id} eq $op_name->{project}) || ($return_merchant->{project_id} eq "Freiburg" && $op_name->{project} eq "Bayern"))){ $o++; #stations_available with optional caching if($rest_hash->{request} eq "stations_available"){ @@ -252,9 +255,10 @@ sub fetch_operator_json { my $self = shift; my $operator_server = shift || ""; my $rest = shift || ""; - my $operator_request = "$operator_server?$rest"; + my $operator_request = "$operator_server"; + $operator_request = "$operator_server?$rest" if($rest); - #$bw->log("fetch_operator_json >> $operator_request","$operator_request",""); + $bw->log("fetch_operator_json >> $operator_server","$operator_request",""); my $req = HTTP::Request->new(GET => "$operator_request"); $req->content_type('application/x-www-form-urlencoded'); $req->content($rest); diff --git a/copri4/main/src/Mod/APIjsonserver.pm b/copri4/main/src/Mod/APIjsonserver.pm index 63c84f5..6ccb982 100755 --- a/copri4/main/src/Mod/APIjsonserver.pm +++ b/copri4/main/src/Mod/APIjsonserver.pm @@ -71,7 +71,7 @@ my $response = { apiserver => "$apiserver", response => "$respreq", uri_primary => "$dbt->{primary}->{sharee_primary}->{primaryApp}", - copri_version => "4.1.23.29", + copri_version => "4.1.23.30", user_id => "", authcookie => "", new_authcoo => "0", @@ -243,18 +243,31 @@ elsif($q->param('request') eq "booking_request"){ $bike_id = $1 if($bike_id =~ /(\d+)/); #check count of occcupied/requested bikes - my $record = $apif->user_bikes_occupied($dbh,$authraw,""); + my $record = {}; my $max_rental_count = 3; $max_rental_count = 10 if($authraw->{int09}); my $rental_count=0; my $still_requested = 0; - foreach my $id (keys(%$record)){ + if($R::calreserv){ + $record = $apif->bikes_reserved($q,$dbh); + foreach my $id (keys(%$record)){ + if($bike_id && $bike_id == $record->{$id}->{barcode}){ + $still_requested = 1; + $response->{response_state} = "OK, bike " . $bike . " already in timerange reserved"; + $response->{response_text} = "Rad " . $bike . " ist für diesen Zeitraum nicht verfügbar."; + } + } + + }else{ + $record = $apif->user_bikes_occupied($q,$dbh,$authraw,""); + foreach my $id (keys(%$record)){ $rental_count++; if($bike_id && $bike_id == $record->{$id}->{barcode}){ $still_requested = 1; $response->{response_state} = "OK, bike " . $bike . " already requested or occupied"; - $response->{response_text} = "Fahrrad Nr. " . $bike . " ist bereits reserviert"; + $response->{response_text} = "Rad " . $bike . " ist bereits reserviert"; } + } } if(!$still_requested){ @@ -293,7 +306,7 @@ elsif($q->param('request') eq "booking_request"){ rentalId => "", }; - if(!$ct_bike->{barcode} || !$ct_bike->{int10} || $ct_bike->{int10} != 1){ + if(!$ct_bike->{barcode} || !$ct_bike->{int10}){ $response->{response_state} = "Failure 2001: booking bike $bike fails, bike not available"; $response->{response_text} = "Mietrad $bike ist nicht verfügbar. Ist das Mietrad für sie freigeschaltet? Bitte überprüfen Sie Ihre Profildaten auf Vollständigkeit"; }elsif(!$ct_tariff->{barcode}){#ist will not happen, because of prios tariff select in fetch_bike_tariff @@ -318,7 +331,7 @@ elsif($q->param('request') eq "booking_request"){ table => "contenttranspos", fetch => "one", barcode => "$bike_id", - int10 => "2", + int10 => "IN::('2','7')", ca_id => "$authraw->{c_id}", }; my $dbh = ""; @@ -342,7 +355,7 @@ elsif($q->param('request') eq "booking_request"){ } #return list of occupied/requested bikes - $record = $apif->user_bikes_occupied($dbh,$authraw,""); + $record = $apif->user_bikes_occupied($q,$dbh,$authraw,""); $response->{bikes_occupied} = $apif->rentals(\%varenv,$record,$authraw,"1");#returns JSON rental values }#end still_requested @@ -379,7 +392,7 @@ elsif($q->param('request') eq "booking_cancel" || $q->param('request') eq "booki $bike_id =~ s/S[1-9]X/SX/; $bike_id = $1 if($bike_id =~ /(\d+)/); - my $ctpos = {}; + my $ctpos = {};#can be removed after sig my $booking_pos = { table => "contenttranspos", fetch => "one", @@ -426,7 +439,7 @@ elsif($q->param('request') eq "booking_cancel" || $q->param('request') eq "booki ($rows, $booking_values) = $apif->booking_update($q,\%varenv,$authraw,$aowner,$sig_book); $response = {%$response, %$booking_values}; - my $record = $apif->user_bikes_occupied($dbh,$authraw,"show_dialog"); + my $record = $apif->user_bikes_occupied($q,$dbh,$authraw,"show_dialog"); $response->{bikes_occupied} = $apif->rentals(\%varenv,$record,$authraw,"1"); #update on Ilockit @@ -435,12 +448,12 @@ elsif($q->param('request') eq "booking_cancel" || $q->param('request') eq "booki $apif->stations_caching($q,\%varenv,$authraw); $response = {%$response, %$booking_values}; - my $record = $apif->user_bikes_occupied($dbh,$authraw,""); + my $record = $apif->user_bikes_occupied($q,$dbh,$authraw,""); $response->{bikes_occupied} = $apif->rentals(\%varenv,$record,$authraw,"1"); } }#end occupied|available else{ - my $record = $apif->user_bikes_occupied($dbh,$authraw,""); + my $record = $apif->user_bikes_occupied($q,$dbh,$authraw,""); $response->{bikes_occupied} = $apif->rentals(\%varenv,$record,$authraw,"1"); } @@ -478,7 +491,7 @@ elsif($q->param('request') eq "user_bikes_occupied"){ ($auth,$authraw) = $apif->auth_verify($q); if(ref($auth) eq "HASH" && $auth->{authcookie}){ $response = { %$response, %$auth }; - my $record = $apif->user_bikes_occupied($dbh,$authraw,"show_dialog"); + my $record = $apif->user_bikes_occupied($q,$dbh,$authraw,"show_dialog"); if($R::withoutkey){ $response->{bikes_occupied} = $apif->rentals(\%varenv,$record,$authraw,""); }else{ @@ -531,9 +544,12 @@ elsif($q->param('request') eq "bikes_available"){ my $station_id = ""; $station_id = $1 if($station =~ /(\d+)$/); - $record = $apif->user_bikes_occupied($dbh,$authraw,"",$station_id); + $record = $apif->user_bikes_occupied($q,$dbh,$authraw,"",$station_id); $response->{bikes_occupied} = $apif->rentals(\%varenv,$record,$authraw,"1");#returns JSON rental values } + + #$response->{bikes_blocked} = $apif->bikes_reserved($q,$dbh) if($R::calreserv); + } if(ref($response->{bikes}) ne "HASH"){ $response->{response_state} = "Failure 5003: cannot find any user defined bike tariff"; @@ -742,13 +758,15 @@ elsif($q->param('request') eq "stations_available"){ } #App merchant message + #if($user_agent =~ /konrad/i && $dbt->{copri_conf}->{betau_id}->{$authraw->{c_id}} && $varenv{cms}->{'App-merchant-message'}->{txt}){ if($user_agent =~ /konrad/i && $varenv{cms}->{'App-merchant-message'}->{txt}){ #if($epoch_now >= $epoch_start && $epoch_now <= $epoch_end){ $response->{merchant_message} = $varenv{cms}->{'App-merchant-message'}->{txt}; #} } #App merchant message bayern - if($user_agent =~ /bayern/i && $varenv{cms}->{'App-merchant-message-bayern'}->{txt}){ + #if($user_agent =~ /bayern/i && $varenv{cms}->{'App-merchant-message-bayern'}->{txt}){ + if($user_agent =~ /bayern/i && $user_agent_subversion <= 380 && $varenv{cms}->{'App-merchant-message-bayern'}->{txt}){ #if($epoch_now >= $epoch_start && $epoch_now <= $epoch_end){ $response->{merchant_message} = $varenv{cms}->{'App-merchant-message-bayern'}->{txt}; #} diff --git a/copri4/main/src/Mod/DBtank.pm b/copri4/main/src/Mod/DBtank.pm index 84d13d7..1609106 100755 --- a/copri4/main/src/Mod/DBtank.pm +++ b/copri4/main/src/Mod/DBtank.pm @@ -876,6 +876,8 @@ sub fetch_tablerecord(){ $where .= " and $key $op $value"; }elsif($op eq "IN"){ $where .= " and $key $op $value"; + }elsif($op eq "NOT IN"){ + $where .= " and $key $op $value"; }else{ $where .= " and $key $op '$value'"; } @@ -894,12 +896,10 @@ sub fetch_tablerecord(){ }elsif($key =~ /^(c_id|u_id|cc_id|ct_id|ca_id|barcode|int\d+|owner|template_id)$/ && (looks_like_number($value) || $value eq "null")){ if($value eq "null"){ $where .= " and ($key is null OR $key = 0)"; - }elsif($value eq "nullOR1"){ - $where .= " and ($key is null OR $key = 1)"; }else{ $where .= " and $key $op $value"; } - }elsif($key =~ /int\d+/ && $op eq "IN"){ + }elsif($key =~ /int\d+|template_id/ && $op eq "IN"){ $where .= " and $key $op $value"; } } @@ -917,7 +917,7 @@ sub fetch_tablerecord(){ my $rc = $sth->execute(); #debug $fetch->{table} eq "contenttranspos" on Failure 758 - #$bw->log("DBtank fetch_tablerecord source-dbname $source:",$sql,"") if($debug && $fetch->{table} eq "contenttranspos"); + $bw->log("DBtank fetch_tablerecord source-dbname $source:",$sql,"") if($debug && $fetch->{table} eq "contenttranspos"); my $record = { c_id => 0 }; if($fetch->{fetch} eq "all" && $fetch->{keyfield}){ @@ -1239,8 +1239,10 @@ sub collect_transpos { $search->{offset} = 0 if(!$search->{offset}); - my $where = "where cp.ct_id=ct.c_id"; + my $where = "where 1=1"; + $where .= " and cp.ct_id=ct.c_id" if($search->{table}); $where .= " and cp.int05 is null";#do not select sub workflow docs like storno + foreach my $key (keys (%$search)){ $search->{$key} =~ s/^\s//g; $search->{$key} =~ s/\s$//g; @@ -1256,6 +1258,7 @@ sub collect_transpos { $where .= " and cp.$key = $search->{$key}" if($key eq "int20" && looks_like_number($search->{$key})); $where .= " and cp.$key = $search->{$key}" if($key eq "barcode" && looks_like_number($search->{$key})); $where .= " and cp.$key = $search->{$key}" if($key eq "int12" && looks_like_number($search->{$key})); + $where .= " and cp.$key = $search->{$key}" if($key eq "template_id" && looks_like_number($search->{$key})); $where .= " and (cp.$key = $search->{$key} OR cp.owner_end = $search->{$key})" if($key eq "owner" && looks_like_number($search->{$key})); $where .= " and (cp.$key is $search->{$key} OR cp.$key = 0)" if($key eq "int34" && $search->{$key} eq "null"); $where .= " and cp.$key ilike '%$search->{$key}%'" if($key eq "txt23" && $search->{$key}); @@ -1267,24 +1270,31 @@ sub collect_transpos { #adding itime to get also not rental dependent entries if($search->{start_date_time} && $search->{end_date_time}){ - $where .= " and ((cp.end_time >= '$search->{start_date_time}' and cp.end_time <= '$search->{end_date_time}' and cp.start_time <= '$search->{end_date_time}') OR (cp.itime >= '$search->{start_date_time}' and cp.itime <= '$search->{end_date_time}'))"; + my $or_itime = ""; + #because of bikes_reserved, don't search others when bike is requested + if(!$search->{template_id} || $search->{template_id} != 205){ + $or_itime = "OR (cp.itime >= '$search->{start_date_time}' and cp.itime <= '$search->{end_date_time}')"; + } + $where .= " and ((cp.end_time >= '$search->{start_date_time}' and cp.end_time <= '$search->{end_date_time}' and cp.start_time <= '$search->{end_date_time}') $or_itime)"; + }elsif($search->{start_time_interval}){ $where .= " and cp.start_time <= $search->{start_time_interval}"; } $where .= " ORDER BY cp.c_id DESC LIMIT $search->{limit} OFFSET $search->{offset}" if($search->{limit}); - my $sql = "SELECT cp.* from $search->{table} cp, contenttrans ct $where"; - #2024-02-22 not used anymore - #for system messaging - #if($messaging){ - # $sql = "SELECT cp.*,ct.txt07 AS phone,ct.txt08 AS email,ct.txt11 AS lang from $search->{table} cp, contenttrans ct $where"; - #} + my $sql = ""; + if($search->{table}){ + $sql = "SELECT cp.* from $search->{table_pos} cp, $search->{table} ct $where"; + }else{ + $sql = "SELECT cp.* from $search->{table_pos} cp $where"; + } + my $sth = $dbh->prepare($sql); my $rc = $sth->execute(); my $ct = $sth->fetchall_hashref("c_id"); - #$bw->log("collect_transpos",$sql,"") if($debug); + $bw->log("collect_transpos",$sql,"") if($debug); return $ct; -} +}#end collect_transpos #collect contenttheftpos sub collect_theftpos { @@ -1534,13 +1544,14 @@ sub insert_pos(){ my $self = shift; my $dbh = shift || $dbh_intern; my $ctt_id = shift; - my $ct = shift || {}; + my $ct = shift || {};#bike or part content my $ct_station = shift || {}; my $ctadr = shift || {}; - my $ct_tariff = shift || ""; - my $endRental = shift || "0000-00-00"; + my $ct_tariff = shift || {}; + #my $endRental = shift || "0000-00-00"; + my $request_para = shift || {}; my $ct_name = shift || ""; - my $status = shift || ""; + my $booking_state = shift || ""; my $owner = shift || ""; my $sig_book = shift || {}; @@ -1601,7 +1612,7 @@ sub insert_pos(){ my $sth; #Verleihräder if($ct->{template_id} && $ct->{template_id} == 205){#Leihrad_list - $sth = $dbh->prepare("INSERT INTO contenttranspos (ct_id,cc_id,ca_id,ct_name,barcode,txt01,txt08,txt02,txt09,txt12,itime,start_time,end_time,int01,int02,int03,int06,txt05,txt06,txt07,int10,int12,template_id,int13,owner,int07,txt04,int09,int17,int15,int11,int18,int19,txt17,txt18,int20,int25,int29,int34,txt22,txt11,int35,int36,int37,int42,time01,time02) VALUES ('$ctt_id','$ct->{c_id}','$ctadr->{c_id}','$ct_name','$ct->{barcode}','$ct->{txt01}','$user_name','$ct->{txt02}','$ctadr->{txt09}','$prefix',now(),now(),'$endRental','1','$unit_price','$menge','$start_station','$ct->{txt06}','$ct->{txt06}','$ct->{txt07}','$status','$from_main_id','$from_template_id','$deviceId','$owner','$rabatt','$tariff_desc','$tariff_nr','$daymax_price','$abo_price','$ct->{int11}','$sharing_type','$bike_charge','$ct->{txt17}','$ct->{txt18}','1','$trackon','$bike_type_id','$staff','$sig_book->{bikeId}','$sig_book->{rentalId}','$unit_price1','$unit_price2','$start_price','$aa_station','$unit_time','$free_time') RETURNING c_id"); + $sth = $dbh->prepare("INSERT INTO contenttranspos (ct_id,cc_id,ca_id,ct_name,barcode,txt01,txt08,txt02,txt09,txt12,itime,start_time,end_time,int01,int02,int03,int06,txt05,txt06,txt07,int10,int12,template_id,int13,owner,int07,txt04,int09,int17,int15,int11,int18,int19,txt17,txt18,int20,int25,int29,int34,txt22,txt11,int35,int36,int37,int42,time01,time02) VALUES ('$ctt_id','$ct->{c_id}','$ctadr->{c_id}','$ct_name','$ct->{barcode}','$ct->{txt01}','$user_name','$ct->{txt02}','$ctadr->{txt09}','$prefix',now(),'$request_para->{start_time}','$request_para->{end_time}','1','$unit_price','$menge','$start_station','$ct->{txt06}','$ct->{txt06}','$ct->{txt07}','$booking_state','$from_main_id','$from_template_id','$deviceId','$owner','$rabatt','$tariff_desc','$tariff_nr','$daymax_price','$abo_price','$ct->{int11}','$sharing_type','$bike_charge','$ct->{txt17}','$ct->{txt18}','1','$trackon','$bike_type_id','$staff','$sig_book->{bikeId}','$sig_book->{rentalId}','$unit_price1','$unit_price2','$start_price','$aa_station','$unit_time','$free_time') RETURNING c_id"); }else{ $sth = $dbh->prepare("INSERT INTO contenttranspos (ct_id,cc_id,ca_id,ct_name,barcode,txt08,itime,int01,int02,int03,txt01,int10,int12,int16,template_id,owner) VALUES ('$ctt_id','$ct->{c_id}','$ctadr->{c_id}','$ct_name','$ct->{barcode}','$user_name',now(),'1','$unit_price','1','$ct->{txt01}','0','$from_main_id','$fibumark','$from_template_id','$owner') RETURNING c_id"); } @@ -1610,15 +1621,6 @@ sub insert_pos(){ $sth->bind_columns(\$last_id); my $c_id = $sth->fetchrow_array(); - if($c_id && $status){ - #update Leihräder in Stammdaten - my $set2 = "owner=$owner" if($owner); - $set2 .= ",int10='$status'" if($status); - $set2 .= ",mtime='now()'"; - my $sth2 = $dbh->prepare("UPDATE content SET $set2 where c_id='$ct->{c_id}'"); - my $rows2 = $sth2->execute(); - } - return $c_id; } diff --git a/copri4/main/src/Mod/GBFSout.pm b/copri4/main/src/Mod/GBFSout.pm index 92bdb2d..8352d13 100755 --- a/copri4/main/src/Mod/GBFSout.pm +++ b/copri4/main/src/Mod/GBFSout.pm @@ -39,6 +39,7 @@ sub handler { my %varenv = $cf->envonline(); my $coo = $q->cookie('domcookie') || $R::sessionid || ""; + my $station_select = $R::station || ""; my $users_sharee = { c_id => 0 }; my $api_return = { authcookie => '' }; @@ -63,14 +64,14 @@ sub handler { #request primary will jsonclient loop_sharees my $uri_request = $dbt->{primary}->{sharee_primary}->{primaryApp}; - #detect DMS, because this will do it directly without loop_sharees - $uri_request = $dbt->{operator}->{$varenv{dbname}}->{operatorApp} if($varenv{dbname} ne $dbt->{primary}->{sharee_primary}->{database}->{dbname} && $varenv{syshost} =~ /shareedms-/); + #detect operator, because this will do it directly without loop_sharees + $uri_request = $dbt->{operator}->{$varenv{dbname}}->{operatorApp} if($varenv{dbname} ne $dbt->{primary}->{sharee_primary}->{database}->{dbname}); if($R::request eq "stations_available"){ station_information($api_return,\%varenv,$users_sharee,$uri_request,$project); } if($R::request eq "bikes_available"){ - vehicle_status($api_return,\%varenv,$users_sharee,$uri_request,$project); + vehicle_status($api_return,\%varenv,$users_sharee,$uri_request,$project,$station_select); } return Apache2::Const::OK; @@ -103,6 +104,10 @@ sub station_information { $gbfs_station{$station}{bike_count} = $response_stations->{shareejson}->{stations}->{$station}->{bike_count}; $gbfs_station{$station}{lat} = $response_stations->{shareejson}->{stations}->{$station}->{gps}->{latitude}; $gbfs_station{$station}{lon} = $response_stations->{shareejson}->{stations}->{$station}->{gps}->{longitude}; + #view it only for bike reservation + if($R::calreserv){ + $gbfs_station{$station}{uri_operator} = $response_stations->{shareejson}->{stations}->{$station}->{uri_operator}; + } #$gbfs_station{$station}{is_charging_station} = 1 if(grep(/300102/, @{$response_stations->{shareejson}->{stations}->{$station}->{station_group}}));#E-L push (@gbfs_stations, $gbfs_station{$station}); } @@ -133,9 +138,11 @@ sub vehicle_status { my $users_sharee = shift || { c_id => 0 }; my $uri_request = shift || ""; my $project = shift || "all"; + my $station_select = shift || ""; my $json = JSON->new->allow_nonref; my $rest_bikes = "request=bikes_available&project=$project&authcookie=$authcookie->{authcookie}"; + $rest_bikes = "request=bikes_available&project=$project&station=$station_select&authcookie=$authcookie->{authcookie}" if($station_select); my $gbfs_resp = {}; my @gbfs_bikes = (); diff --git a/copri4/main/src/Mod/Indexsharee.pm b/copri4/main/src/Mod/Indexsharee.pm index c4cc057..9f4a2d9 100755 --- a/copri4/main/src/Mod/Indexsharee.pm +++ b/copri4/main/src/Mod/Indexsharee.pm @@ -568,12 +568,15 @@ sub handler { if($users_sharee->{c_id} && $R::sharee_edit && $R::sharee_edit =~ /save_account/){ ($returnwww,$feedb) = $shwo->save_account($dbh,$q,$users_sharee->{c_id},\%varenv,$aowner); } - if($users_sharee->{c_id} && $R::sharee_edit && $R::sharee_edit =~ /save_transact/){ + elsif($users_sharee->{c_id} && $R::sharee_edit && $R::sharee_edit =~ /save_transact/){ $returnwww = $shwo->save_transact($q,$users_sharee->{c_id},$coo,$aowner); } - if($users_sharee->{c_id} && $R::sharee_edit && $R::sharee_edit =~ /generate_payonelink/ && $R::prepaid_amount && $R::prepaid_amount =~ /\d+/){ + elsif($users_sharee->{c_id} && $R::sharee_edit && $R::sharee_edit =~ /generate_payonelink/ && $R::prepaid_amount && $R::prepaid_amount =~ /\d+/){ system("$dbt->{copri_conf}->{basedir}/$varenv{syshost}/src/scripts/payonelink.pl '$varenv{syshost}' '$users_sharee->{c_id}' '$R::prepaid_amount' '$aowner' &"); } + elsif($users_sharee->{c_id} && $R::sharee_edit && $R::sharee_edit =~ /bike_reserv/){ + $returnwww = $shwo->bike_reserv($q,\%varenv,$users_sharee->{c_id},$aowner); + } if($returnwww && $returnwww =~ /failure::(.*)/){ $returnwww =~ s/::/=/g; @@ -634,7 +637,7 @@ sub handler { $dbt->update_record($dbh,$update_adr,$users_sharee) if($users_sharee->{c_id} > 0); ($api_return,$users_sharee) = $apif->auth_verify($q,$coo,""); - #payment_ack + #payment_ack payAck system("$dbt->{copri_conf}->{basedir}/$varenv{syshost}/src/scripts/payment_ack.pl '$varenv{syshost}' 'payment_ackCC' '$users_sharee->{c_id}' '$aowner' &"); if(1==1){ @@ -726,6 +729,10 @@ sub handler { exit 0; } } + elsif(!$users_sharee->{c_id} && !$R::logedout && ($path !~ /$varenv{mandant}\/Anmelden|$varenv{mandant}\/Account/)){ + print redirect("$varenv{wwwhost}?logedout=1$session_and"); + exit 0; + } }#end web frame @@ -776,7 +783,6 @@ sub handler { }#end confirm - #Printpreview if($view =~ /Printpreview/){ require "Mod/Printpreview.pm"; @@ -803,8 +809,9 @@ sub handler { my $onload=""; my $local_style = "$varenv{metahost}/$dbt->{shareeapp_conf}->{local_style}"; - my $jquery = ""; - my $jquery_ui = ""; + #my $jquery = "$varenv{metahost}/$dbt->{copri_conf}->{jsscript}"; + my $jquery = "$varenv{metahost}/$dbt->{shareeapp_conf}->{jquery}";#used by CalReserv / rentalator.js + my $jquery_ui = "$varenv{metahost}/$dbt->{copri_conf}->{jsscript}"; my $style_jquery_ui = ""; my $js_bootstrap = "$varenv{metahost}/$dbt->{shareeapp_conf}->{js_bootstrap}"; my $style_bootstrap = "$varenv{metahost}/$dbt->{shareeapp_conf}->{style_bootstrap}"; diff --git a/copri4/main/src/Mod/MailTransport.pm b/copri4/main/src/Mod/MailTransport.pm index 839e63c..0b7e2a6 100755 --- a/copri4/main/src/Mod/MailTransport.pm +++ b/copri4/main/src/Mod/MailTransport.pm @@ -276,6 +276,8 @@ sub mail_hours_occupied { my $uadr = shift; my $contentpos = shift; my $sendref = $self->sendrefhash(); + $sendref->{mailxcfg} = "mailx_hotline"; + $sendref->{mailxcfg} = "mailx_konrad" if($varenv->{syshost} eq "shareedms-kn"); my $dbh_primary = $dbt->dbconnect_extern($dbt->{primary}->{sharee_primary}->{database}->{dbname},"iso-8859-1"); diff --git a/copri4/main/src/Mod/Payment.pm b/copri4/main/src/Mod/Payment.pm index 6960a67..1090941 100755 --- a/copri4/main/src/Mod/Payment.pm +++ b/copri4/main/src/Mod/Payment.pm @@ -927,7 +927,8 @@ sub rpc { $payoneret = $txidval; print FILE "payone CAPTURE $now_dt\n $todo: txid=$txidval && ctt.c_id=$ctt->{c_id} && ctadr.c_id=$ctadr->{c_id}\n" if($debug); - if($txidval && $ctt->{c_id} && $ctadr->{c_id} && $res->content =~ /settleaccount=/){ + #if($txidval && $ctt->{c_id} && $ctadr->{c_id} && $res->content =~ /settleaccount=/){ + if($txidval && $ctt->{c_id} && $ctadr->{c_id}){ $update_ctt->{int14} = "null"; $update_adr->{int12} = 0; }else{#because of Prelogic logic set it empty if no capture diff --git a/copri4/main/src/Mod/Prelib.pm b/copri4/main/src/Mod/Prelib.pm index 1d71ced..d062214 100755 --- a/copri4/main/src/Mod/Prelib.pm +++ b/copri4/main/src/Mod/Prelib.pm @@ -72,12 +72,11 @@ sub longterm_occupied { }; my $uadr = { c_id => 0 }; $uadr = $dbt->fetch_record($dbh,$pref_cc); - $uadr->{txt07} =~ s/\s//g; my $search = { - table => "contenttranspos", + table_pos => "contenttranspos", int10 => 3, - #int34 => "null",#if not staff TODO + int34 => "null",#if not staff start_time_interval => "(now() - interval '12 hours')", }; my $update_pos = { @@ -126,6 +125,7 @@ sub longterm_occupied { print FILE "if(!$cttpos->{$pid}->{int33} || $cttpos->{$pid}->{int33} < $h_id)\n"; print FILE "Sent message for > $h_id hour rental by $posting_sms->{$h_id}\n"; + $uadr->{txt07} =~ s/\s//g; my $contact_hotline = "Hotline $uadr->{txt01} $uadr->{txt08}, $uadr->{txt07}"; $smstrans->sms_message($h_id,$contact_hotline,$cttpos->{$pid}->{ca_id},"",$cttpos->{$pid}->{ct_name}); my $message_log = $cttpos->{$pid}->{txt20} . "\n- $log_stamp $posting_sms->{$h_id}"; @@ -963,6 +963,7 @@ sub delete_contenttranspos { table => "contenttrans", table_pos => "contenttranspos", fetch => "one", + catch => "content_contenttranspos", template_id => "219",#prepaid tpl_id c_id => $c_id, int02 => ">=::1", diff --git a/copri4/main/src/Mod/Printpreview.pm b/copri4/main/src/Mod/Printpreview.pm index 439ad36..f9c8973 100755 --- a/copri4/main/src/Mod/Printpreview.pm +++ b/copri4/main/src/Mod/Printpreview.pm @@ -276,7 +276,7 @@ td { $header_top = $header_px * ($site -1); $footer_top = $footer_px * $site + ($header_px - $footer_px -10); - $footer_top = $footer_px * $site + ($site * (0.70 * ($header_px - $footer_px))) if($site > 2); + $footer_top = $footer_px * $site + ($site * (0.75 * ($header_px - $footer_px))) if($site > 2); print PMA "2.$site) text_footer footer_top: $footer_top | $site/$site_all\n"; &text_footer(\%varenv,$ctf,$ctt,$footer_top,$site,$site_all); diff --git a/copri4/main/src/Mod/Shareework.pm b/copri4/main/src/Mod/Shareework.pm index 6ef9a71..984a158 100755 --- a/copri4/main/src/Mod/Shareework.pm +++ b/copri4/main/src/Mod/Shareework.pm @@ -52,6 +52,18 @@ my $i_rows=0; my $u_rows=0; my $d_rows=0; +#bike reservation by CalReserv +sub bike_reserv { + my $self = shift; + my $q = shift; + my $varenv = shift; + my $ca_id = shift; + my $aowner = shift; + + return; +} + + # #also done in src/Tpl/Anmelden.pm!? sub delete_account { @@ -286,10 +298,11 @@ sub save_account(){ } #Freischaltcode format can be "CA-Li-hsze789k" or "CA1234567" - if($valxx && ($valxx =~ /^(\w{2,3})-([\w\-]+)/i || $valxx =~ /^(\w{2,3})(\d+)/i)){ + if($valxx && ($valxx =~ /^(\w{2,3})-([\w\-]+)/i || $valxx =~ /^(\w{2,3})(\d+)/i || $valxx =~ /^(\w{2,3})-(\w+)/i)){ $valxx =~ s/\s//g; my $bonus_prefix = uc($1), my $bonusnr = $2; + $bonusnr = "$1-$2" if($valxx =~ /^(\w{2,3})-(\w+)/i);#TR Oberried my $operator_conf = $dbt->get_operator_conf($bonus_prefix); my @txt30_op = (); @@ -563,7 +576,7 @@ sub save_account(){ my $payone_mival = $payone->managemandate_main(\%varenv,$ctadr,"",$owner); if($payone_mival && $payone_mival =~ /\w{2}-\w+/){ - #payment_ack + #payment_ack payAck system("$dbt->{copri_conf}->{basedir}/$varenv{syshost}/src/scripts/payment_ack.pl '$varenv{syshost}' 'payment_ackSEPA' '$ctadr->{c_id}' '$owner' &"); $vde_on_fail = 0 if($vde_on_fail != 2); diff --git a/copri4/main/src/Tpl/BaseEdit.pm b/copri4/main/src/Tpl/BaseEdit.pm index a622772..6398a26 100755 --- a/copri4/main/src/Tpl/BaseEdit.pm +++ b/copri4/main/src/Tpl/BaseEdit.pm @@ -960,7 +960,7 @@ EOF table => "content", fetch => "one", template_id => "228", - ct_name => "$ctrel->{txt15}", + ct_name => "ilike::$ctrel->{txt15}", }; $bonus_record = $dbt->fetch_record($dbh,$pref_cc) if($ctrel->{txt15}); } @@ -974,11 +974,11 @@ EOF if($bonus_record->{int22} && $tf_id && $bonus_record->{int22} == $tf_id){ $postdes .= "*code aktiviert $sharing_type Tarif Nr. $bonus_record->{int22}. "; } - if((!$ctrel->{txt15} || $bonus_record->{ct_name} ne $ctrel->{txt15}) && $tf_id && $tariff_all->{$tf_id}->{int18} != 2){ + if((!$ctrel->{txt15} || $bonus_record->{ct_name} !~ /$ctrel->{txt15}/i) && $tf_id && $tariff_all->{$tf_id}->{int18} != 2){ $postdes .= $q->span({-style=>'color:red;padding-left:10px;'},"Achtung, $sharing_type Tarif $tf_id ohne *code aktiviert. "); } } - if($ctrel->{txt15} && $bonus_record->{ct_name} ne $ctrel->{txt15}){ + if($ctrel->{txt15} && $bonus_record->{ct_name} !~ /$ctrel->{txt15}/i){ $postdes .= $q->span({-style=>'color:red;padding-left:10px;'},"*code ist nicht vorhanden! "); }elsif($ctrel->{txt15} && $bonus_record->{ct_name} eq $ctrel->{txt15}){ my $sharing_type = "public-bonus"; diff --git a/copri4/main/src/Tpl/Calorin.pm b/copri4/main/src/Tpl/Calorin.pm index 245271a..e2ed674 100755 --- a/copri4/main/src/Tpl/Calorin.pm +++ b/copri4/main/src/Tpl/Calorin.pm @@ -85,6 +85,7 @@ sub tpl(){ parent_id => $dbt->{shareedms_conf}->{waren}, fetch => "all", keyfield => "main_id", + content_id => "null", }; my $part_nodes = $dbt->fetch_rel4tpl4nd($dbh,$bnode); @@ -178,7 +179,8 @@ sub tpl(){ my $cttpos = {}; $R::ct_ct_name =~ s/\#//; my $search = { - table => "$node_meta->{ct_table}", + table => "contenttrans", + table_pos => "$node_meta->{ct_table}", limit => $q->escapeHTML($limit), offset => $q->escapeHTML($offset), }; @@ -352,7 +354,7 @@ sub tpl(){ ($year_st,$mon_st,$day_st,$hh_st,$mm_st) = $lb->split_date($cttpos->{$pid}->{itime}); } if($cttpos->{$pid}->{end_time}){ - $cttpos->{$pid}->{end_time} = $now_dt if($node_meta->{ct_table} eq "contenttranspos" && $cttpos->{$pid}->{int10} == 3); + $cttpos->{$pid}->{end_time} = $now_dt if($node_meta->{ct_table} eq "contenttranspos" && $cttpos->{$pid}->{start_time} eq $cttpos->{$pid}->{end_time} ); ($year_en,$mon_en,$day_en,$hh_en,$mm_en) = $lb->split_date($cttpos->{$pid}->{end_time}); }else{ ($year_en,$mon_en,$day_en,$hh_en,$mm_en) = $lb->split_date($cttpos->{$pid}->{itime}); diff --git a/copri4/main/src/Tpl/Liste3.pm b/copri4/main/src/Tpl/Liste3.pm index 59706b7..b76ad5b 100755 --- a/copri4/main/src/Tpl/Liste3.pm +++ b/copri4/main/src/Tpl/Liste3.pm @@ -281,9 +281,10 @@ sub tpl(){ $tplids = "209,218"; } $searchref->{tplids} = "$tplids"; - }elsif($R::detail_search && $R::detail_search eq "search"){ + } + if($R::detail_search && $R::detail_search eq "search"){ $searchref->{offset} = 0; - $searchref->{limit} = 1000; + $searchref->{limit} = 1500; } my $main_ids .= $dbt->collect_noderec($dbh,$main_id); @@ -1118,7 +1119,7 @@ EOF if($cal_count <= 1){ my $scale_color = "#86cbd7;"; my $calement = "calement_86cbd7"; - if($ct4rel->{$id}->{int13} == $cttpos->{$ctid}->{int13} && $cttpos->{$ctid}->{int10} == 7){ + if($ct4rel->{$id}->{int13} == $cttpos->{$ctid}->{int13} && $cttpos->{$ctid}->{int05} == 7){ $scale_color = "#f0536e;"; $calement = "calement_f0536e"; } diff --git a/copri4/main/src/scripts/Ilockit_cloud.pl b/copri4/main/src/scripts/Ilockit_cloud.pl index 83bf9f1..0049c11 100755 --- a/copri4/main/src/scripts/Ilockit_cloud.pl +++ b/copri4/main/src/scripts/Ilockit_cloud.pl @@ -125,8 +125,8 @@ sub utctime { #'deviceTime' => '2021-10-14T08:19:35.000+0000', #'serverTime' => '2021-10-14T07:19:37.000+0000', - #$utc_epoch -= 2*60*60;# -2 std (Sommerzeit) - $utc_epoch -= 1*60*60;# -1 std (Winterzeit) + $utc_epoch -= 2*60*60;# -2 std (Sommerzeit) + #$utc_epoch -= 1*60*60;# -1 std (Winterzeit) $utc_epoch += $latency; $time = gmtime($utc_epoch);#epoch diff --git a/copri4/main/src/scripts/Ilockit_trackingcloud.pl b/copri4/main/src/scripts/Ilockit_trackingcloud.pl index 2f6ac23..5ecfa3e 100755 --- a/copri4/main/src/scripts/Ilockit_trackingcloud.pl +++ b/copri4/main/src/scripts/Ilockit_trackingcloud.pl @@ -87,8 +87,8 @@ sub utctime { my $time = Time::Piece->strptime($date, "%Y-%m-%dT%H:%M:%S"); print FILE "localtime: " . $time->datetime . "\n";#localtime my $utc_epoch = $time->epoch; - #$utc_epoch -= 2*60*60;# -2 std (Sommerzeit) - $utc_epoch -= 1*60*60;# -1 std (Winterzeit) + $utc_epoch -= 2*60*60;# -2 std (Sommerzeit) + #$utc_epoch -= 1*60*60;# -1 std (Winterzeit) $utc_epoch += $latency; $time = gmtime($utc_epoch);#epoch print FILE "utctime: " . $time->datetime . "\n";#utc zulu date time diff --git a/copri4/main/src/scripts/mailTransportcms.pl b/copri4/main/src/scripts/mailTransportcms.pl index 63136ec..2304986 100755 --- a/copri4/main/src/scripts/mailTransportcms.pl +++ b/copri4/main/src/scripts/mailTransportcms.pl @@ -431,7 +431,7 @@ sub send_occupied2hotline { $sendref->{mail_to} = $uadr->{txt08}; my $search = { - table => "contenttranspos", + table_pos => "contenttranspos", int10 => 3, #int33 => 3,#marker for sending 3. SMS int34 => "null",#not staff diff --git a/copri4/main/src/scripts/sms_message.pl b/copri4/main/src/scripts/sms_message.pl index b64a695..fcdacba 100755 --- a/copri4/main/src/scripts/sms_message.pl +++ b/copri4/main/src/scripts/sms_message.pl @@ -61,7 +61,7 @@ $contact_hotline = "Hotline $record_cc->{txt01} $record_cc->{txt08}, $record_cc- if($todo eq "24h_occupied"){ #select booking pos if state=occupied and start_time > 24h my $search = { - table => "contenttranspos", + table_pos => "contenttranspos", int10 => 3, int34 => "null",#if not staff start_time_interval => "(now() - interval '1 day')", diff --git a/copri4/shareeapp-operator/css/local_style20230105.css b/copri4/shareeapp-operator/css/local_style20240315.css similarity index 70% rename from copri4/shareeapp-operator/css/local_style20230105.css rename to copri4/shareeapp-operator/css/local_style20240315.css index 988e6c7..eb54121 100755 --- a/copri4/shareeapp-operator/css/local_style20230105.css +++ b/copri4/shareeapp-operator/css/local_style20240315.css @@ -15,6 +15,43 @@ html,body { text-align: center; } +/* Style the buttons that are used to open and close the accordion panel */ +.accordion { + text-align:left; + padding:0; + background-color: white; + border: none; + cursor: pointer; + text-decoration: none; + outline: none; + transition: 0.4s; +} + +.active, .accordion:hover { + color: #b2acac; +} + +/* Style the accordion panel. Note: hidden by default */ +.panel { + font-weight:normal; + padding:14px 0px 0 4px; + max-height: 0; + transition: max-height 0.5s ease-out; + overflow: hidden; +} + + +#scroll-top-wrapper a:hover { + color: gray; +} +#scroll-top-wrapper { + visibility:visible; + cursor:pointer; + opacity: 1.0; + text-decoration:underline; + padding: 10px; +} + .tdint { padding:0.3em 0.5em; vertical-align: top; diff --git a/copri4/shareeapp-operator/src/Lib/Mlogic.pm b/copri4/shareeapp-operator/src/Lib/Mlogic.pm index 771a5e9..96a7a71 100755 --- a/copri4/shareeapp-operator/src/Lib/Mlogic.pm +++ b/copri4/shareeapp-operator/src/Lib/Mlogic.pm @@ -8,10 +8,11 @@ use warnings; use CGI::Carp qw(fatalsToBrowser); use CGI ':standard'; use Mod::DBtank; - +use Tpl::CalReserv; use Data::Dumper; -my $dbt = new DBtank; +my $dbt = new DBtank; +my $calres = new CalReserv; sub new { my $class = shift; @@ -40,19 +41,11 @@ sub tpl(){ } my $bgcolor1 = $dbt->{primary}->{$varenv->{dbname}}->{bgcolor1}; - if($users_sharee->{c_id} && (!$R::sharee_edit || $R::sharee_edit ne "delete_account2") && ($users_sharee->{c_id} eq $varenv->{superu_id} || $dbt->{copri_conf}->{stage} eq "test" || $users_sharee->{txt08} eq "sigo\@sharee.bike")){ + #show it only in testmode + if($users_sharee->{c_id} && $node_meta->{tpl_id} == 302004 && ($users_sharee->{c_id} eq $varenv->{superu_id} || $dbt->{copri_conf}->{stage} eq "test")){ my $coo = $q->cookie('domcookie') || $q->param('sessionid') || ""; - - #my $api_test = "sharee_fr01"; my $bike="FR1538"; - #my $api_test = "sharee_fr01"; my $bike="FR1005";#E-Lastenrad (bike_group=300101, bike_node=300102) - my $api_test = "sharee_fr01"; my $bike="FR4781";#Tracking and BVB test - #my $api_test = "sharee_kn"; my $bike="KN1011"; - #my $api_test = "sharee_wue"; my $bike="WUE5525"; - #my $api_test = "sharee_sx"; my $bike="S3X1001"; - #my $api_test = "sharee_ren"; my $bike="REN2"; - + my $api_test = "sharee_fr01"; my $bike="FR4781";# test print $q->div({-style=>'float:right;text-align:right;height:25px;padding:6px 15px;background-color:white'},$q->a({-style=>"background-color:#ffffff;color:#$bgcolor1;", -href=>"$varenv->{metahost}/src/scripts/tests/index.pl?sessionid=$coo\&api_test=$api_test\&bike=$bike\&user_test=$users_sharee->{txt08}", -target=>'_blank'}," [ tests --> $api_test ] "),"$users_sharee->{txt08}",$q->a({-style=>"color:#$bgcolor1;", -href=>"logout_sharee$session"},"logout")),"\n"; - } print "