From bf83052322c0c8ffb4383e647c57275d2e7824f5 Mon Sep 17 00:00:00 2001 From: ragu Date: Mon, 24 Apr 2023 14:49:30 +0200 Subject: [PATCH] fixing some file links and creating standard dirs. Moving Service-Tour setup to DMS-Account --- .gitignore | 8 + copri4/main/src/Mod/APIfunc.pm | 39 +-- copri4/main/src/Mod/DBtank.pm | 8 +- copri4/main/src/Mod/Indexsharee.pm | 2 +- copri4/main/src/Mod/Payment.pm | 1 - copri4/main/src/Mod/Prelib.pm | 82 ++++- copri4/main/src/Mod/Pricing.pm | 2 +- copri4/main/src/Mod/Shareework.pm | 78 ----- copri4/main/src/Tpl/BaseEdit.pm | 2 +- copri4/main/src/Tpl/Liste3.pm | 15 +- copri4/main/src/scripts/Ilockauth.java | 5 + copri4/main/src/scripts/Ilockit_CSV2DB.pl | 145 --------- copri4/main/src/scripts/Ilockit_cloud.pl | 12 +- .../main/src/scripts/Ilockit_trackingcloud.pl | 10 +- copri4/main/src/scripts/Ilockkeygen.java | 15 +- copri4/main/src/scripts/Ilocktestauth.pl | 50 ---- copri4/main/src/scripts/adrupdate_byCSV.pl | 1 - copri4/main/src/scripts/auerswald_gespr.pl | 1 - copri4/main/src/scripts/coupongen.pl | 1 - copri4/main/src/scripts/coupongen_check.pl | 1 - copri4/main/src/scripts/cpdate_check.pl | 1 - copri4/main/src/scripts/ftpSWK.pl | 1 - copri4/main/src/scripts/ftpSWKstatistik.pl | 1 - copri4/main/src/scripts/jsonclient.pl | 26 -- copri4/main/src/scripts/loop_SWKcode.pl | 1 - .../main/src/scripts/mailTransportInnofact.pl | 1 - copri4/main/src/scripts/mailTransportcms.pl | 255 +++++++++++++++- copri4/main/src/scripts/payone_cron.pl | 1 - .../main/src/scripts/payone_post_Payment.pl | 1 - copri4/main/src/scripts/requested_timeout.pl | 8 +- copri4/main/src/scripts/sig_client.pl | 23 +- .../main/src/scripts/sms_gtx_SMSTransport.pl | 26 -- copri4/main/src/scripts/sms_message.pl | 7 +- .../src/scripts/statistik_amountCSV_files.pl | 277 ++++++++++++++++- .../src/scripts/statistik_dailystation.pl | 82 ++++- .../main/src/scripts/statistik_monthlyCSV.pl | 1 - .../scripts/statistik_occubike_stationCSV.pl | 280 +++++++++++++++++- .../statistik_occubike_stationCSV_innofact.pl | 1 - .../src/scripts/statistik_userevaluation.pl | 118 +++++++- .../src/scripts/statistik_zip_transport.pl | 64 +++- copri4/main/src/scripts/velofaktur_client.pl | 7 +- copri4/mkaccess.sh | 12 +- .../apache/shareeapp-operator.conf | 14 +- copri4/shareeapp-operator/cache | 1 + copri4/shareeapp-operator/src/Tpl/FormEdit.pm | 4 +- copri4/shareeconf/examples/global.cfg | 4 +- .../examples/sharee_operator.sql.gz | Bin 16199 -> 15579 bytes .../apache/shareedms-operator.conf | 9 +- copri4/shareedms-operator/pdf/pdfinvoice | 1 + .../apache/shareeweb-operator.conf | 5 +- copri4/shareeweb-project/cache | 1 + 51 files changed, 1275 insertions(+), 436 deletions(-) delete mode 100755 copri4/main/src/scripts/Ilockit_CSV2DB.pl delete mode 100755 copri4/main/src/scripts/Ilocktestauth.pl delete mode 120000 copri4/main/src/scripts/adrupdate_byCSV.pl delete mode 120000 copri4/main/src/scripts/auerswald_gespr.pl delete mode 120000 copri4/main/src/scripts/coupongen.pl delete mode 120000 copri4/main/src/scripts/coupongen_check.pl delete mode 120000 copri4/main/src/scripts/cpdate_check.pl delete mode 120000 copri4/main/src/scripts/ftpSWK.pl delete mode 120000 copri4/main/src/scripts/ftpSWKstatistik.pl delete mode 100755 copri4/main/src/scripts/jsonclient.pl delete mode 120000 copri4/main/src/scripts/loop_SWKcode.pl delete mode 120000 copri4/main/src/scripts/mailTransportInnofact.pl mode change 120000 => 100755 copri4/main/src/scripts/mailTransportcms.pl delete mode 120000 copri4/main/src/scripts/payone_cron.pl delete mode 120000 copri4/main/src/scripts/payone_post_Payment.pl delete mode 100755 copri4/main/src/scripts/sms_gtx_SMSTransport.pl mode change 120000 => 100755 copri4/main/src/scripts/statistik_amountCSV_files.pl mode change 120000 => 100755 copri4/main/src/scripts/statistik_dailystation.pl delete mode 120000 copri4/main/src/scripts/statistik_monthlyCSV.pl mode change 120000 => 100755 copri4/main/src/scripts/statistik_occubike_stationCSV.pl delete mode 120000 copri4/main/src/scripts/statistik_occubike_stationCSV_innofact.pl mode change 120000 => 100755 copri4/main/src/scripts/statistik_userevaluation.pl mode change 120000 => 100755 copri4/main/src/scripts/statistik_zip_transport.pl create mode 120000 copri4/shareeapp-operator/cache create mode 120000 copri4/shareedms-operator/pdf/pdfinvoice create mode 120000 copri4/shareeweb-project/cache diff --git a/.gitignore b/.gitignore index e69de29..124e92c 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,8 @@ +cache/ +data/ +pdf/ +cache/ +xml/ +csv/ +json/ +site/ diff --git a/copri4/main/src/Mod/APIfunc.pm b/copri4/main/src/Mod/APIfunc.pm index 6cf5bc9..1a8bdb7 100755 --- a/copri4/main/src/Mod/APIfunc.pm +++ b/copri4/main/src/Mod/APIfunc.pm @@ -1256,7 +1256,10 @@ sub booking_update(){ $update_cc->{txt13} = "$dbt->{operator}->{$varenv{dbname}}->{oprefix}"; #return after booking_update + #in real, we know freed accountable rentals only on rental end's + $pri->count_freedrental($q,$varenv,$auth->{c_id},$record_pos); 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})); @@ -1264,8 +1267,6 @@ sub booking_update(){ $update_pos->{int40} = "$counting->{int40}" if(looks_like_number($counting->{int40})); $update_pos->{int41} = "$counting->{int41}" if(looks_like_number($counting->{int41})); - #in real, we know freed accountable rentals only on rental end's - $pri->count_freedrental($q,$varenv,$auth->{c_id},$update_pos); $rows_end = $dbt->update_record($dbh,$update_pos,$record_pos); if($rows_end > 0){ @@ -1276,7 +1277,9 @@ sub booking_update(){ $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; - }else{ + } + #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}"; @@ -1302,22 +1305,21 @@ sub booking_update(){ $rows_end = $dbt->update_record($dbh,$update_pos,$record_pos); - $geo_debug .= "Out of station distance: $stations_raw->{$id}->{int04}|$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"; - - $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 Fahrradstation. Die Miete Fahrrad Nr. " . $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\"."; + $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"; } } - #$geo_distance_next == 100000 defaults to if no station in stations_raw - if($record_pos->{int42} == 0 && !$rows_end && $geo_distance_next == 100000){ - $geo_distance_next = "undefined"; - $booking_values->{response_state} = "Failure 2244: this bike not accepted on A-A station, state change forbidden."; - $booking_values->{response_text} = "Ein Mietende mit diesem Rad ist an dieser Station nicht erlaubt, da es sich hier um eine sog. A-A Station handelt. An A-A Stationen dürfen nur Mieträder zurück gegeben werden die von dort gemietet wurden."; - } $booking_values->{geo_distance} = "$geo_distance_next"; #print "$geo_debug\n"; $bw->log("GEOfencing geo_debug:$geo_debug",$q,""); @@ -2540,10 +2542,10 @@ sub fetch_tariff(){ #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}){ - $auth_operator->{txt18} =~ s/(\d+)/$dbt->{operator}->{$dbname}->{oprefix}$1/g; - @user_tour = ($auth_operator->{txt18}); - @user_tour = split(/\s/,$auth_operator->{txt18}) if($auth_operator->{txt18} =~ /\s/); + if($users_serviceapp->{int09} && $users_serviceapp->{txt07}){ + $users_serviceapp->{txt07} =~ s/(\d+)/$dbt->{operator}->{$dbname}->{oprefix}$1/g; + @user_tour = ($users_serviceapp->{txt07}); + @user_tour = split(/\s/,$users_serviceapp->{txt07}) if($users_serviceapp->{txt07} =~ /\s/); } }#end user_tour @@ -2557,7 +2559,7 @@ sub fetch_tariff(){ } #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 $auth_operator->{txt30} by int18:$tariff->{int18} select 4:",$tariff_all,""); + $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{ @@ -3065,7 +3067,6 @@ sub authorization(){ $pass_name =~ s/\s//g; my $pwmd5=md5_hex($pass_name) || ""; my $pwsha256=sha256_base64($pwmd5) || ""; - #$authref->{txt11} = "$pwmd5"; $authref->{txt04} = "$pwsha256"; #Servicetool, only users with users.int09=1 diff --git a/copri4/main/src/Mod/DBtank.pm b/copri4/main/src/Mod/DBtank.pm index 24dab02..eb36582 100755 --- a/copri4/main/src/Mod/DBtank.pm +++ b/copri4/main/src/Mod/DBtank.pm @@ -151,7 +151,7 @@ sub update_operatorsloop { delete $record_primary->{txt30};#tarifs delete $record_primary->{txt15};#Bonusnr delete $record_primary->{int07};#Rabatt - delete $record_primary->{txt18};#Service tour + delete $record_primary->{int09};#Service App staff delete $record_primary->{int16};#payone-cron-interval delete $record_primary->{int19};#Ilockit Admin #delete $record_primary->{int05};#Web-Login @@ -1049,9 +1049,9 @@ sub insert_contentoid { delete $insert->{txt17};#operators delete $insert->{txt30};#tarifs delete $insert->{txt15};#Bonusnr - delete $insert->{int07};#Rabatt - delete $insert->{txt18};#Service tour delete $insert->{int05};#Web-Login + delete $insert->{int07};#Rabatt + delete $insert->{int09};#Service App staff delete $insert->{int16};#payone-cron-interval delete $insert->{int19};#Ilockit Admin #delete $insert->{int12};#Vde (remove delete for global setting) @@ -1454,7 +1454,7 @@ sub insert_pos(){ my $user_name = $ctadr->{txt01}; $user_name = $ctadr->{txt08} if(!$user_name || $user_name eq "no name"); my $staff = 0; - $staff = 1 if($ctadr->{txt18});#service staff (no sms message) + $staff = 1 if($ctadr->{int09});#service staff (no sms message) my $deviceId = $ct->{int13} || 0; my $bike_charge = $ct->{int19} || 0; diff --git a/copri4/main/src/Mod/Indexsharee.pm b/copri4/main/src/Mod/Indexsharee.pm index 3292e9c..228ca52 100755 --- a/copri4/main/src/Mod/Indexsharee.pm +++ b/copri4/main/src/Mod/Indexsharee.pm @@ -345,7 +345,7 @@ sub handler { }elsif(($R::u_id || $R::c_idadr) && $R::base_edit =~ /_dmsusers/){ my $u_id = $1 if($R::u_id && $R::u_id =~ /(\d+)/); $u_id = $1 if($R::c_idadr && $R::c_idadr =~ /(\d+)/ && $R::base_edit eq "new_dmsusers"); - $feedb = $tk->manage_dmsusers($q,\%varenv,$R::base_edit,$u_id,$users_dms); + $feedb = $pl->manage_dmsusers($q,\%varenv,$R::base_edit,$u_id,$users_dms); } }else{ $feedb->{message} = "failure::Abbruch. Schreibender Zugriff \"DMS-Account\" verweigert."; diff --git a/copri4/main/src/Mod/Payment.pm b/copri4/main/src/Mod/Payment.pm index 46b74b2..f767535 100755 --- a/copri4/main/src/Mod/Payment.pm +++ b/copri4/main/src/Mod/Payment.pm @@ -380,7 +380,6 @@ sub captureCC_main { #txt16=txid must be copied from last captured invoice. #int01 sum must be set! #sequenz = 2 -#sudo su www-data -c "./src/scripts/payone_post.pl tinkdms refund contenttrans '' 32332 2" sub refund { my $self = shift; my $varenv = shift; diff --git a/copri4/main/src/Mod/Prelib.pm b/copri4/main/src/Mod/Prelib.pm index a69dd3f..14ddf13 100755 --- a/copri4/main/src/Mod/Prelib.pm +++ b/copri4/main/src/Mod/Prelib.pm @@ -51,6 +51,86 @@ my %varenv = $cf->envonline(); my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime; my $debug=1; +#insert/save/delete DMS users +sub manage_dmsusers { + my $self = shift; + my $q = shift; + my $varenv = shift; + my $base_edit = shift; + my $u_id = shift; + my $users_dms = shift || {}; + my $owner = $users_dms->{u_id} || 0; + my $table = "users"; + $q->import_names('R'); + my @keywords = $q->param; + + my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime; + my $feedb = { message => "", i_rows => 0, u_rows => 0, d_rows => 0 }; + $bw->log("manage_dmsusers",$q,""); + + my $dbh = ""; + my $adref = { + table => "contentadr", + fetch => "one", + template_id => "202", + c_id => "$u_id", + }; + my $ctadr = $dbt->fetch_record($dbh,$adref); + + #users have to be exist only if DMS activated + my $uref = { + table => "users", + fetch => "one", + u_id => "$u_id", + }; + my $users = $dbt->fetch_tablerecord($dbh,$uref); + + #datahash on update + my $dmsusers = { + table => "users", + mtime => "now()", + owner => "$owner", + u_id => "$u_id", + }; + if(ref($users) eq "HASH" && $users->{u_id} && (!$ctadr->{c_id} || $base_edit eq "delete_dmsusers")){ + $bw->log("delete DMS user from $varenv->{dbname}",$ctadr->{c_id},""); + $feedb->{d_rows} = $dbt->delete_content($dbh,"users",$u_id); + $dbt->update_one($dbh,$adref,"int07=null"); + $dbt->update_one($dbh,$adref,"int09=null"); + }elsif(ref($users) eq "HASH" && $users->{u_id} && $ctadr->{c_id} && $ctadr->{c_id} == $users->{u_id} && $base_edit eq "save_dmsusers"){ + $bw->log("update DMS user to $varenv->{dbname}",$ctadr->{c_id},""); + foreach(@keywords){ + my $val = $q->param($_); + my $valxx = $q->escapeHTML("$val"); + $valxx =~ s/^\s+//; $valxx =~ s/\s+$//; + if($_ =~ /^int\d+/){ + $valxx =~ s/,/./g; + $valxx = 0 if(!looks_like_number($valxx));# set to 0 for using == operator + $feedb->{u_rows} = $dbt->update_one($dbh,$dmsusers,"$_=$valxx"); + if($_ eq "int09"){ + if($valxx == 1){ + $dbt->update_one($dbh,$adref,"int09=1"); + }else{ + $dbt->update_one($dbh,$adref,"int09=null"); + } + } + }elsif($_ =~ /^txt\d+/){ + my @val = $q->param($_); + $valxx = $q->escapeHTML("@val"); + $feedb->{u_rows} = $dbt->update_one($dbh,$dmsusers,"$_='$valxx'"); + } + } + + }elsif($ctadr->{c_id} && !$users->{u_id} && $base_edit eq "new_dmsusers"){ + $bw->log("insert DMS user to $varenv->{dbname}",$ctadr->{c_id},""); + $feedb->{i_rows} = $dbt->insert_users($dbh,$ctadr->{c_id},$owner); + $dbt->update_one($dbh,$adref,"int07=100"); + } + + return $feedb; +}#end manage_dmsusers + + #insert content or contentuser sub new_content { my $self = shift; @@ -1014,7 +1094,7 @@ sub set_usertarif { my $i = 0; my $dbh_operator = $dbt->dbconnect_extern($dbname);#operator connect - my $tariff_all = { barcode => 0, txt18 => 0}; + my $tariff_all = { barcode => 0, int18 => 0}; my $tariff = { table => "content", fetch => "all", diff --git a/copri4/main/src/Mod/Pricing.pm b/copri4/main/src/Mod/Pricing.pm index dfc40b1..8e24d21 100755 --- a/copri4/main/src/Mod/Pricing.pm +++ b/copri4/main/src/Mod/Pricing.pm @@ -151,7 +151,7 @@ sub counting_rental { my $rental_minute = $self->clock_minutes($computed_clock); #if end_station == start_station and rental minutes < 5 minutes, then 0 - $rental_minute = 0 if($ctpos->{int04} == $ctpos->{int06} && $rental_minute && $rental_minute < 5); + $rental_minute = 0 if($ctpos->{int04} && $ctpos->{int06} && $ctpos->{int04} == $ctpos->{int06} && $rental_minute && $rental_minute < 5); my $rental_minute_all = $rental_minute; #init with some defaults diff --git a/copri4/main/src/Mod/Shareework.pm b/copri4/main/src/Mod/Shareework.pm index 9da716a..405cc3c 100755 --- a/copri4/main/src/Mod/Shareework.pm +++ b/copri4/main/src/Mod/Shareework.pm @@ -217,7 +217,6 @@ sub save_account(){ $pw_dummy = "1"; }elsif(length($valxx) >= 8){ my $pwmd5 = md5_hex($valxx) || ""; - $u_rows = $dbt->update_one($dbh,$update_primary,"txt11='$pwmd5'") if(length($pwmd5) > 20); my $pwsha256=sha256_base64($pwmd5) || ""; $u_rows = $dbt->update_one($dbh,$update_primary,"txt04='$pwsha256'") if(length($pwsha256) > 20); } @@ -244,12 +243,6 @@ sub save_account(){ elsif($_ =~ /int07|int16|int19|int23/){ $u_rows = $dbt->update_one("",$update_primary,"$_=$valxx"); } - #user_tour - elsif($_ =~ /txt18/){ - my @txt18 = $q->param('txt18'); - @txt18 = grep {!/null/} @txt18; - $u_rows = $dbt->update_one("",$update_primary,"$_='@txt18'"); - } #Text Sonstiges elsif($_ =~ /txt29/){ $u_rows = $dbt->update_one("",$update_primary,"$_='$valxx'"); @@ -580,76 +573,6 @@ sub save_account(){ return ($ret,$feedb); }#end save_account -#insert/save/delete DMS users -sub manage_dmsusers { - my $self = shift; - my $q = shift; - my $varenv = shift; - my $base_edit = shift; - my $u_id = shift; - my $users_dms = shift || {}; - my $owner = $users_dms->{u_id} || 0; - my $table = "users"; - $q->import_names('R'); - my @keywords = $q->param; - - my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime; - my $feedb = { message => "", i_rows => 0, u_rows => 0, d_rows => 0 }; - $bw->log("manage_dmsusers",$q,""); - - my $dbh = ""; - my $adref = { - table => "contentadr", - fetch => "one", - template_id => "202", - c_id => "$u_id", - }; - my $ctadr = $dbt->fetch_record($dbh,$adref); - - #users have to be exist only if DMS activated - my $uref = { - table => "users", - fetch => "one", - u_id => "$u_id", - }; - my $users = $dbt->fetch_tablerecord($dbh,$uref); - - #datahash on update - my $dmsusers = { - table => "users", - mtime => "now()", - owner => "$owner", - u_id => "$u_id", - }; - - if(ref($users) eq "HASH" && $users->{u_id} && (!$ctadr->{c_id} || $base_edit eq "delete_dmsusers")){ - $bw->log("delete DMS user from $varenv->{dbname}",$ctadr->{c_id},""); - $feedb->{d_rows} = $dbt->delete_content($dbh,"users",$u_id); - $dbt->update_one($dbh,$adref,"int07=null"); - }elsif(ref($users) eq "HASH" && $users->{u_id} && $ctadr->{c_id} && $ctadr->{c_id} == $users->{u_id} && $base_edit eq "save_dmsusers"){ - $bw->log("update DMS user to $varenv->{dbname}",$ctadr->{c_id},""); - foreach(@keywords){ - my $val = $q->param($_); - my $valxx = $q->escapeHTML("$val"); - $valxx =~ s/^\s+//; $valxx =~ s/\s+$//; - if($_ =~ /^int\d+/){ - $valxx =~ s/,/./g; - #$valxx = "null" if(!looks_like_number($valxx));#empty - $valxx = 0 if(!looks_like_number($valxx));# set to 0 for using == operator - $feedb->{u_rows} = $dbt->update_one($dbh,$dmsusers,"$_=$valxx"); - } - } - - }elsif($ctadr->{c_id} && !$users->{u_id} && $base_edit eq "new_dmsusers"){ - $bw->log("insert DMS user to $varenv->{dbname}",$ctadr->{c_id},""); - $feedb->{i_rows} = $dbt->insert_users($dbh,$ctadr->{c_id},$owner); - $dbt->update_one($dbh,$adref,"int07=100"); - } - - return $feedb; -} - - #coupon alias Gutschein sub save_transact(){ my $self = shift; @@ -846,7 +769,6 @@ sub send_password(){ my $pwmd5 = md5_hex($coo) || ""; if($email && $email =~ /\w\@\w/ && $pwmd5 && length($pwmd5) > 20 && $email !~ /$dbt->{copri_conf}->{test_accounts}/i){ - $db->updater("contentadr","1","1","txt11","$pwmd5","$owner","txt08","ilike","$email"); my $pwsha256=sha256_base64($pwmd5) || ""; $db->updater("contentadr","1","1","txt04","$pwsha256","$owner","txt08","ilike","$email"); system(`$varenv{basedir}/src/Mod/newsletter_tink.pl "$varenv{basedir}" "$varenv{wwwhost}" "send_password" "$email" "$coo"`); diff --git a/copri4/main/src/Tpl/BaseEdit.pm b/copri4/main/src/Tpl/BaseEdit.pm index c4b597a..45dda83 100755 --- a/copri4/main/src/Tpl/BaseEdit.pm +++ b/copri4/main/src/Tpl/BaseEdit.pm @@ -760,7 +760,7 @@ EOF } elsif($key =~ /txt/ && "$size" =~ /select/){ if($size =~ /_multiple/){ - if($key =~ /txt18/ && $node_meta->{tpl_id} eq "202"){ #user defined service_tour alias user_tour + if($key =~ /txt07/ && $node_meta->{tpl_id} eq "198"){ #user defined service_tour alias user_tour my $height = scalar(@_service_valxx); print $q->Tr(); print $q->td({-class=>'left_italic_cms',-style=>'vertical-align:top;',-colspan=>'1'},"$des"); diff --git a/copri4/main/src/Tpl/Liste3.pm b/copri4/main/src/Tpl/Liste3.pm index 55301e5..cfde663 100755 --- a/copri4/main/src/Tpl/Liste3.pm +++ b/copri4/main/src/Tpl/Liste3.pm @@ -274,7 +274,7 @@ sub tpl(){ elsif($node_meta->{node_name} eq "Tagesbericht"){ $R::detail_search="search"; $searchref->{offset} = 0; - $searchref->{limit} = 1000; + $searchref->{limit} = 10000; $v_journal = $node_meta->{node_name}; $searchref->{opos} = "null"; $tplids = 218; @@ -301,11 +301,16 @@ sub tpl(){ } #search at all - if($R::detail_search eq "search"){ + if($R::detail_search && $R::detail_search eq "search"){ $tplids = "209,218"; } $searchref->{tplids} = "$tplids"; + }elsif($R::detail_search && $R::detail_search eq "search"){ + $searchref->{offset} = 0; + $searchref->{limit} = 1000; } + + $main_ids = "$main_id,"; $main_ids .= $db->collect_noderec($main_id,$lang,"nothing"); $main_ids =~ s/,$//; @@ -389,11 +394,6 @@ EOF my $ct_ids = ""; my $last_ab = {}; - if($R::detail_search && $R::detail_search eq "search"){ - $searchref->{offset} = 0; - $searchref->{limit} = 1000; - } - my $channel_map = $dbt->channel_map(); my $mapref = {}; my $ct_users = $dbt->users_map($dbh,$mapref);#get serviceAPP and DMS users from contentadr @@ -1297,6 +1297,7 @@ EOF print "
\n"; print $q->a({-class=>"linknav1",-href=>"?go=backward_list;offset=$searchref->{offset};limit=$searchref->{limit}",-title=>'backward'},"← ") if($searchref->{offset} >= $searchref->{limit}); print $q->a({-class=>"linknav1",-href=>"?go=forward_list;offset=$searchref->{offset};limit=$searchref->{limit}",-title=>'forward'}," →") if($counter >= $limit-10); #if($rows > $limit && $nr > 0); + print $q->span({-style=>'color:silver;'}," (offset:$searchref->{offset}, limit:$searchref->{limit})"); print "
\n"; print $q->div({-style=>''}, " "),"\n"; diff --git a/copri4/main/src/scripts/Ilockauth.java b/copri4/main/src/scripts/Ilockauth.java index 47a4ac2..d69041e 100755 --- a/copri4/main/src/scripts/Ilockauth.java +++ b/copri4/main/src/scripts/Ilockauth.java @@ -1,3 +1,8 @@ +/* +SPDX-License-Identifier: AGPL-3.0-or-later +Copyright (c) Rainer Gümpelein, TeilRad GmbH +*/ + import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; diff --git a/copri4/main/src/scripts/Ilockit_CSV2DB.pl b/copri4/main/src/scripts/Ilockit_CSV2DB.pl deleted file mode 100755 index ab6d56e..0000000 --- a/copri4/main/src/scripts/Ilockit_CSV2DB.pl +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/perl -# -# SPDX-License-Identifier: AGPL-3.0-or-later -# Copyright (c) Rainer Gümpelein, TeilRad GmbH -# -#For pdf pw files -#"pdftotext -upw FksjxxxxxxfmC1h Teilrad_ISI_PLUS_BB01207.pdf" -#:1,$ s/^\n//g -#:1,$ s/\n/;/g -#:1,$ s/;C2-/\rC2-/g -#:1,$ s/;QR-/\rQR-/g -# -# -#check if UTF-8 -#file Teilrad_ISI_PLUS_BB01207.txt -#iconv -t utf-8 -f iso-8859-1 Ilockitkeys_110520.csv -o Ilockitkeys_110520_utf8.cs -# -#sudo su www-data -c "./src/scripts/Ilockit_CSV2DB.pl shareedms-kn ../shareeconf/smartlock-keys/Ilockit-16-BB01742_1v2.csv" -# -#do it twice to set hex-key and bike-nr! -# -use vars qw($syshost); - -BEGIN { - $syshost = $ARGV[0] || exit 1; -} - -use lib "/var/www/copri-bike/$syshost/src"; - -my $csv_file = $ARGV[1] || ""; - -use strict; -use warnings; -use POSIX; -use DBI; -use CGI ':standard'; -use Lib::Config; -use Mod::DBtank; -use Scalar::Util qw(looks_like_number); -use Data::Dumper; - -my $q = new CGI; -my $cf = new Config; -my %varenv = $cf->envonline("$syshost"); -print "$varenv{wwwhost}\n"; -my $dbt = new DBtank; -my $lang = "de"; -my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime; -my $dbh = ""; -my $main_id = 300103;#TODO Flotten ID -my $template_id = 205; - -### -#Start loop payone log and update userid ################################## -#### -#reading CSV - my $dbh_csv = DBI->connect("DBI:CSV:"); - $dbh_csv->{'csv_tables'}->{'ilockitcsv'} = { - 'eol' => "\n", - 'sep_char' => ";", - 'quote_char' => undef, - #'quote_char' => "\"", - 'escape_char' => undef, - 'file' => $csv_file, - #'col_names' => ["serialnr","ilockit_id","ilockit_key","c1"] - 'col_names' => ["serialnr","ilockit_id","ilockit_key","c1","bikeid","rahmen","stationid","bike_name"] - }; - - my $sth = $dbh_csv->prepare("SELECT * FROM ilockitcsv where serialnr like 'C2-%'"); - my $rc = $sth->execute(); - my $csv = $sth->fetchall_hashref("serialnr"); - - my $i=0; - foreach my $id (sort { $csv->{$a}->{serialnr} cmp $csv->{$b}->{serialnr} } keys (%$csv)){ - $i++; - - if($csv->{$id}->{serialnr}){ - $csv->{$id}->{ilockit_id} =~ s/\+/\-/; - $csv->{$id}->{c1} =~ s/R/red /g; - $csv->{$id}->{c1} =~ s/B/blue /g; - $csv->{$id}->{c1} =~ s/G/green /g; - $csv->{$id}->{c1} =~ s/\s$//;#empty last space - $csv->{$id}->{bikeid} =~ s/THU//; - $csv->{$id}->{stationid} =~ s/THU//; - - print "$i) $csv->{$id}->{serialnr}|\n"; - - my $ct = &select_content($csv->{$id}); - - my $data = { - table => "content", - main_id => "$main_id", - template_id => "$template_id", - txt22 => "$csv->{$id}->{serialnr}", - txt18 => "$csv->{$id}->{ilockit_id}", - byte01 => "\\x$csv->{$id}->{ilockit_key}", - barcode => "$csv->{$id}->{bikeid}", - int04 => "$csv->{$id}->{stationid}",#station - txt01 => "$csv->{$id}->{bike_name}", - txt11 => "$csv->{$id}->{rahmen}", - txt23 => "$csv->{$id}->{c1}", - int10 => "1",#available - int20 => "1",#locked - int11 => "2",#Ilockit - txt04 => "", #Sonstiges - mtime => "now()", - owner => "1842", - }; - - if(ref($ct) eq "HASH" && $ct->{c_id} && ref($data) eq "HASH" && $csv->{$id}->{serialnr}){ - print "UPDATE $csv->{$id}->{serialnr} (c_id:$ct->{c_id})\n"; - $data->{barcode} = $ct->{c_id} if(!$ct->{barcode}); - $dbt->update_record($dbh,$data, { c_id => $ct->{c_id} }); - print Dumper($data) . "\n"; - }elsif(ref($data) eq "HASH" && $csv->{$id}->{serialnr}){ - print "INSERT $csv->{$id}->{serialnr}\n"; - $dbt->insert_contentoid($dbh,$data); - print Dumper($data) . "\n"; - }else{ - print "nothing todo\n"; - } - } -} - -#content check if still exists -sub select_content{ - my $ct_hash = shift; - my $fetch = { - table => "content", - main_id => "$main_id", - template_id => "$template_id", - fetch => "one", - }; - if(ref($ct_hash) eq "HASH" && $ct_hash->{serialnr}){ - $fetch = { %$fetch , txt22 => "=::$ct_hash->{serialnr}" }; - #$fetch = { %$fetch , barcode => "<::100" }; - #$fetch = { %$fetch , int10 => "!=::3" }; - #$fetch = { %$fetch , int11 => "!=::2" }; - } - - my $ct = $dbt->fetch_record($dbh,$fetch); - return $ct; -} - - diff --git a/copri4/main/src/scripts/Ilockit_cloud.pl b/copri4/main/src/scripts/Ilockit_cloud.pl index ea9c509..b80de71 100755 --- a/copri4/main/src/scripts/Ilockit_cloud.pl +++ b/copri4/main/src/scripts/Ilockit_cloud.pl @@ -3,10 +3,10 @@ # SPDX-License-Identifier: AGPL-3.0-or-later # Copyright (c) Rainer Gümpelein, TeilRad GmbH # +#Examples +#./src/scripts/Ilockit_cloud.pl shareedms-operator get_events 95 # -##sudo su www-data -c "./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_events 95" -# -#sudo su www-data -c "./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_positions" +#./src/scripts/Ilockit_cloud.pl shareedms-operator get_positions # #Ilockit GPS cloud # @@ -77,15 +77,15 @@ while (my ($key, $op_name) = each %{ $dbt->{operator} }) { $dbh = $dbt->dbconnect_extern($sharee_operator); #per cronjob once a day to get and update content with cloud device id - #sudo su www-data -c "./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_devices" + #./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_devices &get_devices($dbh,$op_name) if($todo eq "get_devices"); - #sudo su www-data -c "./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_events 95" + #./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_events 95 if($todo eq "get_events"){ &get_events($dbh,$op_name,$response_in); &get_positions($dbh,$op_name); } - #sudo su www-data -c "./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_positions 6572" + #./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_positions 6572 #&get_positions($dbh,$op_name->{oprefix}) if($todo eq "get_positions"); } } diff --git a/copri4/main/src/scripts/Ilockit_trackingcloud.pl b/copri4/main/src/scripts/Ilockit_trackingcloud.pl index b61a212..8d99330 100755 --- a/copri4/main/src/scripts/Ilockit_trackingcloud.pl +++ b/copri4/main/src/scripts/Ilockit_trackingcloud.pl @@ -6,15 +6,9 @@ #get tracking by #Ilockit trips by Ilockit cloud # -#sudo su www-data -c "./src/scripts/Ilockit_trackingcloud.pl shareedms-fr01 get_tripsum 155884" +#Example +#./src/scripts/Ilockit_trackingcloud.pl shareedms-operator get_tripsum 155884 # -#2021-07-20 -#GPS tracking -#Unser System bieten für die Auswertung von Fahrtstrecken bereits Zusammenfassungen an. Hierfür können Sie einfach die folgenden Calls benutzen: -# -#GET /api/reports/summary?groupId=95& from=2021-07-17T18:30:00Z& to=2021-07-20T18:30:00Z - Gibt Ihnen eine Zusammenfassung aller Fahrstrecken für die Schlösser in der Gruppe zurück. -# -#GET /api/reports/trips?groupId=95& from=2020-07-17T18:30:00Z& to=2021-07-20T18:30:00Z - Gibt Ihnen einzelne Fahrtstrecken für die Schlösser in der Gruppe zurück. # # use vars qw($syshost); diff --git a/copri4/main/src/scripts/Ilockkeygen.java b/copri4/main/src/scripts/Ilockkeygen.java index b5cb00b..b56f488 100755 --- a/copri4/main/src/scripts/Ilockkeygen.java +++ b/copri4/main/src/scripts/Ilockkeygen.java @@ -1,4 +1,9 @@ /* +SPDX-License-Identifier: AGPL-3.0-or-later +Copyright (c) haveltec GmbH, TeilRad GmbH + +Created by Bjoern Kinberger on 04.10.18. + import android.util.Log; */ import java.io.InputStream; @@ -11,22 +16,12 @@ import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Random; -/** - * Created by Bjoern Kinberger on 04.10.18. - * - * This is a test class for the authentication process without a server - * - * Only use this for the development process, the key generation should be done on the server! - */ public class Ilockkeygen { //private static final String LOG_TAG = Ilockkeygen.class.getName(); public static byte[] sha1Value; - public static void generateKey(byte[] randomNum, byte[] internKey) { - //System.out.println( "K_int_byte = " + internKey ); - //System.out.println("K_int_string = " + new String(internKey)); System.out.println("K_int = " + Arrays.toString(internKey)); byte[] filler = {0, 0, 0, 0}; diff --git a/copri4/main/src/scripts/Ilocktestauth.pl b/copri4/main/src/scripts/Ilocktestauth.pl deleted file mode 100755 index 2cb5567..0000000 --- a/copri4/main/src/scripts/Ilocktestauth.pl +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/perl -# -#Autor ragu@gnu-systems.de -# -#Ilockit authentify test -# -#sudo su www-data -c "./src/scripts/Ilocktestauth.pl shareeapp_operator 1003" -# -# -use vars qw($syshost); - -BEGIN { - $syshost = $ARGV[0] || exit 1; -} - -use lib "/var/www/copri-bike/$syshost/src"; - -my $dbname = $ARGV[1] || ""; -my $bike = $ARGV[2] || ""; - -use strict; -use warnings; -use POSIX; -use CGI ':standard'; -use Lib::Config; -use Data::Dumper; - -my $q = new CGI; -my $cf = new Config; -my %varenv = $cf->envonline("$syshost"); -my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime; - - -my @K_select = `cd /var/www/copri-bike/$varenv{syshost}/src/scripts && export CLASSPATH='.:/usr/share/java:/usr/share/java/postgresql.jar' && java Ilockauth $dbname $bike`; - foreach(@K_select){ - my ($K_key,$K_val) = split(/ = /, $_); - $K_val =~ s/\n//g; - print "$K_key: $K_val\n"; - } - -my $receiver_usb = "abcd"; -if($receiver_usb =~ /(\w)(\w)$/){ - my $a = ord($1); - my $b = ord($2); - print "$1|$2" . "\n"; - print "$a|$b" . "\n"; - my $receiver_id = sprintf( "%x", $a ) . sprintf( "%x", $b ); - print $receiver_id . "\n"; -} - diff --git a/copri4/main/src/scripts/adrupdate_byCSV.pl b/copri4/main/src/scripts/adrupdate_byCSV.pl deleted file mode 120000 index 2675e8a..0000000 --- a/copri4/main/src/scripts/adrupdate_byCSV.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/adrupdate_byCSV.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/auerswald_gespr.pl b/copri4/main/src/scripts/auerswald_gespr.pl deleted file mode 120000 index 2a67161..0000000 --- a/copri4/main/src/scripts/auerswald_gespr.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/auerswald_gespr.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/coupongen.pl b/copri4/main/src/scripts/coupongen.pl deleted file mode 120000 index 4b65ed8..0000000 --- a/copri4/main/src/scripts/coupongen.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/coupongen.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/coupongen_check.pl b/copri4/main/src/scripts/coupongen_check.pl deleted file mode 120000 index c0d3103..0000000 --- a/copri4/main/src/scripts/coupongen_check.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/coupongen_check.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/cpdate_check.pl b/copri4/main/src/scripts/cpdate_check.pl deleted file mode 120000 index b72d90e..0000000 --- a/copri4/main/src/scripts/cpdate_check.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/cpdate_check.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/ftpSWK.pl b/copri4/main/src/scripts/ftpSWK.pl deleted file mode 120000 index 9c7ad35..0000000 --- a/copri4/main/src/scripts/ftpSWK.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/ftpSWK.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/ftpSWKstatistik.pl b/copri4/main/src/scripts/ftpSWKstatistik.pl deleted file mode 120000 index 64db4b7..0000000 --- a/copri4/main/src/scripts/ftpSWKstatistik.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/ftpSWKstatistik.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/jsonclient.pl b/copri4/main/src/scripts/jsonclient.pl deleted file mode 100755 index e7aba70..0000000 --- a/copri4/main/src/scripts/jsonclient.pl +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/perl - -# Client -use JSON::RPC::Client; - -my $client = new JSON::RPC::Client; - -my $uri = 'http://www.example.com/jsonrpc/Test'; -my $obj = { - method => 'sum', # or 'MyApp.sum' - params => [10, 20], -}; - -my $res = $client->call( $uri, $obj ) - -if($res){ - if ($res->is_error) { - print "Error : ", $res->error_message; - } - else { - print $res->result; - } -} -else { - print $client->status_line; -} diff --git a/copri4/main/src/scripts/loop_SWKcode.pl b/copri4/main/src/scripts/loop_SWKcode.pl deleted file mode 120000 index 22622df..0000000 --- a/copri4/main/src/scripts/loop_SWKcode.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/loop_SWKcode.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/mailTransportInnofact.pl b/copri4/main/src/scripts/mailTransportInnofact.pl deleted file mode 120000 index f2a4035..0000000 --- a/copri4/main/src/scripts/mailTransportInnofact.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/mailTransportInnofact.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/mailTransportcms.pl b/copri4/main/src/scripts/mailTransportcms.pl deleted file mode 120000 index 0bc6af8..0000000 --- a/copri4/main/src/scripts/mailTransportcms.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/mailTransportcms.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/mailTransportcms.pl b/copri4/main/src/scripts/mailTransportcms.pl new file mode 100755 index 0000000..ddc4c87 --- /dev/null +++ b/copri4/main/src/scripts/mailTransportcms.pl @@ -0,0 +1,254 @@ +#!/usr/bin/perl +# +# SPDX-License-Identifier: AGPL-3.0-or-later +# Copyright (c) Rainer Gümpelein, TeilRad GmbH +# +#2023-01-02 +#adapted from mailTransport.pl without bulkmail +#NEW +#managed text by operator cms +# +#Example +#./src/scripts/mailTransportcms.pl 'shareedms-operator' 'send_alarm2hotline' '[contentuser.c_id]' '[contenttheftpos.c_id]' +# +# +# +use vars qw($syshost); + +BEGIN { + $syshost = $ARGV[0] || die 'syshost not defined'; +} + +use lib "/var/www/copri-bike/$syshost/src"; + +use strict; +use warnings; +use utf8; +use Encode; +use POSIX; +use Scalar::Util qw(looks_like_number); +use Lib::Config; +use Mod::DBtank; +use Mod::MailTransport; +use Data::Dumper; +my $cf = new Config; +my %varenv = $cf->envonline(); + +my $dbt = new DBtank; +my $mailtrans = new MailTransport; +my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime; + +#one contentadr.c_id OR email on command +my $todo = $ARGV[1] || ""; +my $adr_id = $ARGV[2] || "";#takes ctt.c_id or ctadr.email +my $ct_id = $ARGV[3] || ""; +my $attachment = $ARGV[4] || ""; + +open(EMA, ">> $dbt->{copri_conf}->{logdir}/mailTransportcms.log"); +print EMA "\n$now_dt, start mailTransportcms.pl syshost: $syshost, todo:$todo, adr_id:$adr_id, ct_id:$ct_id, attachment:$attachment \n"; + + +#mailxcfg is shareeconf/mailx.cfg selection! +#hash data to send +my $sendref = { + mailxcfg => "mailx_default", + #mailxcfg => "mailx_admin", + syshost => "$syshost", + mail_to => "", + c_id => 0, + subject => "", + message => "", + signature => "", + attachment => "", +}; + +#my $project = $dbt->{operator}->{$varenv{dbname}}->{project} || die "project not defined"; +my $oprefix = $dbt->{operator}->{$varenv{dbname}}->{oprefix} || ""; + +my $sendmail = {}; + +#send_cpdate_message, done by cronjob cpdate_check.pl +$sendmail = send_cpupdate_message($todo,$sendref,$adr_id) if(($todo eq "send_cpupdate_message" || $todo eq "send_proactive_cpupdate_message") && looks_like_number($adr_id)); + +#send_alarm2hotline, done by Ilockit_cloud.pl +$sendmail = send_alarm2hotline($sendref,$ct_id) if($todo eq "send_alarm2hotline" && looks_like_number($adr_id) && looks_like_number($ct_id)); + +if($sendmail->{c_id}){ + sendmailjob($sendmail); +}else{ + print EMA "Error, can not sendmailjob without c_id\n"; +} + +#send_cpupdate_message +sub send_cpupdate_message { + my $todo = shift; + my $sendref = shift; + my $adr_id = shift || ""; + + my $client_encoding = "iso-8859-1"; + my $dbh_primary = $dbt->dbconnect_extern($dbt->{primary}->{sharee_primary}->{database}->{dbname},$client_encoding); + + #TeilRad Kontakt + my $pref_ctu = { + table => "contentuser", + fetch => "one", + c_id => "1",#Kontakt-hotline + }; + my $uadr = { c_id => 0 }; + $uadr = $dbt->fetch_tablerecord($dbh_primary,$pref_ctu); + + #CMS text + my $cms_message_key = "email-cpupdate-message"; + $cms_message_key = "email-proactive-cpupdate-message" if($todo eq "send_proactive_cpupdate_message"); + my $pref_cms = { + table => "contentuser", + fetch => "one", + ct_name => "$cms_message_key", + }; + my $cms_prim = { c_id => 0, txt01 => '' }; + $cms_prim = $dbt->fetch_tablerecord($dbh_primary,$pref_cms); + + #Kunde + my $pref_adr = { + table => "contentadr", + fetch => "one", + c_id => "$adr_id", + }; + my $cta = { c_id => 0 }; + $cta = $dbt->fetch_tablerecord($dbh_primary,$pref_adr); + + $sendref = prepare_content($sendref,$cta,$cms_prim,$uadr); + + return $sendref; +}#end send_cpupdate_message + +#prepare email by cms markup +sub prepare_content { + my $sendref = shift; + my $cta = shift; + my $cms_prim = shift; + my $uadr = shift; + + my $globalconf_file = "/var/www/copri4/shareeconf/global.cfg"; + my $conf = Config::General->new($globalconf_file); + my %globalconf = $conf->getall; + + my $app_name = "App"; + while (my ($key, $merchant) = each %{ $globalconf{merchant_ids} }) { + $app_name =~ s/$app_name/$merchant->{app_name}/ if($merchant->{app_name} && $cta->{int15} && $cta->{int15} == $merchant->{id}); + } + my $subject = "TeilRad Mietradsystem";#default + $subject = $1 if($cms_prim->{txt01} =~ /--subject--(.*)--subject--/); + $cms_prim->{txt01} =~ s/--subject--$subject--subject--//; + $cms_prim->{txt01} =~ s/\n//; + $cms_prim->{txt01} =~ s/\n//; + +my $signature = <{txt01} + $uadr->{txt03} + $uadr->{txt06} + $uadr->{txt07} + $uadr->{txt08} + + $uadr->{txt84} + +EOF +; + + $sendref->{mail_to} = $cta->{txt08}; + $sendref->{c_id} = $cta->{c_id}; + $sendref->{subject} = $subject; + $sendref->{subject} =~ s/::app_name::/$app_name/; + $sendref->{subject} =~ s/Mein // if($sendref->{subject} =~ /^Mein/); + + $sendref->{message} = $cms_prim->{txt01}; + $sendref->{message} =~ s/::user_name::/$cta->{txt01}/; + $sendref->{message} =~ s/::app_name::/$app_name/g; + $sendref->{message} =~ s/::signature::/$signature/; + $sendref->{message} =~ s/\n/\
/g; + + return $sendref; +}#end prepare_content + + +#send_alarm2hotline +sub send_alarm2hotline { + my $sendref = shift; + my $ct_id = shift || ""; + + my $client_encoding = "iso-8859-1"; + my $dbh = $dbt->dbconnect_extern($dbt->{operator}->{$varenv{dbname}}->{database}->{dbname},$client_encoding); + + my $pref_ctu = { + table => "contentuser", + fetch => "one", + c_id => "1",#Kontakt-hotline + }; + my $uadr = { c_id => 0 }; + $uadr = $dbt->fetch_tablerecord($dbh,$pref_ctu); + $sendref->{mail_to} = $uadr->{txt08}; + + #without cms + my $cms_prim = { c_id => 0, txt01 => 'Folgendes Mietrad hat einen Diebstahlalarm ausgelöst' }; + + my $pref_ct = { + table => "contenttheftpos", + fetch => "one", + c_id => $ct_id, + }; + + my $ct = { c_id => 0 }; + $ct = $dbt->fetch_tablerecord($dbh,$pref_ct); + + $sendref->{c_id} = $ct->{c_id}; + $sendref->{subject} = "Diebstahlalarm $oprefix$ct->{barcode}"; + +$sendref->{message} = <{txt01} + + Bike: $oprefix$ct->{barcode} + Speed: $ct->{int07} + Meter: $ct->{int08} + GPS: $ct->{txt06} + Timestamp: $ct->{start_time} + + Öffne das Alarmjournal für weitere Informationen: + $dbt->{operator}->{$varenv{dbname}}->{operatorDMS}/DMS/Alarmjournal + + Freundliche Grüße, + -- + $uadr->{txt01} + $uadr->{txt03} + $uadr->{txt06} + + $uadr->{txt84} + +EOF +; + + $sendref->{message} =~ s/\n/\
/g; + return $sendref; +} + +#sending mail job +sub sendmailjob { + my $sendref = shift || ""; + + #at first connect mailxchanger by mailx.cfg config + my ($smtp,$mailxconf) = $mailtrans->mail_connect($sendref); + + #one mailing with mail address on command + if($sendref->{mail_to} =~ /\w\@\w/ && $sendref->{subject} && $sendref->{message}){ + my $ret = ""; + $ret = $mailtrans->mail_transport($smtp,$mailxconf,$sendref); + + print EMA "done mailing with state to $sendref->{mail_to}: $ret\n"; + }else{ + print EMA "Error, no or false email address $sendref->{mail_to}, exit\n"; + } +} + +print EMA "\n\n"; +close EMA; + diff --git a/copri4/main/src/scripts/payone_cron.pl b/copri4/main/src/scripts/payone_cron.pl deleted file mode 120000 index f1fa908..0000000 --- a/copri4/main/src/scripts/payone_cron.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/payone_cron.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/payone_post_Payment.pl b/copri4/main/src/scripts/payone_post_Payment.pl deleted file mode 120000 index f975fdd..0000000 --- a/copri4/main/src/scripts/payone_post_Payment.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/payone_post_Payment.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/requested_timeout.pl b/copri4/main/src/scripts/requested_timeout.pl index 5f2293d..022ee42 100755 --- a/copri4/main/src/scripts/requested_timeout.pl +++ b/copri4/main/src/scripts/requested_timeout.pl @@ -1,10 +1,12 @@ #!/usr/bin/perl # -#Autor ragu@gnu-systems.de +# SPDX-License-Identifier: AGPL-3.0-or-later +# Copyright (c) Rainer Gümpelein, TeilRad GmbH # #set availabel if requested > 15min # -#sudo su www-data -c "./src/scripts/requested_timeout.pl shareedms-fr01" +#Example +#./src/scripts/requested_timeout.pl shareedms-operator # # use vars qw($syshost); @@ -40,7 +42,6 @@ my $pref = { table => "contenttranspos", fetch => "all", keyfield => "c_id", - #txt10 => "requested", int10 => "2", owner => "!=::199",#don't select LV api requested bikes start_time => "<=::(now() - interval '$interval_min minutes')", @@ -49,7 +50,6 @@ my $record_cp = $dbt->fetch_tablerecord($dbh,$pref); my $update_cp = { table => "contenttranspos", - #txt10 => "available", int10 => "1", owner_end => "172", mtime => "now()", diff --git a/copri4/main/src/scripts/sig_client.pl b/copri4/main/src/scripts/sig_client.pl index 3520d82..7173e9b 100755 --- a/copri4/main/src/scripts/sig_client.pl +++ b/copri4/main/src/scripts/sig_client.pl @@ -5,13 +5,14 @@ # #On this forking script, nothing will saved on script, else by execute APIsigclient methodes # -# command line syntax -# sudo su www-data -c "./src/scripts/sig_client.pl shareeapp-sx 'todo' 'user_id' 'sig bikeId' 'pos_id'" +# command line syntax +# examples +# ./src/scripts/sig_client.pl shareeapp-operator 'todo' 'user_id' 'sig bikeId' 'pos_id' # -# sudo su www-data -c "./src/scripts/sig_client.pl shareeapp-sx bikes_available" +# ./src/scripts/sig_client.pl shareeapp-operator bikes_available # -# sudo su www-data -c "./src/scripts/sig_client.pl shareeapp-sx reserve 1842 '380116b5-0522-43da-ab66-477744a731a3' ''" -# sudo su www-data -c "./src/scripts/sig_client.pl shareeapp-sx rental 1842 '380116b5-0522-43da-ab66-477744a731a3' ''" +# ./src/scripts/sig_client.pl shareeapp-operator reserve [user_id] '380116b5-0522-43da-ab66-477744axxxxx' '' +# ./src/scripts/sig_client.pl shareeapp-operator rental [user_id] '380116b5-0522-43da-ab66-477744axxxxx' '' # use vars qw($syshost); @@ -95,24 +96,24 @@ if($todo eq "bikes_available"){ #only for tests. build in methode elsif($todo eq "reserve"){ - #$ctadr = { c_id => 1842 }; - #$ct_bike = { txt22 => "380116b5-0522-43da-ab66-477744a731a3" }; + #$ctadr = { c_id => user }; + #$ct_bike = { txt22 => "380116b5-0522-43da-ab66-4777xxxxxxx3" }; my $return = $si->sig_booking(\%varenv,$todo,$ctadr,$ct_bike,$ctpos); #print $0 . Dumper($return) . "\n"; } #live! Fork rental request with bike "id" elsif($todo eq "rental" && $ctadr->{c_id} > 0){ - #$ctadr = { c_id => 1842 }; - #$ct_bike = { txt22 => "380116b5-0522-43da-ab66-477744a731a3" }; + #$ctadr = { c_id => user }; + #$ct_bike = { txt22 => "380116b5-0522-43da-ab66-47774xxxxxa3" }; my $return = $si->sig_booking(\%varenv,$todo,$ctadr,$ct_bike,$ctpos); #print $0 . Dumper($return) . "\n"; } #live! Fork unlock by lock_state=unlocking request with bike "id" elsif($todo eq "unlock" && $ctadr->{c_id} > 0){ - #$ctadr = { c_id => 1842 }; - #$ct_bike = { txt22 => "380116b5-0522-43da-ab66-477744a731a3" }; + #$ctadr = { c_id => user }; + #$ct_bike = { txt22 => "380116b5-0522-43da-ab66-47774xxxxxa3" }; my $return = $si->sig_unlock(\%varenv,$todo,$ctadr,$ct_bike,$ctpos); #print $0 . Dumper($return) . "\n"; } diff --git a/copri4/main/src/scripts/sms_gtx_SMSTransport.pl b/copri4/main/src/scripts/sms_gtx_SMSTransport.pl deleted file mode 100755 index bd018c8..0000000 --- a/copri4/main/src/scripts/sms_gtx_SMSTransport.pl +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/perl -# -#sudo su www-data -c "./src/scripts/sms_gtx_SMSTransport.pl shareeapp-operator '+491799xxxx72'" -# -use vars qw($syshost); - -BEGIN { - $syshost = $ARGV[0] || die 'syshost not defined'; -} - -use lib "/var/www/copri4/$syshost/src"; - -use strict; -use warnings; -use POSIX; -use Mod::SMSTransport; - -my $smstrans = new SMSTransport; - -my $phone = $ARGV[1] || die 'phone not defined'; -my $adrhash = { - txt07 => $phone, - txt34 => "nureinlangertestdigest", -}; - -my $ret_json = $smstrans->sms_ack_digest($adrhash); diff --git a/copri4/main/src/scripts/sms_message.pl b/copri4/main/src/scripts/sms_message.pl index 3f4374d..246426f 100755 --- a/copri4/main/src/scripts/sms_message.pl +++ b/copri4/main/src/scripts/sms_message.pl @@ -3,14 +3,15 @@ # SPDX-License-Identifier: AGPL-3.0-or-later # Copyright (c) Rainer Gümpelein, TeilRad GmbH # +#Examples #SMS message if 24h,48h,72h occupied -#sudo su www-data -c "./src/scripts/sms_message.pl shareedms-fr01 '24h_occupied' '' ''" +#./src/scripts/sms_message.pl shareedms-operator '24h_occupied' '' '' # #SMS message locking_progress after 60sec -#sudo su www-data -c "./src/scripts/sms_message.pl shareeapp-operator locking_progress '0179xxxx372' $pos_id" +#./src/scripts/sms_message.pl shareeapp-operator locking_progress '0179xxxx372' $pos_id # #SMS theftalarm -#sudo su www-data -c "./src/scripts/sms_message.pl shareedms-kn 'send_alarm2hotline' '' '18498'" +#./src/scripts/sms_message.pl shareedms-operator 'send_alarm2hotline' '' '18498' # use vars qw($syshost); diff --git a/copri4/main/src/scripts/statistik_amountCSV_files.pl b/copri4/main/src/scripts/statistik_amountCSV_files.pl deleted file mode 120000 index 5eb83e3..0000000 --- a/copri4/main/src/scripts/statistik_amountCSV_files.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/statistik_amountCSV_files.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/statistik_amountCSV_files.pl b/copri4/main/src/scripts/statistik_amountCSV_files.pl new file mode 100755 index 0000000..8b39863 --- /dev/null +++ b/copri4/main/src/scripts/statistik_amountCSV_files.pl @@ -0,0 +1,276 @@ +#!/usr/bin/perl +# +# SPDX-License-Identifier: AGPL-3.0-or-later +# Copyright (c) Rainer Gümpelein, TeilRad GmbH +# +#Generates CSV for amount channels and start-station/end-station and Nuter Registrierung +# +#csv/Statistik-Allnewuser_amount_* +#csv/Statistik-channel_amount_* +#csv/Statistik-start_end_station_* +#csv/Statistik-Bonusnewuser_amount_* +# +# +#Examples +#./src/scripts/statistik_amountCSV_files.pl shareedms-operator '' '' '300103'" +# +#with start_time and end_time +#./src/scripts/statistik_amountCSV_files.pl shareedms-operator '2022-01-01' '2022-02-01' '300101'" +#./src/scripts/statistik_amountCSV_files.pl shareedms-operator '2022-01-01' '2022-02-01' '300103'" +# +use vars qw($syshost); + +BEGIN { + $syshost = $ARGV[0] || exit 1; +} + +use lib "/var/www/copri-bike/$syshost/src"; + +my $start_itime = $ARGV[1] || ""; +my $end_itime = $ARGV[2] || ""; + +#2022-08-03 changed $bikesys int12 select to $bike_type_id int29 +my $bike_type_id = $ARGV[3] || ""; +my $flotte_type = ""; +if($bike_type_id == 300101){ + $flotte_type = "Lastenrad"; +}elsif($bike_type_id == 300103){ + $flotte_type = "Stadtrad"; +}else{ + print "Failure, bike_type_id must be nodes.type_id number of Flot\n\n"; + exit 1; +} + + +my $owner = $ARGV[4] || ""; + +use strict; +use warnings; +use utf8; +use POSIX; +use CGI ':standard'; +use Lib::Config; +use Mod::DBtank; +use Scalar::Util qw(looks_like_number); +use DateTime; +use DateTime::Format::Pg; +use Text::CSV_XS; +use Sys::Hostname; +my $hostname = hostname; + +use Mod::Libenz; +use Mod::Pricing; +use Mod::APIfunc; + +use Data::Dumper; + +my $q = new CGI; +my $cf = new Config; +my %varenv = $cf->envonline(); +#print "host: $varenv{wwwhost}\n"; +my $dbt = new DBtank; +my $lb = new Libenz; +my $pri = new Pricing; +my $apif = new APIfunc; + +my $dbh = $dbt->dbconnect(); + +my $dt1 = DateTime->now(time_zone => 'Europe/Berlin'); +if(!$end_itime){ + $end_itime = $dt1; +} + +if(!$start_itime){ + $start_itime = $dt1->clone->add(months => -1, end_of_month => 'preserve'); +} + +my $month = $1 if($start_itime =~ /\d{4}-(\d{2})-\d{2}/); +$month = sprintf('%.2d',$month); +my $year = $1 if($start_itime =~ /(\d{4})-\d{2}-\d{2}/); + + +my $channel_map = $dbt->channel_map(); +my $channel = "ALL"; +foreach my $id (keys (%$channel_map)){ + $channel = $channel_map->{$id} if($id eq $owner); +} + +my $new_reg=0; +my $swk_reg=0; +my $swk_i=0; + +#collect new users in time-range +my $adr_search = { + table => "contentadr", + fetch => "all", + keyfield => "c_id", + int09 => "is::null", #not Service App staff + }; +$adr_search = { %$adr_search , owner => $owner } if($owner && $owner =~ /^\d+$/); +$adr_search = { %$adr_search , start_itime => ">=::$start_itime" } if($start_itime); +$adr_search = { %$adr_search , end_itime => "<::$end_itime" } if($end_itime); +my $adr = $dbt->fetch_tablerecord($dbh,$adr_search); + + +foreach my $id (sort { $adr->{$a}->{itime} cmp $adr->{$b}->{itime} }keys (%$adr)){ + #mailAck && smsAck + if($adr->{$id}->{int04} && $adr->{$id}->{int04} == 1 && $adr->{$id}->{int13} && $adr->{$id}->{int13} == 1){ + + $new_reg++; + + #New SWK Bonus registrations + if($adr->{$id}->{txt15} && $adr->{$id}->{txt15} =~ /\d+/){ + $swk_reg++; + } + } +} + + #fetch all stations + my $pref = { + table => "content", + fetch => "all", + keyfield => "int04", + main_id => "=::300016", + template_id => "225", + int04 => "!=::99",#virtual station + int10 => "1", #available + txt01 => "not ilike::%Contributor%", + }; + my $station_rec = $dbt->fetch_record($dbh,$pref); + + +#Statistik-start_end_station +my $csv_start_station = Text::CSV_XS->new ({ binary => 1, sep_char => ";", eol => "\r\n" }); +my $filename_start_station = "Statistik-start_end_station_$year-$month-$flotte_type.csv"; +open my $sstation, ">", "$varenv{csv}/$filename_start_station" or die "$filename_start_station: $!\n"; +my @start_station = ("$year-$month Station","Menge Anmietungen/Rueckgaben"); +$csv_start_station->print($sstation, \@start_station);#$start_station CSV header + +#Statistik-channel_amount +my $csv_amount = Text::CSV_XS->new ({ binary => 1, sep_char => ";", eol => "\r\n" }); +my $filename_amount = "Statistik-channel_amount_$year-$month-$flotte_type.csv"; +open my $aamount, ">", "$varenv{csv}/$filename_amount" or die "$filename_amount: $!\n"; +my @amount = ("$year-$month $flotte_type","Menge"); +$csv_amount->print($aamount, \@amount);#$amount CSV header: + +#Statistik-Allnewuser_amount +my $csv_allamount = Text::CSV_XS->new ({ binary => 1, sep_char => ";", eol => "\r\n" }); +my $filename_allamount = "Statistik-Allnewuser_amount_$year-$month.csv"; +open my $allaamount, ">", "$varenv{csv}/$filename_allamount" or die "$filename_allamount: $!\n"; +my @allamount = ("$year-$month Gesamtanzahl Neuregistrierungen","Menge"); +$csv_allamount->print($allaamount, \@allamount);#$allamount CSV header: +$csv_allamount->print($allaamount, ["neue NutzerInnen","$new_reg"]); +print "Neue NutzerInnen: $new_reg\n"; + +#Statistik-Bonusnewuser_amount +my $csv_swkamount = Text::CSV_XS->new ({ binary => 1, sep_char => ";", eol => "\r\n" }); +my $filename_swkamount = "Statistik-Bonusnewuser_amount_$year-$month.csv"; +open my $swkaamount, ">", "$varenv{csv}/$filename_swkamount" or die "$filename_swkamount: $!\n"; +my @swkamount = ("$year-$month Gesamtanzahl Neuregistrierungen Bonusnummer","Menge"); +$csv_swkamount->print($swkaamount, \@swkamount);#$swkamount CSV header: +$csv_swkamount->print($swkaamount, ["neue NutzerInnen mit Bonus Tarif","$swk_reg"]); +print "Neue NutzerInnen mit Bonus Tarif: $swk_reg\n"; + + my $sum_minutes=0; + my $sum_hours=0; + my $pricing = {}; + my $counting = {}; + my $diff_station = 0; + + #station hash init + my $start_station = {}; + my $end_station = {}; + foreach my $int04_id (sort { $station_rec->{$a}->{int04} <=> $station_rec->{$b}->{int04} } keys (%$station_rec)){ + $start_station->{$int04_id} = 0; + $end_station->{$int04_id} = 0; + } + + my $pos_search = { + table => "contenttranspos", + fetch => "all", + keyfield => "c_id", + #int04 => "!=::99",#virtual end-station + int05 => "is::null",#not if sub workflow doc + int06 => "!=::99",#virtual start-station + int29 => "$bike_type_id",#nodes.type_id + int34 => "is::null",#not if staff + }; + $pos_search->{owner} = $owner if($owner && $owner =~ /^\d+$/); + $pos_search->{start_time} = ">=::$start_itime" if($start_itime); + $pos_search->{end_time} = "<::$end_itime" if($end_itime); + my $pos = $dbt->fetch_tablerecord($dbh,$pos_search); + + #Loop rental positions alias Mietjournal + foreach my $id (sort { $pos->{$a}->{mtime} cmp $pos->{$b}->{mtime} }keys (%$pos)){ + + ($pricing->{$id},my $counting) = $pri->counting_rental(\%varenv,$pos->{$id}); + + #umsatz by tarif-nr in int09 + if($pos->{$id}->{template_id} && $pos->{$id}->{template_id} == 205 && $pos->{$id}->{int09} && $pos->{$id}->{int35} && $pos->{$id}->{int10} == 1 && $pricing->{$id}->{rentalog}->{rental_minute_all} && $pricing->{$id}->{rentalog}->{rental_minute_all} > 0){ + + #if sharing type public-bonus = 5 + if($pos->{$id}->{int18} && $pos->{$id}->{int18} == 5){ + $swk_i++; + } + + if($pos->{$id}->{int06} && exists($start_station->{$pos->{$id}->{int06}})){ + $start_station->{$pos->{$id}->{int06}} += 1; + }elsif($pos->{$id}->{int04} && exists($start_station->{$pos->{$id}->{int04}})){ + $start_station->{$pos->{$id}->{int04}} += 1; + } + $end_station->{$pos->{$id}->{int04}} += 1 if($pos->{$id}->{int04} && exists($start_station->{$pos->{$id}->{int04}})); + $diff_station += 1 if($pos->{$id}->{int06} && $pos->{$id}->{int04} && $pos->{$id}->{int06} != $pos->{$id}->{int04}); + + $sum_minutes += $pricing->{$id}->{rentalog}->{rental_minute_all}; + } + }#end Loop rental + + #Service pos + my $pos_partref = { + table => "contenttranspos", + fetch => "all", + keyfield => "c_id", + int05 => "is::null",#not if sub workflow doc + start_itime => ">=::$start_itime", + end_itime => "<::$end_itime", + }; + my $pos_part = $dbt->fetch_tablerecord($dbh,$pos_partref); + + $sum_hours = $sum_minutes / 60 if($sum_minutes > 0); + $sum_hours = sprintf('%.2f',$sum_hours); + $sum_hours =~ s/\./,/; + $csv_amount->print($aamount, ["Gesamtnutzungsstunden im Gesamtsystem","$sum_hours"]); + print "Gesamtnutzungsstunden im Gesamtsystem: $sum_hours\n"; + + my $count_start = 0; + foreach my $stid (sort { $a <=> $b } (keys (%$start_station))){ + $count_start += $start_station->{$stid}; + my @start_station_line = ("start-Station $stid","$start_station->{$stid}"); + $csv_start_station->print($sstation, \@start_station_line);#foreach line + } + print "Count start_station: $count_start\n"; + + my $count_end = 0; + foreach my $stid (sort { $a <=> $b } (keys (%$end_station))){ + $count_end += $end_station->{$stid}; + my @end_station_line = ("end-Station $stid","$end_station->{$stid}"); + $csv_start_station->print($sstation, \@end_station_line);#foreach line + } + print "Count end_station: $count_end\n"; + + $csv_amount->print($aamount, ["APP Anmietungen","$count_start"]); + print "APP Anmietungen: $count_start\n"; + + $csv_amount->print($aamount, ["Gesamtanzahl Anmietungen im Gesamtsystem","$count_start"]); + print "Gesamtanzahl Anmietungen im Gesamtsystem: $count_start\n"; + + + $csv_amount->print($aamount, ["One-Way-Fahrten","$diff_station"]); + print "\nAnteil One-Way-Fahrten: $diff_station\n"; + + if($swk_i){ + $csv_amount->print($aamount, ["Anmietungen mit Bonusnummer","$swk_i"]); + print "Anmietungen mit Bonusnummer: $swk_i\n"; + } + + diff --git a/copri4/main/src/scripts/statistik_dailystation.pl b/copri4/main/src/scripts/statistik_dailystation.pl deleted file mode 120000 index b242789..0000000 --- a/copri4/main/src/scripts/statistik_dailystation.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/statistik_dailystation.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/statistik_dailystation.pl b/copri4/main/src/scripts/statistik_dailystation.pl new file mode 100755 index 0000000..ab3ba5b --- /dev/null +++ b/copri4/main/src/scripts/statistik_dailystation.pl @@ -0,0 +1,81 @@ +#!/usr/bin/perl +# +# SPDX-License-Identifier: AGPL-3.0-or-later +# Copyright (c) Rainer Gümpelein, TeilRad GmbH +# +#./src/scripts/statistik_dailystation.pl shareedms-operator" +# +# +use vars qw($syshost); + +BEGIN { + $syshost = $ARGV[0] || exit 1; +} + +use lib "/var/www/copri-bike/$syshost/src"; + +use strict; +use warnings; +use POSIX; +use CGI ':standard'; +use Lib::Config; +use Scalar::Util qw(looks_like_number); +use DateTime; +use DateTime::Format::Pg; +use Mod::DBtank; +use Data::Dumper; + +my $q = new CGI; +my $cf = new Config; +my $dbt = new DBtank; + +my $dbh = ""; +my $now_dt = strftime "%Y-%m-%d", localtime; + + my $pref_st = { + table => "content", + fetch => "all", + keyfield => "int04", + template_id => "225", + }; + my $ct4rel_st = $dbt->fetch_record($dbh,$pref_st); + + my $pref_bi = { + table => "content", + fetch => "all", + keyfield => "barcode", + template_id => "205", + }; + my $ct4rel = $dbt->fetch_record($dbh,$pref_bi); + +my $station_bikes = {}; + +#foreach station +foreach my $st (sort { $ct4rel_st->{$a}->{int04} <=> $ct4rel_st->{$b}->{int04} } keys (%$ct4rel_st)){ + $station_bikes->{$ct4rel_st->{$st}->{int04}}->{on}->{bikes} = ""; + $station_bikes->{$ct4rel_st->{$st}->{int04}}->{off}->{bikes} = ""; + + #foreach bike + foreach my $cpid (sort { $ct4rel->{$a}->{barcode} <=> $ct4rel->{$b}->{barcode} } keys (%$ct4rel)){ + if(($ct4rel->{$cpid}->{barcode} && $ct4rel->{$cpid}->{barcode} > 0) && ($ct4rel->{$cpid}->{int04} && $ct4rel_st->{$st}->{int04} == $ct4rel->{$cpid}->{int04})){ + + if($ct4rel->{$cpid}->{int10} && $ct4rel->{$cpid}->{int10} =~ /1|2|3/){ + $station_bikes->{$ct4rel_st->{$st}->{int04}}->{on}->{bikes} .= "$ct4rel->{$cpid}->{barcode},"; + }elsif($ct4rel->{$cpid}->{int10} && $ct4rel->{$cpid}->{int10} =~ /4|5/){ + $station_bikes->{$ct4rel_st->{$st}->{int04}}->{off}->{bikes} .= "$ct4rel->{$cpid}->{barcode},"; + } + + } + } + $station_bikes->{$ct4rel_st->{$st}->{int04}}->{on}->{bikes} =~ s/,$// if($station_bikes->{$ct4rel_st->{$st}->{int04}}->{on}->{bikes}); + $station_bikes->{$ct4rel_st->{$st}->{int04}}->{off}->{bikes} =~ s/,$// if($station_bikes->{$ct4rel_st->{$st}->{int04}}->{off}->{bikes}); + + print "Registered on station: $ct4rel_st->{$st}->{int04} --> bikes_on: $station_bikes->{$ct4rel_st->{$st}->{int04}}->{on}->{bikes} --> bikes_off: $station_bikes->{$ct4rel_st->{$st}->{int04}}->{off}->{bikes}\n"; + my $sethash = { + station => $ct4rel_st->{$st}->{int04}, + bikes_on => "$station_bikes->{$ct4rel_st->{$st}->{int04}}->{on}->{bikes}", + bikes_off => "$station_bikes->{$ct4rel_st->{$st}->{int04}}->{off}->{bikes}", + }; + $dbt->insert_contenthash($dbh,"statistik",$sethash); +} + diff --git a/copri4/main/src/scripts/statistik_monthlyCSV.pl b/copri4/main/src/scripts/statistik_monthlyCSV.pl deleted file mode 120000 index 52207b3..0000000 --- a/copri4/main/src/scripts/statistik_monthlyCSV.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/statistik_monthlyCSV.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/statistik_occubike_stationCSV.pl b/copri4/main/src/scripts/statistik_occubike_stationCSV.pl deleted file mode 120000 index 0bc24ae..0000000 --- a/copri4/main/src/scripts/statistik_occubike_stationCSV.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/statistik_occubike_stationCSV.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/statistik_occubike_stationCSV.pl b/copri4/main/src/scripts/statistik_occubike_stationCSV.pl new file mode 100755 index 0000000..546bc5a --- /dev/null +++ b/copri4/main/src/scripts/statistik_occubike_stationCSV.pl @@ -0,0 +1,279 @@ +#!/usr/bin/perl +# +## SPDX-License-Identifier: AGPL-3.0-or-later +# Copyright (c) Rainer Gümpelein, TeilRad GmbH +# +#csv/Statistik-average_bike_* +#csv/Statistik-occubike_station_* +#csv/Statistik-average_user_* +# +#Example citybike +#./src/scripts/statistik_occubike_stationCSV.pl shareedms-operator '2022-01-01' '2022-02-01' '300103' +# +#Example cargobike +#Without date defaults to duration of last 1 month up to now +#./src/scripts/statistik_occubike_stationCSV.pl shareedms-operator '' '' '300101' +# +# +use vars qw($syshost); + +BEGIN { + $syshost = $ARGV[0] || exit 1; +} +use lib "/var/www/copri-bike/$syshost/src"; + +use strict; +use warnings; +use feature qw(say); +use POSIX; +use CGI ':standard'; +use Lib::Config; +use Scalar::Util qw(looks_like_number); +use DateTime; +use DateTime::Format::Pg; +use Text::CSV_XS; +use Mod::DBtank; +use Mod::Pricing; + +use Data::Dumper; + +my $q = new CGI; +my $cf = new Config; +my %varenv = $cf->envonline(); +my $dbt = new DBtank; +my $pri = new Pricing; + +my $dbh = $dbt->dbconnect(); + +my $start_itime = ""; +my $end_itime = ""; +my $filename = ""; + +#If NO date on command then now +my $dt1 = DateTime->now(time_zone => 'Europe/Berlin'); +if($ARGV[2] && $ARGV[2] =~ /(\d{4})-(\d{2})-(\d{2})/){ + $end_itime = DateTime->new( + year => $1, + month => $2, + day => $3, + time_zone => 'Europe/Berlin', + ); +}else{ + $end_itime = $dt1; +} + +if($ARGV[1] && $ARGV[1] =~ /(\d{4})-(\d{2})-(\d{2})/){ + $start_itime = DateTime->new( + year => $1, + month => $2, + day => $3, + time_zone => 'Europe/Berlin', + ); +}else{ + $start_itime = $end_itime->clone->add(months => -1, end_of_month => 'preserve'); +} + +#2022-08-03 changed $bikesys int12 select to $bike_type_id int29 +my $bike_type_id = $ARGV[3] || ""; +my $flotte = ""; +if($bike_type_id == 300101){ + $flotte = "Lastenrad"; +}elsif($bike_type_id == 300103){ + $flotte = "Stadtrad"; +}else{ + print "Failure, bike_type_id must be nodes.type_id number of Flot\n\n"; + exit 1; +} + +my $month = $start_itime->month; +$month = sprintf('%.2d',$month); +my $year = $start_itime->year; + +my $sendref = { + mail_from => "", + mail_to => "ragu\@gnu-systems.de", + subject => "$syshost $bike_type_id statistik_occubike_stationCSV $year-$month", + message => "", + }; + + +$sendref->{message} .= "\nCSV Generation and debugging\n$syshost $bike_type_id $flotte Statistik occupied bike on station $start_itime - $end_itime\n"; +$sendref->{message} .= "CSV Attachemnt will be sent by loop_statistik_monthly.pl after CSV generation to get it\n\n"; + +my $month_days = DateTime->last_day_of_month( + year => $year, + month => $month, +); +my $days = $1 if($month_days =~ /\d{4}-\d{2}-(\d{2})/); +$sendref->{message} .= "occubike on station\n"; + + #fetch stations + my $pref = { + table => "content", + fetch => "all", + keyfield => "int04", + main_id => "=::300016", + template_id => "225", + int04 => "!=::99", + int10 => 1, #available + txt01 => "not ilike::%Contributor%", + }; + my $station_rec = $dbt->fetch_record($dbh,$pref); + + #fetch all bikes + my $pref_b = { + table => "content", + fetch => "all", + keyfield => "barcode", + barcode => ">::0", + template_id => "205", + }; + my $bikes_rec = $dbt->fetch_record($dbh,$pref_b); + my $bike_stat = {}; + my $adr_stat = {}; + + + #fetch contenttranspos + my $pos_search = { + table => "contenttranspos", + fetch => "all", + keyfield => "c_id", + #int04 => "!=::99",#virtuel end-station + int05 => "is::null",#not if sub workflow doc + int06 => "!=::99",#virtuel start-station + int29 => "$bike_type_id",#nodes.type_id + int34 => "is::null",#not if staff + }; + $pos_search->{start_time} = ">=::$start_itime" if($start_itime); + $pos_search->{end_time} = "<::$end_itime" if($end_itime); + my $pos = $dbt->fetch_tablerecord($dbh,$pos_search); + + #print "fetching bookings: Start >= $start_itime End < $end_itime\n"; + +my @stations = ("$year-$month Mietmenge Rad/Station"); +foreach my $int04_id (sort { $station_rec->{$a}->{int04} <=> $station_rec->{$b}->{int04} } keys (%$station_rec)){ + push(@stations,$station_rec->{$int04_id}->{int04}); +} + +#Statistik-occubike_station +my $csv = Text::CSV_XS->new ({ binary => 1, sep_char => ";", eol => "\r\n" }); +my $filename_fhda = "Statistik-occubike_station_$year-$month-$flotte.csv"; +open my $fhda, ">", "$varenv{csv}/$filename_fhda" or die "$filename_fhda: $!\n"; +$csv->print($fhda, \@stations);#Stations CSV header + +#Statistik-average_bike +my $csv_average_bike = Text::CSV_XS->new ({ binary => 1, sep_char => ";", eol => "\r\n" }); +my $filename_average_bike = "Statistik-average_bike_$year-$month-$flotte.csv"; +open my $abike, ">", "$varenv{csv}/$filename_average_bike" or die "$filename_average_bike: $!\n"; +my @average_bike = ("$year-$month Nutzung/Rad","Anzahl","Gesamt Std","Durchschnitt Std","Gesamt KM","Durchschnitt KM"); +$csv_average_bike->print($abike, \@average_bike);#$average_bike CSV header + +#Statistik-average_user +my $csv_average_user = Text::CSV_XS->new ({ binary => 1, sep_char => ";", eol => "\r\n" }); +my $filename_average_user = "Statistik-average_user_$year-$month-$flotte.csv"; +open my $auser, ">", "$varenv{csv}/$filename_average_user" or die "$filename_average_user: $!\n"; +my @average_user = ("$year-$month Nutzung/Nutzer","Anzahl","Gesamt Std","Durchschnitt Std"); +$csv_average_user->print($auser, \@average_user);#$average_user CSV header + + +if(1==1){ + my $pricing = {}; + my $rental = {}; + #loop bookings + foreach my $c_id (sort { $pos->{$a}->{barcode} <=> $pos->{$b}->{barcode} } keys (%$pos)){ + ($pricing->{$c_id},my $counting) = $pri->counting_rental(\%varenv,$pos->{$c_id}); + + if($pos->{$c_id}->{int10} == 1 && $pricing->{$c_id}->{rentalog}->{rental_minute_all} && $pricing->{$c_id}->{rentalog}->{rental_minute_all} > 0){ + #print "$pos->{$c_id}->{barcode} --> rental_minute_all: $pricing->{$c_id}->{rentalog}->{rental_minute_all}\n"; + + if($pos->{$c_id}->{ca_id}){ + + #if($adr_one->{c_id}){ + if(1==1){ + $adr_stat->{$pos->{$c_id}->{ca_id}}->{c_id} = $pos->{$c_id}->{ca_id}; + $adr_stat->{$pos->{$c_id}->{ca_id}}->{counter}++; + $adr_stat->{$pos->{$c_id}->{ca_id}}->{minutes} += $pricing->{$c_id}->{rentalog}->{rental_minute_all}; + $adr_stat->{$pos->{$c_id}->{ca_id}}->{hours} = $adr_stat->{$pos->{$c_id}->{ca_id}}->{minutes} / 60 if($adr_stat->{$pos->{$c_id}->{ca_id}}->{minutes}); + + + $bike_stat->{$pos->{$c_id}->{barcode}}->{counter}++; + $bike_stat->{$pos->{$c_id}->{barcode}}->{minutes} += $pricing->{$c_id}->{rentalog}->{rental_minute_all}; + $bike_stat->{$pos->{$c_id}->{barcode}}->{hours} = $bike_stat->{$pos->{$c_id}->{barcode}}->{minutes} / 60 if($bike_stat->{$pos->{$c_id}->{barcode}}->{minutes}); + $bike_stat->{$pos->{$c_id}->{barcode}}->{km} += $pos->{$c_id}->{int26} if($pos->{$c_id}->{int26}); + + foreach my $int04_id (sort { $station_rec->{$a}->{int04} <=> $station_rec->{$b}->{int04} } keys (%$station_rec)){ + + if(($pos->{$c_id}->{int06} && $station_rec->{$int04_id}->{int04}) && ($pos->{$c_id}->{int06} == $station_rec->{$int04_id}->{int04})){ + $rental->{$pos->{$c_id}->{barcode}}->{$station_rec->{$int04_id}->{int04}}++;#counter + } + } + } + } + + } + } + #print Dumper($rental) . "\n"; + + #Durchschnittliche Gesamtnutzungsdauer pro NutzerIn"; + foreach my $a_id (sort { $adr_stat->{$a}->{c_id} <=> $adr_stat->{$b}->{c_id} } keys(%$adr_stat)){ + if($adr_stat->{$a_id}->{hours} > 0 && $adr_stat->{$a_id}->{counter} > 0){ + my $hours = sprintf('%.2f',$adr_stat->{$a_id}->{hours}); + my $average = sprintf('%.2f',$hours / $adr_stat->{$a_id}->{counter}); + $hours =~ s/\./,/; + $average =~ s/\./,/; + + my @average_user_line = ("Nutzer ID:$adr_stat->{$a_id}->{c_id}","$adr_stat->{$a_id}->{counter}","$hours","$average"); + $csv_average_user->print($auser, \@average_user_line);#foreach user one line + + $sendref->{message} .= "Nutzer ID:$adr_stat->{$a_id}->{c_id}, $hours Std / $adr_stat->{$a_id}->{counter} Menge = $average Std im Durchschnitt\n"; + } + } + + + #Generate bike/station CSV-lines + foreach my $b_id (sort { $bikes_rec->{$a}->{barcode} <=> $bikes_rec->{$b}->{barcode} } keys(%$bikes_rec)){ + if($bikes_rec->{$b_id}->{type_id} == $bike_type_id && $bikes_rec->{$b_id}->{node_name} !~ /Contributor/i){ + + #Durchschnittliche Nutzungsdauer pro Rad + my $km = $bike_stat->{$b_id}->{km} || 0; + my $km_average = 0; + my $hours = $bike_stat->{$b_id}->{hours} || 0; + my $counter = $bike_stat->{$b_id}->{counter} || 0; + my $average = 0; + if($hours > 0){ + $hours = sprintf('%.2f',$bike_stat->{$b_id}->{hours}); + $average = sprintf('%.2f',$hours / $counter); + $hours =~ s/\./,/; + $average =~ s/\./,/; + } + if($km > 0){ + $km = sprintf('%.2f',$bike_stat->{$b_id}->{km}); + $km_average = sprintf('%.2f',$km / $counter); + $km =~ s/\./,/; + $km_average =~ s/\./,/; + } + + my @average_bike_line = ("$bikes_rec->{$b_id}->{txt01} Nr. $b_id","$counter","$hours","$average","$km","$km_average"); + $csv_average_bike->print($abike, \@average_bike_line);#foreach bike one line + + $sendref->{message} .= "$bikes_rec->{$b_id}->{txt01} Nr. $b_id, $hours Std / $counter Miete = $average Std im Durchschnitt\n"; + + my @bike_station_array = ("$bikes_rec->{$b_id}->{txt01}, Nr. $b_id"); + my $i = 0; + foreach my $int04_id (sort { $station_rec->{$a}->{int04} <=> $station_rec->{$b}->{int04} } keys (%$station_rec)){ + $i++; + if($rental->{$b_id}->{$int04_id}){ + #print "bike: $b_id, station: $int04_id --> count: $rental->{$b_id}->{$int04_id}\n"; + #print "-> Stations count: " . Dumper($rental->{$b_id}->{$int04_id}) . "\n"; + $bike_station_array[$i] = $rental->{$b_id}->{$int04_id} || 0;#Stations count + #print "--> Stations count: " . Dumper(\@bike_station_array) . "\n"; + } + } + $csv->print($fhda, \@bike_station_array);#foreach bike one line + } + } + + +}#end if + + diff --git a/copri4/main/src/scripts/statistik_occubike_stationCSV_innofact.pl b/copri4/main/src/scripts/statistik_occubike_stationCSV_innofact.pl deleted file mode 120000 index 3bb2cec..0000000 --- a/copri4/main/src/scripts/statistik_occubike_stationCSV_innofact.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/statistik_occubike_stationCSV_innofact.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/statistik_userevaluation.pl b/copri4/main/src/scripts/statistik_userevaluation.pl deleted file mode 120000 index 42ec946..0000000 --- a/copri4/main/src/scripts/statistik_userevaluation.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/statistik_userevaluation.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/statistik_userevaluation.pl b/copri4/main/src/scripts/statistik_userevaluation.pl new file mode 100755 index 0000000..c7f860b --- /dev/null +++ b/copri4/main/src/scripts/statistik_userevaluation.pl @@ -0,0 +1,117 @@ +#!/usr/bin/perl +# +# SPDX-License-Identifier: AGPL-3.0-or-later +# Copyright (c) Rainer Gümpelein, TeilRad GmbH +# +#with date range +#./src/scripts/statistik_userevaluation.pl shareedms-operator '2022-01-01' '2022-02-01' +# +#Without date defaults to duration of last 1 month up to now +#./src/scripts/statistik_userevaluation.pl shareedms-operator '' '' +# +# +use vars qw($syshost); + +BEGIN { + $syshost = $ARGV[0] || exit 1; +} +use lib "/var/www/copri-bike/$syshost/src"; + +use strict; +#use warnings; +use feature qw(say); +use POSIX; +use CGI ':standard'; +use Lib::Config; +use Scalar::Util qw(looks_like_number); +use DateTime; +use DateTime::Format::Pg; +use Text::CSV_XS; +use Mod::Libenz; +use Mod::DBtank; + +use Data::Dumper; + +my $q = new CGI; +my $cf = new Config; +my $lb = new Libenz; +my $dbt = new DBtank; +my %varenv = $cf->envonline(); + +my $dbh = $dbt->dbconnect(); + +my $start_itime = ""; +my $end_itime = ""; +my $filename = ""; + +#If NO date on command then now +my $dt1 = DateTime->now(time_zone => 'Europe/Berlin'); +if($ARGV[2] && $ARGV[2] =~ /(\d{4})-(\d{2})-(\d{2})/){ + $end_itime = DateTime->new( + year => $1, + month => $2, + day => $3, + time_zone => 'Europe/Berlin', + ); +}else{ + $end_itime = $dt1; +} + +if($ARGV[1] && $ARGV[1] =~ /(\d{4})-(\d{2})-(\d{2})/){ + $start_itime = DateTime->new( + year => $1, + month => $2, + day => $3, + time_zone => 'Europe/Berlin', + ); +}else{ + $start_itime = $end_itime->clone->add(months => -1, end_of_month => 'preserve'); +} + +my $month = $start_itime->month; +$month = sprintf('%.2d',$month); +my $year = $start_itime->year; + +my $month_days = DateTime->last_day_of_month( + year => $year, + month => $month, +); +my $days = $1 if($month_days =~ /\d{4}-\d{2}-(\d{2})/); + + #fetch contentadrpos + my $pref_adr = { + table => "contentadrpos", + fetch => "all", + keyfield => "c_id", + template_id => 602,#evaluation template_id + txt10 => "IN::('MAK','SX','CAD','LEC')",#operators + start_mtime => ">=::$start_itime", + end_mtime => "<=::$end_itime", + }; + my $adr_rec = $dbt->fetch_tablerecord($dbh,$pref_adr); + +my $csv_minianswer = Text::CSV_XS->new ({ binary => 1, sep_char => ";", eol => "\r\n" }); +my $filename_minianswer = "Statistik-LastenradBayern-evaluation_$year-$month.csv"; +open my $auser, ">", "$varenv{csv}/$filename_minianswer" or die "$filename_minianswer: $!\n"; +my @minianswer = ("$year-$month ID","Zeitstempel","Operator","Antwort zu 1.","Antwort zu 2.","Antwort zu 3.","KM"); +$csv_minianswer->print($auser, \@minianswer);#CSV header + + +if(1==1){ + + foreach my $a_id (sort { $adr_rec->{$a}->{c_id} <=> $adr_rec->{$b}->{c_id} } keys(%$adr_rec)){ + #if($adr_rec->{$a_id}->{txt01} || $adr_rec->{$a_id}->{txt02} || $adr_rec->{$a_id}->{txt03}){ + my $mtime = $lb->time4de($adr_rec->{$a_id}->{mtime},"",""); + my @minianswer_line = ("$adr_rec->{$a_id}->{c_id}","$mtime","$adr_rec->{$a_id}->{txt10}","$adr_rec->{$a_id}->{txt01}","$adr_rec->{$a_id}->{txt02}","$adr_rec->{$a_id}->{txt03}","$adr_rec->{$a_id}->{int02}"); + print "\n"; + foreach (@minianswer_line){ + print $_ . ";"; + } + print "\n"; + $csv_minianswer->print($auser, \@minianswer_line);#foreach one line + + #} + } +} + + diff --git a/copri4/main/src/scripts/statistik_zip_transport.pl b/copri4/main/src/scripts/statistik_zip_transport.pl deleted file mode 120000 index f272ecd..0000000 --- a/copri4/main/src/scripts/statistik_zip_transport.pl +++ /dev/null @@ -1 +0,0 @@ -../../../../../sharee.bike/copri-bike/main/src/scripts/statistik_zip_transport.pl \ No newline at end of file diff --git a/copri4/main/src/scripts/statistik_zip_transport.pl b/copri4/main/src/scripts/statistik_zip_transport.pl new file mode 100755 index 0000000..f51640a --- /dev/null +++ b/copri4/main/src/scripts/statistik_zip_transport.pl @@ -0,0 +1,63 @@ +#!/usr/bin/perl +# +# SPDX-License-Identifier: AGPL-3.0-or-later +# Copyright (c) Rainer Gümpelein, TeilRad GmbH +# +#Just CSV attachment zipping +# + +#with start_time and end_time +#./src/scripts/statistik_zip_transport.pl shareedms-operator '2022-01-01' '2022-02-01' +# +#defaults now() +#./src/scripts/statistik_zip_transport.pl shareedms-operator +# +use vars qw($syshost); + +BEGIN { + $syshost = $ARGV[0] || exit 1; +} + +use lib "/var/www/copri-bike/$syshost/src"; + +my $start_itime = $ARGV[1] || ""; +my $end_itime = $ARGV[2] || ""; + +use strict; +use warnings; +use utf8; +use POSIX; +use CGI ':standard'; +use Lib::Config; +use Scalar::Util qw(looks_like_number); +use DateTime; +use DateTime::Format::Pg; +use Sys::Hostname; +my $hostname = hostname; + +use Data::Dumper; + +my $q = new CGI; +my $cf = new Config; +my %varenv = $cf->envonline(); + +my $dt1 = DateTime->now(time_zone => 'Europe/Berlin'); +if(!$end_itime){ + $end_itime = $dt1; +} + +if(!$start_itime){ + $start_itime = $dt1->clone->add(months => -1, end_of_month => 'preserve'); +} + +my $month = $1 if($start_itime =~ /\d{4}-(\d{2})-\d{2}/); +$month = sprintf('%.2d',$month); +my $year = $1 if($start_itime =~ /(\d{4})-\d{2}-\d{2}/); +my $filename = "Statistik_$year-$month.zip"; + +#zip it +`cd $varenv{csv} && rm -f $filename && /usr/bin/zip $filename *$year-$month*.csv && sync`; + +#`$varenv{basedir}/src/scripts/ftpSWKstatistik.pl $filename`; + + diff --git a/copri4/main/src/scripts/velofaktur_client.pl b/copri4/main/src/scripts/velofaktur_client.pl index 67cb848..dea9422 100755 --- a/copri4/main/src/scripts/velofaktur_client.pl +++ b/copri4/main/src/scripts/velofaktur_client.pl @@ -5,13 +5,14 @@ # # velofaktur per REST JSON Payload with Bearer Token # +#Examples # Abrufen einer Liste mit Stationen, Anzahl Slots + Name -# sudo su www-data -c "./src/scripts/velofaktur_client.pl shareedms-fr01 get_velo" +# ./src/scripts/velofaktur_client.pl shareedms-operator get_velo # # bike ID Statusabfrage | Freigeben -# sudo su www-data -c "./src/scripts/velofaktur_client.pl shareedms-fr01 post_velo 8 1 200008 Statusabfrage" +# ./src/scripts/velofaktur_client.pl shareedms-operator post_velo 8 1 200008 Statusabfrage # will be sent by booking_update $lock_state eq "unlocked" -# sudo su www-data -c "./src/scripts/velofaktur_client.pl shareedms-fr01 post_velo 8 1 200008 Freigeben "$record_pos->{c_id}"" +# ./src/scripts/velofaktur_client.pl shareedms-operator post_velo 8 1 200008 Freigeben "$record_pos->{c_id}" # use vars qw($syshost); diff --git a/copri4/mkaccess.sh b/copri4/mkaccess.sh index cef0335..91c9715 100755 --- a/copri4/mkaccess.sh +++ b/copri4/mkaccess.sh @@ -4,8 +4,18 @@ # SPDX-License-Identifier: AGPL-3.0-or-later # Copyright (c) Rainer Gümpelein, TeilRad GmbH -echo "YOur working directory:"; +echo "YOur working directory:" pwd + +echo "Creating some empty directories:" +mkdir -vp shareedms-operator/cache +mkdir -vp shareedms-operator/csv +mkdir -vp shareedms-operator/data +mkdir -vp shareedms-operator/json +mkdir -vp shareedms-operator/pdf +mkdir -vp shareedms-operator/site +mkdir -vp shareedms-operator/xml + echo "Set up file access rights. Please also check if it meets your needs" chgrp -R www-data * diff --git a/copri4/shareeapp-operator/apache/shareeapp-operator.conf b/copri4/shareeapp-operator/apache/shareeapp-operator.conf index b29b3f0..bb0cb9a 100644 --- a/copri4/shareeapp-operator/apache/shareeapp-operator.conf +++ b/copri4/shareeapp-operator/apache/shareeapp-operator.conf @@ -30,6 +30,12 @@ Header set Access-Control-Allow-Origin "example.tld" + + Options -Indexes +FollowSymLinks -ExecCGI + Order allow,deny + Allow from all + + Options -Indexes +FollowSymLinks -ExecCGI Order allow,deny @@ -77,6 +83,12 @@ PerlResponseHandler Mod::APIjsonserver + + SetHandler perl-script + PerlInitHandler Apache2::Reload + PerlResponseHandler Mod::GBFSout + + SetHandler perl-script PerlInitHandler Apache2::Reload @@ -87,7 +99,7 @@ RewriteEngine On RedirectMatch ^/$ /app/Anmelden SSLProxyEngine On - RewriteCond %{REQUEST_URI} ^/(site|img|data|css|js|jquery) + RewriteCond %{REQUEST_URI} ^/(site|img|data|css|js) RewriteRule ^(.*)$ https://shareeapp-operator1.example.tld/$1 [P,L] diff --git a/copri4/shareeapp-operator/cache b/copri4/shareeapp-operator/cache new file mode 120000 index 0000000..f67d287 --- /dev/null +++ b/copri4/shareeapp-operator/cache @@ -0,0 +1 @@ +../shareedms-operator/cache \ No newline at end of file diff --git a/copri4/shareeapp-operator/src/Tpl/FormEdit.pm b/copri4/shareeapp-operator/src/Tpl/FormEdit.pm index 02a0f4c..78e1040 100755 --- a/copri4/shareeapp-operator/src/Tpl/FormEdit.pm +++ b/copri4/shareeapp-operator/src/Tpl/FormEdit.pm @@ -97,7 +97,7 @@ Weitere Personen aus Ihrem Haushalt profitieren jedoch ebenfalls, falls Sie weit $ctrel = $users_sharee if(ref($users_sharee) eq "HASH" && $users_sharee->{c_id}); # #collect rentals on operators and get operator hash with dbname->uri_operator - $q->param(-name=>'month',-value=>"1"); + #$q->param(-name=>'month',-value=>"1"); my ($cttpos,$operator_hash) = $apif->user_rentals_history($q,$ctrel); #print Dumper($cttpos); @@ -344,7 +344,7 @@ Nach Abschluss der Registrierung erhalten Sie sowohl auf die von Ihnen hinterleg }elsif($key =~ /barcode/){ if($cttpos_count){ - print $q->div({-style=>'padding-top:1.5em;font-weight:bold;'},"Folgende Positionen liegen zur nächsten Abbuchung vor (max. 1 Monat)"),"\n"; + print $q->div({-style=>'padding-top:1.5em;font-weight:bold;'},"Folgende Positionen liegen zur nächsten Abbuchung vor"),"\n"; my @tpl_posorder = ("txt01=Beschreibung","int04=Station","ct_name=(Rad) Nummer","int26=CO2","int02=Betrag"); diff --git a/copri4/shareeconf/examples/global.cfg b/copri4/shareeconf/examples/global.cfg index 4c0c636..ed68e00 100755 --- a/copri4/shareeconf/examples/global.cfg +++ b/copri4/shareeconf/examples/global.cfg @@ -195,8 +195,8 @@ logdir = "/var/log/copri4" basedir = "/var/www/copri4" - 300101 = "Lastenrad" - 300103 = "Stadtrad" + 300101 = "cargo" + 300103 = "city" 2 = "public" diff --git a/copri4/shareeconf/examples/sharee_operator.sql.gz b/copri4/shareeconf/examples/sharee_operator.sql.gz index c513e3ef9c609bf42c2f80ec0a16cd0d1177f808..988b337f136edb8f34f4720461864550fbaac63f 100755 GIT binary patch literal 15579 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 literal 16199 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 h8R?!#^e>|{x^;|7KirQ - Options +Indexes +FollowSymLinks -ExecCGI + Options -Indexes +FollowSymLinks -ExecCGI + Order allow,deny + Allow from all + + + + Options -Indexes +FollowSymLinks -ExecCGI Order allow,deny Allow from all @@ -59,7 +65,6 @@ ServerAdmin admin@example.tld DocumentRoot /var/www/copri4/shareedms-operator - PerlOptions +Parent PerlRequire /var/www/copri4/shareedms-operator/startup.pl diff --git a/copri4/shareedms-operator/pdf/pdfinvoice b/copri4/shareedms-operator/pdf/pdfinvoice new file mode 120000 index 0000000..576566b --- /dev/null +++ b/copri4/shareedms-operator/pdf/pdfinvoice @@ -0,0 +1 @@ +pdfinvoice \ No newline at end of file diff --git a/copri4/shareeweb-project/apache/shareeweb-operator.conf b/copri4/shareeweb-project/apache/shareeweb-operator.conf index ac597aa..ce81716 100644 --- a/copri4/shareeweb-project/apache/shareeweb-operator.conf +++ b/copri4/shareeweb-project/apache/shareeweb-operator.conf @@ -2,7 +2,6 @@ ServerName shareeweb-project.example.tld ServerAlias shareeweb-project1.example.tld - ServerAdmin info@gnu-systems.de DocumentRoot /var/www/copri4/shareeweb-project ErrorLog /var/log/apache2/shareeweb-project-error.log @@ -18,7 +17,6 @@ ServerName shareeweb-project1.example.tld - ServerAdmin info@gnu-systems.de DocumentRoot /var/www/copri4/shareeweb-project AddHandler cgi-script .cgi .sh .pl @@ -57,7 +55,6 @@ ServerName shareeweb-project.example.tld - ServerAdmin info@gnu-systems.de DocumentRoot /var/www/copri4/shareeweb-project PerlOptions +Parent @@ -95,7 +92,7 @@ RewriteEngine On RedirectMatch ^/$ /frame/Karte SSLProxyEngine On - RewriteCond %{REQUEST_URI} ^/(site|img|data|css|js|jquery) + RewriteCond %{REQUEST_URI} ^/(site|img|data|css|js) RewriteRule ^(.*)$ https://shareeweb-project1.example.tld/$1 [P,L] diff --git a/copri4/shareeweb-project/cache b/copri4/shareeweb-project/cache new file mode 120000 index 0000000..f67d287 --- /dev/null +++ b/copri4/shareeweb-project/cache @@ -0,0 +1 @@ +../shareedms-operator/cache \ No newline at end of file