sharee.bike/copri4/main/src/scripts/statistik_occubike_stationCSV.pl

281 lines
10 KiB
Perl
Executable file

#!/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
int09 => "is::null", #not Contributor-Archive
};
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",
archive => "is::null", #not Contributor-bikes
};
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
start_itime => ">=::$start_itime",
end_itime => "<::$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){
#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