sharee.bike/copri4/main/src/Mod/Pricing.pm
2022-01-09 18:31:20 +01:00

272 lines
9.6 KiB
Perl
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package Pricing;
#
# SPDX-License-Identifier: AGPL-3.0-or-later
# Copyright (c) Rainer Gümpelein, TeilRad GmbH
#
use strict;
use warnings;
use POSIX;
use CGI; # only for debugging
use Scalar::Util qw(looks_like_number);
use Lib::Config;
use Mod::Libenz;
use Mod::DBtank;
use Mod::Callib;
use Mod::Basework;
use Data::Dumper;
my $cf = new Config;
my $lb = new Libenz;
my $dbt = new DBtank;
my $cal = new Callib;
my $bw = new Basework;
sub new {
my $class = shift;
my $self = {};
bless($self,$class);
return $self;
}
my $dbh = "";
sub only_first_free(){
my $self = shift;
my $ctpos = shift;
my %varenv = $cf->envonline();
my $pref = {
table => "contenttrans",
table_pos => "contenttranspos",
fetch => "one",
template_id => "218",#Faktura tpl_id
ca_id => "=::$ctpos->{ca_id}",
c_id => "!=::$ctpos->{c_id}",
#txt10 => "IN::('available','canceled')",
int10 => "IN::('1','6')",
"ct.close_time" => "is::null",
};
$pref = { %$pref, time_range => "start_time >= '$ctpos->{start_time}' and start_time < '$ctpos->{end_time}' and start_time != end_time" };
my $record = $dbt->collect_post($dbh,$pref);
return $record;
}
sub sharee_pricing(){
my $self = shift;
my $ctpos = shift;
my $todo = shift;
my %varenv = $cf->envonline();
my $today4db = strftime("%Y-%m-%d %H:%M:%S",localtime(time));
my $return = {};
my $logging = {};
$logging->{ID} = "c_id:$ctpos->{c_id}/ct_id:$ctpos->{ct_id}/ca_id:$ctpos->{ca_id}";
my $computed_end_time = $ctpos->{end_time} || $today4db;
$computed_end_time = $today4db if($ctpos->{int10} && $ctpos->{int10} == 3);
my ($start_datetime,$end_datetime,$s_up,$e_up,$hours) = $cal->contenttranspos_dating($ctpos->{c_id},$ctpos->{start_time},"$computed_end_time","$today4db","");
$logging->{hours_input} = $hours;
$logging->{tariff} = "$ctpos->{txt04} - $ctpos->{int09}";
;
my $bike_group = "$dbt->{operator}->{$varenv{dbname}}->{oprefix}$ctpos->{int12}" || "";
my $days_pricemax = $ctpos->{int17} || 9;
$logging->{days_pricemax} = $days_pricemax;
my $price = 2; #FIXME to real val. must be not 0
$price = sprintf('%.2f',$ctpos->{int02}) if($ctpos->{int02} && $ctpos->{int02} > 0);
my $total = 0;
#my $days_pricemax = "4.5";#TINK max 9,- € bike/day depends on 2,- €/hour
#my $days_pricemax = 5; #KonRad max 15,- € bike/day depends on 3,- €/hour
my $days_hour4price = $days_pricemax / $price;
$logging->{days_hour4price} = $days_hour4price;
my $real_hours = $hours;
if($ctpos->{int16} && $ctpos->{int16} > 0){#z.b. 30 Min/Gratis --> 0.5
my $ctpos_freed = $self->only_first_free($ctpos);
#Bsp 1h = 60min , 60*0,02 = 1,2min
if(!$ctpos_freed->{c_id} || $real_hours <= 0.02){
$hours -= $ctpos->{int16};
$logging->{hours_freed} = $hours;
}else{
$logging->{hours_freed} = "Not freed because of (!$ctpos_freed->{c_id} && $ctpos->{int16} || $real_hours <= 0.02)";
}
}
#If available then take saved hours
if($ctpos->{int10} && $ctpos->{int10} == 1 && $todo eq "readonly"){
if($ctpos->{int03} && $ctpos->{int03} > 0){
$hours = $ctpos->{int03};
$total = $hours * $price if(looks_like_number($hours) && looks_like_number($price));
}else{
$hours = 0;
$total = 0;
}
}
#jede angebrochene Std.
elsif(looks_like_number($hours) && $hours > 0){
if($days_hour4price > 0 && $hours >= $days_hour4price && $hours <= 24){
$logging->{_hours_lower24} = "$days_hour4price > 0 && $hours >= $days_hour4price && $hours <= 24";
$logging->{__hours_lower24} = $hours;
$hours = $days_hour4price;
$logging->{hours_lower24} = $hours;
}
elsif($days_hour4price > 0 && $hours >= 24){
$logging->{hours_greate24} = "$days_hour4price > 0 && $hours >= 24";
my $days = $hours / 24;
my $days_int = $days;
my $dez = 0;
($days_int,$dez) = split(/\./, $days) if($days =~ /\.\d/);
my $days_hour = $days_int * 24;
my $rest = $hours - $days_hour;
$rest = $days_hour4price if($rest > $days_hour4price);
$hours = ($days_int * $days_hour4price) + $rest;
$logging->{hours_compute} = "$hours = ($days_int * $days_hour4price) + $rest";
}
$logging->{hours_preround} = $hours;
$hours = $lb->round_half($hours);
$logging->{hours_postround} = $hours;
$total = $hours * $price if(looks_like_number($hours) && looks_like_number($price));
}else{
$hours = 0;
}
$total = sprintf('%.2f', $total);
#Bsp 1h = 60min , 60*0,02 = 1,2min
$hours = "0" if($real_hours <= 0.02);
$return->{real_hours} = "$real_hours";
$return->{computed_hours} = "$hours";
$return->{unit_price} = "$price";
$return->{total_price} = "$total";
$return->{bike_group} = ["$bike_group"];
$return->{station} = "$dbt->{operator}->{$varenv{dbname}}->{oprefix}$ctpos->{int04}";#TODO save with prefix
$return->{uri_operator} = "$varenv{wwwhost}";#TODO, should be DB select
$return->{bike} = "$dbt->{operator}->{$varenv{dbname}}->{oprefix}$ctpos->{barcode}";
$return->{state} = "$dbt->{copri_conf}->{bike_state}->{$ctpos->{int10}}" || "";
$return->{bike_charge} = "$ctpos->{int19}" if($ctpos->{int19});
$return->{description} = "$ctpos->{txt01}";
$return->{request_time} = "$ctpos->{itime}";
$return->{start_time} = "$ctpos->{start_time}";
$return->{end_time} = "$computed_end_time";
$return->{system} = "Ilockit" || "";#FIXME
if($ctpos->{int11} eq "2"){
#$return->{gps} = "$ctpos->{txt06}";#end_gps
($return->{gps}->{latitude},$return->{gps}->{longitude}) = split(/,/,$ctpos->{txt06});
#if($ctpos->{txt10} =~ /requested|occupied/)
if($ctpos->{int10} == 2 || $ctpos->{int10} == 3){
$return->{tariff_description}->{name} = "$ctpos->{txt04}";
$return->{tariff_description}->{number} = "$ctpos->{int09}";
$return->{tariff_description}->{eur_per_hour} = "$ctpos->{int02}" || "0";
$return->{tariff_description}->{max_eur_per_day} = "$ctpos->{int17}" || "0";
$return->{tariff_description}->{free_hours} = "$ctpos->{int16}" if($ctpos->{int16} && $ctpos->{int16} > 0);
$return->{tariff_description}->{abo_eur_per_month} = "$ctpos->{int15}" if($ctpos->{int15} && $ctpos->{int15} > 0);
$return->{tariff_description}->{track_info} = "Ich stimme der Speicherung (Tracking) meiner Fahrstrecke zwecks wissenschaftlicher Auswertung und Berechnung der CO2-Einsparung zu!" if($ctpos->{int25});
$return->{tariff_description}->{operator_agb} = "Mit der Mietrad Anmietung wird folgender Betreiber <a href='$varenv{wwwhost}/site/agb.html' target='_blank'>AGB</a> zugestimmt (als Demo sharee AGB)." if($ctpos->{ca_id} == 1842 || $ctpos->{ca_id} == 5781);
$return->{Ilockit_GUID} = "$ctpos->{txt17}";
$return->{Ilockit_ID} = "$ctpos->{txt18}";
#$return->{gps} = "$ctpos->{txt06}";#start_gps
($return->{gps}->{latitude},$return->{gps}->{longitude}) = split(/,/,$ctpos->{txt06});
$return->{lock_state} = "locked" if($ctpos->{int20} == 1);
$return->{lock_state} = "unlocked" if($ctpos->{int20} == 2);
}
}
$bw->log("hour computed:",$logging,"");
return $return;
}
#CO2 calculator
#Bsp Berechnungen:
# Pkw:
# Distanz * CO2-Emission Pkw / 100 km
# 8.760 km * 20 kg CO2 / 100 km = 1.752 kg CO2
# Pedelec:
# Distanz * CO2-Emission Pedelec / 100 km
# 10.950 km * 0,546 kg CO2 / 100 km = 62 kg CO2
#
# Aus der Differenz zwischen der CO2-Emission Pkw und der CO2-Emission Pedelec ergibt sich das Einsparpotenzial:
# 1.752 kg CO2 62 kg CO2 = 1.690 kg CO2, also rund 1,7 t CO2 pro Jahr
#
sub co2calc {
my $self = shift;
my $ctpos = shift;
my $co2diff = 0;
my $co2pkw = $ctpos->{int26} * 20 / 100;
my $co2ped = $ctpos->{int26} * 0.546 / 100;
$co2diff = $co2pkw - $co2ped;
$co2diff = sprintf('%.2f',$co2diff);
$co2diff =~ s/\./,/;
return $co2diff;
}
#calculates sprit saving
sub sprit2calc {
my $self = shift;
my $ctpos = shift;
my $einzel = $ctpos->{int02};
my $menge = $ctpos->{int03};
my $rabatt_val = $ctpos->{int07} || 0;
my $gesamt = 0;
if($rabatt_val != 0 && $einzel && $menge){
my $rabatt_eur = $rabatt_val;
#if int08 != 1 alias €
$rabatt_eur = $einzel * $menge * $rabatt_val/100 if($ctpos->{int08} != 1);
$gesamt = $einzel * $menge - $rabatt_eur;
}elsif($einzel && $menge){
$gesamt = $einzel * $menge;
}
my $sprit_price = 0;
$sprit_price = $ctpos->{int26} * 0.3 if($ctpos->{int26} != 0);
$sprit_price -= $gesamt;
$sprit_price = sprintf('%.2f',$sprit_price);
$sprit_price =~ s/\./,/;
return $sprit_price;
}
#computes position price and rabatt
sub price2calc {
my $self = shift;
my $ctpos = shift;
my $gesamt = 0;
my $rabatt = "";
my $einzel = $ctpos->{int02};
my $menge = $ctpos->{int03};
my $rabatt_val = $ctpos->{int07} || 0;
if($rabatt_val != 0 && $einzel && $menge){
my $rabatt_eur = $rabatt_val;
#if int08 != 1 alias €
$rabatt_eur = $einzel * $menge * $rabatt_val/100 if($ctpos->{int08} != 1);
$gesamt = $einzel * $menge - $rabatt_eur;
}elsif($einzel && $menge){
$gesamt = $einzel * $menge;
}
if($ctpos->{int07} && $ctpos->{int07} > 0 && $menge > 0){
$rabatt = "-" . $ctpos->{int07};
if($ctpos->{int08} == 1){
$rabatt .= " €";
}else{
$rabatt =~ s/\.00//;
$rabatt .= " %";
}
}
return ($gesamt,$rabatt);
}
1;