From ae4ff98d9bc128a6b5ecb9293a26364aac6dc3b4 Mon Sep 17 00:00:00 2001 From: ragu Date: Tue, 18 Oct 2022 20:15:11 +0200 Subject: [PATCH] operator faktura config --- copri4/main/css/local_style20220928.css | 10 +- copri4/main/src/Mod/DBtank.pm | 5 +- copri4/main/src/Mod/Libenz.pm | 8 +- copri4/main/src/Mod/Libenzdb.pm | 1 - copri4/main/src/Mod/NodeEdit.pm | 2 +- copri4/main/src/Mod/Prelib.pm | 26 ++- copri4/main/src/Mod/Pricing.pm | 40 ++++ copri4/main/src/Tpl/Address3.pm | 50 +++-- copri4/main/src/Tpl/Liste3.pm | 6 +- copri4/main/src/Tpl/MandantConf.pm | 26 +-- copri4/main/src/Tpl/SubListe.pm | 1 + copri4/main/src/Tpl/TransInvoices.pm | 228 ++++---------------- copri4/main/src/Tpl/TransPositionen.pm | 2 +- copri4/main/src/scripts/Ilockit_CSV2DB.pl | 32 +-- copri4/main/src/scripts/sms_message.pl | 2 +- copri4/shareedms-operator/src/Lib/Mlogic.pm | 7 +- 16 files changed, 186 insertions(+), 260 deletions(-) diff --git a/copri4/main/css/local_style20220928.css b/copri4/main/css/local_style20220928.css index 5ed5843..4fedb16 100755 --- a/copri4/main/css/local_style20220928.css +++ b/copri4/main/css/local_style20220928.css @@ -398,7 +398,7 @@ div#Oline { .etxtarea { min-height: 2em; min-width: 20em; - border: 0px solid silver; + border: 1px solid silver; } .etxtarea2 { min-height: 10em; @@ -683,6 +683,14 @@ div#ContentLogin { border: 0px solid silver; } +div#Content4conf { + text-align:left; + font-size:15px; + border: 0px solid yellow; + margin: 0; + padding: 40px 5px 5px 0px; + min-width: 1000px; +} div#Content4list { text-align:left; font-size:15px; diff --git a/copri4/main/src/Mod/DBtank.pm b/copri4/main/src/Mod/DBtank.pm index 2ad94da..dd60375 100755 --- a/copri4/main/src/Mod/DBtank.pm +++ b/copri4/main/src/Mod/DBtank.pm @@ -1120,6 +1120,7 @@ sub collect_transpos { $search->{offset} = 0 if(!$search->{offset}); my $where = "where cp.ct_id=ct.c_id"; + $where .= " and cp.int05 is null";#do not select sub workflow docs like storno foreach my $key (keys (%$search)){ $search->{$key} =~ s/^\s//g; $search->{$key} =~ s/\s$//g; @@ -1443,7 +1444,9 @@ sub insert_contenttrans(){ $sth->bind_columns(\$last_id); my $c_id = $sth->fetchrow_array(); - my $sth3 = $dbh->prepare("INSERT INTO relation (ca_id,main_id,content_id,template_id,change) VALUES('$ctadr->{c_id}','$main_id','$c_id','$tpl_id','now()')"); + my $foreign_key = "ca_id"; + $foreign_key = "cu_id" if($ctadr->{c_id} == 2);#operator-faktura config + my $sth3 = $dbh->prepare("INSERT INTO relation ($foreign_key,main_id,content_id,template_id,change) VALUES('$ctadr->{c_id}','$main_id','$c_id','$tpl_id','now()')"); $sth3->execute(); return $c_id; } diff --git a/copri4/main/src/Mod/Libenz.pm b/copri4/main/src/Mod/Libenz.pm index b42b5f6..c508906 100755 --- a/copri4/main/src/Mod/Libenz.pm +++ b/copri4/main/src/Mod/Libenz.pm @@ -185,15 +185,15 @@ EOF my $pre = ""; $kind_of_trans = "Transaktions" if(!$kind_of_trans); my $feedb = ""; - $feedb = "neue $pre Daten eingefuegt" if($i_pm); + $feedb = "neue $pre Daten eingefügt" if($i_pm); $feedb = "insert successfully " if($i_pm && $varenv{html_lang} eq "en"); $feedb = "$pre Daten gespeichert" if($s_pm); $feedb = "saved successfully" if($s_pm && $varenv{html_lang} eq "en"); - $feedb = "$pre Daten geloescht" if($d_pm); + $feedb = "$pre Daten gelöscht" if($d_pm); $feedb = "deleted successfully" if($d_pm && $varenv{html_lang} eq "en"); - $feedb = "neue $kind_of_trans Daten eingefuegt" if($i_pl); + $feedb = "neue $kind_of_trans Daten eingefügt" if($i_pl); $feedb = "$kind_of_trans Daten gespeichert" if($s_pl); - $feedb = "$kind_of_trans Daten geloescht" if($d_pl); + $feedb = "$kind_of_trans Daten gelöscht" if($d_pl); $feedb = "Artikel eingefügt" if($i_pl =~ /ctpos_id=\d+/); my $debug; $debug = "($ret_pm|$ret_pl)" if($owner eq "101"); diff --git a/copri4/main/src/Mod/Libenzdb.pm b/copri4/main/src/Mod/Libenzdb.pm index 13363e6..cf86023 100755 --- a/copri4/main/src/Mod/Libenzdb.pm +++ b/copri4/main/src/Mod/Libenzdb.pm @@ -1304,7 +1304,6 @@ sub search_jsonadr(){ my $dbh = $dbt->dbconnect();#because of ajax external handle request my $template_id=200;#$table eq content $template_id=202 if($table eq "contentadr"); - $template_id=203 if($table eq "contentuser"); my $mjkey; $mjkey = $1 if($retype =~ /combobox_(txt\d+)/); diff --git a/copri4/main/src/Mod/NodeEdit.pm b/copri4/main/src/Mod/NodeEdit.pm index 74208c2..05c2460 100755 --- a/copri4/main/src/Mod/NodeEdit.pm +++ b/copri4/main/src/Mod/NodeEdit.pm @@ -121,7 +121,7 @@ sub admin_tpl(){ print $q->hidden(-name=>'owner', -value=>"$users_dms->{u_id}"); print $q->hidden(-name=>'parent_id', -value=>"$node_meta->{parent_id}"); print $q->hidden(-name=>'main_id', -value=>"$node_meta->{main_id}"); - print $q->hidden(-name=>'template_id', -value=>"$node_meta->{template_id}"); + #print $q->hidden(-name=>'template_id', -value=>"$node_meta->{template_id}"); print $q->hidden(-name=>'mode', -value=>"admin"); print $q->start_table({-style=>'margin-top:6px;', -border=>'0', -width=>'100%', -align=>'left', -cellpadding=>'3', -cellspacing=>'3'}); diff --git a/copri4/main/src/Mod/Prelib.pm b/copri4/main/src/Mod/Prelib.pm index a6133ad..1b475e4 100755 --- a/copri4/main/src/Mod/Prelib.pm +++ b/copri4/main/src/Mod/Prelib.pm @@ -409,9 +409,8 @@ sub set_workflow { foreach my $id (sort { lc($cttpos->{$a}->{sort}) cmp lc($cttpos->{$b}->{sort}) } keys(%$cttpos)){ #reverse pos sum for example by Storno $cttpos->{$id}->{int01} = $cttpos->{$id}->{int01} * -1 if($cttpos->{$id}->{int01} != 0); - $cttpos->{$id}->{txt23} = "Storno" if($cttpos->{$id}->{int01} == -1); - #$cttpos->{$id}->{int02} = $cttpos->{$id}->{int02} * -1 if($cttpos->{$id}->{int02} != 0); - #$cttpos->{$id}->{int07} = $cttpos->{$id}->{int07} * -1 if($cttpos->{$id}->{int07} != 0 && $cttpos->{$id}->{int08} == 1);#if Rabatt int08 != 1 alias €; + $cttpos->{$id}->{int05} = $cttpos->{$id}->{c_id};# set source pos id if sub doc + $cttpos->{$id}->{txt23} = "workflow doc" if($cttpos->{$id}->{int01} == -1); delete $cttpos->{$id}->{c_id}; delete $cttpos->{$id}->{ct_id}; @@ -827,7 +826,6 @@ sub operator_accounting { print FILE "Invoice c_id's ck4ex: $ck4ex\n"; - close FILE; my $accounting_main_id = 300029; my $node_faktura = $dbt->get_node($dbh,$dbt->{shareedms_conf}->{faktura}); @@ -835,13 +833,21 @@ sub operator_accounting { my $praefix = "$node->{node_name}-$varenv{praefix}"; my $ret = ""; - my $auth = $users_sharee;#workaround, must be operator addr. my $c_idnew = ""; if($ck4ex){ - $c_idnew = $dbt->insert_contenttrans($dbh,$auth,$accounting_main_id,"208","----",$users_dms->{u_id}); + + my $opuser = { + table => "contentuser", + fetch => "one", + c_id => 2, + }; + my $ctuser = $dbt->fetch_tablerecord($dbh,$opuser); + + $c_idnew = $dbt->insert_contenttrans($dbh,$ctuser,$accounting_main_id,"208","----",$users_dms->{u_id}); if($c_idnew){ + print FILE "c_idnew: $c_idnew\n"; $i_rows++; my $ctt = { c_id => $c_idnew }; my $update_ctt = { @@ -851,6 +857,11 @@ sub operator_accounting { mtime => "now()", owner => $users_dms->{u_id}, }; + $update_ctt->{int21} = $ctuser->{int01} if($ctuser->{int01}); + $update_ctt->{int22} = $ctuser->{int02} if($ctuser->{int02}); + $update_ctt->{int23} = $ctuser->{int03} if($ctuser->{int03}); + $update_ctt->{int24} = $ctuser->{int04} if($ctuser->{int04}); + $update_ctt->{int25} = $ctuser->{int05} if($ctuser->{int05}); $dbt->update_record($dbh,$update_ctt,$ctt); my $pref = { @@ -865,6 +876,7 @@ sub operator_accounting { $ck4ex =~ s/\s/,/g; $dbt->update_sql($dbh,"UPDATE contenttrans set int20='$ctt->{c_id}' where c_id IN ($ck4ex)"); + print FILE "UPDATE contenttrans set int20='$ctt->{c_id}' where c_id IN ($ck4ex)\n"; if(1==2){#should only be done on buchen @@ -902,6 +914,8 @@ sub operator_accounting { }else{ $ret = "failure::Abbruch, es wurden keine Belege selektiert."; } + + close FILE; return $ret; } diff --git a/copri4/main/src/Mod/Pricing.pm b/copri4/main/src/Mod/Pricing.pm index c2baead..0013310 100755 --- a/copri4/main/src/Mod/Pricing.pm +++ b/copri4/main/src/Mod/Pricing.pm @@ -472,5 +472,45 @@ sub price2calc { return ($total,$discount); } +#computes operator invoices for accounting +sub operator_accounting2calc { + my $self = shift; + my $varenv = shift; + my $ctpos = shift;#client invoices + my $ctf = shift;#Operator-Faktura config + my $tplf = shift;#Operator-Faktura template + my @tplf_order = split /,/,$tplf->{tpl_order}; + + #returned values + my $oac = { + int01 => 0, + int02 => 0, + int91 => 0, + int92 => 0, + int93 => 0, + }; + + + foreach(@tplf_order){ + my ($key,$val,$size) = split /=/,$_; + if($key =~ /int/){ + $oac->{int01} = $oac->{int01} + $ctpos->{int01} if($key eq "int01" && $ctpos->{int01});#invoice capture + if($ctpos->{state} =~ /Lastschrift/){ + $oac->{int91} = $oac->{int01} / 100 * $ctf->{$key} * -1 if($key eq "int01");#7,5% + $oac->{int92} = $ctf->{$key} * -1 if($key eq "int04");#Trans + $oac->{int93} = $oac->{int01} / 100 * $ctf->{$key} * -1 if($key eq "int02");#Disagio + } + if($ctpos->{state} =~ /Kreditkarte/){ + $oac->{int91} = $oac->{int01} / 100 * $ctf->{$key} * -1 if($key eq "int01");#7,5% + $oac->{int92} = $ctf->{$key} * -1 if($key eq "int05");#Trans + $oac->{int93} = $oac->{int01} / 100 * $ctf->{$key} * -1 if($key eq "int03");#Disagio + } + $oac->{int02} = $oac->{int01} + $oac->{int91} + $oac->{int92} + $oac->{int93};#operator accounting + } + } + + return $oac; +} + 1; diff --git a/copri4/main/src/Tpl/Address3.pm b/copri4/main/src/Tpl/Address3.pm index 940666a..b2aed8a 100755 --- a/copri4/main/src/Tpl/Address3.pm +++ b/copri4/main/src/Tpl/Address3.pm @@ -45,7 +45,7 @@ sub tpl(){ my $line_count1 = 0; my $line_count2 = 0; - #get Firma + #Kunden Faktura ex Firma my $ctf = $db->get_content1("contentuser",$dbt->{shareedms_conf}->{parent_id}); #my $rel4tpl = $db->get_rel4tpl("",$lang,$users_dms->{c_id4trans},$node_meta->{tpl_id}); @@ -53,16 +53,17 @@ sub tpl(){ my @tpl_order = split /,/,$rel4tpl->{tpl_order}; my $ctx = { c_id => 0 }; + my $ctadr = { c_id => 0 }; + my $rel_adr = { rel_id => 0 }; $ctx = $db->get_content1("contenttrans",$users_dms->{c_id4trans}); - my $c_idadr = $ctx->{int10};#c_id orig from contentadr - my $ctadr = $db->get_content1("contentadr",$c_idadr); - my $rel_adr = $db->get_rel4tpl("","$lang","$c_idadr","202"); + my $c_idadr = $ctx->{int10} || "";#c_id orig from contentadr - #print "\nc_idadr Got it from contenttrans.int10: $c_idadr\n"; - # - #my $c_kdnr = $ctx->{txt14}; - #my $mandat; - #$mandat = " | Mandat $ctx->{txt26}" if($ctx->{txt26}); + if($node_meta->{tpl_id} == 208){ + $ctadr = $db->get_content1("contentuser","2"); + }else{ + $ctadr = $db->get_content1("contentadr",$c_idadr); + $rel_adr = $db->get_rel4tpl("","$lang","$c_idadr","202"); + } my $ctt = $ctx; if(("$R::trans2edit" eq "client" && $R::c_idadr) || ($R::ct_trans eq "add_transadr")){ @@ -226,7 +227,7 @@ EOF }elsif($users_dms->{u_id}){ print $q->Tr(),"\n"; - if(!$ctx->{close_time}){ + if(!$ctx->{close_time} && $node_meta->{template_id} == 218){ print ""; print $but->singlesubmit2glyph("trans2edit","client","Kunden bearbeiten","background-color:white;"),"\n"; print $q->hidden(-name=>'c_id4trans', -override=>'1', -value=>"$ctx->{c_id}"),"\n"; @@ -270,12 +271,20 @@ EOF print "\n"; print $q->start_table({-class=>'list', -border=>'0', -width=>'100%',-align=>'left', -cellpadding=>'0', -cellspacing=>'0'}),"\n"; - #payone is working? - #keep in mind - #$ctx is primarly contenttrans - #$ctt = $ctx - #$ctt will partly overwritten by contentadr if address changes - my $pay_sequence = " | sequencenr: $ctt->{int18}" if($ctt->{int18}); + if($node_meta->{tpl_id} == 208){ + my $tplop = $db->get_tpl("196");#Operator-Faktuar + my @tplop_order = split /,/,$tplop->{tpl_order}; + foreach(@tplop_order){ + my ($key,$val,$size,$unit) = split /=/,$_; + if($key =~ /int/){ + $ctadr->{$key} =~ s/\./,/; + print $q->Tr(),"\n"; + print $q->td({-class=>'tdescr', -style=>'width:50%;'},"$val"),"\n"; + print $q->td({-class=>'tdval'},"$ctadr->{$key} $unit"),"\n"; + } + } + }else{ + my $pay_sequence = " | sequencenr: $ctt->{int18}" if($ctt->{int18}); my @_paymentstate = split(/\|/,$dbt->{shareedms_conf}->{payment_state}); my $kind_of_payment = "fehlt"; $kind_of_payment = "$_paymentstate[0]" if($ctadr->{int03} == 1); @@ -293,14 +302,13 @@ EOF print $q->td({-class=>'tdescr'},"Payone Referenz"),"\n"; print $q->td({-class=>'tdval'},"$ctt->{txt25}"),"\n"; - - #check payone status - if($ctt->{txt28} =~ /error/i){ + #check payone status + if($ctt->{txt28} =~ /error/i){ print $q->Tr(),"\n"; print $q->td({-class=>'tdescr'},"payone error"),"\n"; print $q->td({-class=>'tdval'},"(transaction) $ctt->{txt28}"),"\n"; - } - + } + } print $q->end_table; print "\n"; diff --git a/copri4/main/src/Tpl/Liste3.pm b/copri4/main/src/Tpl/Liste3.pm index 046288a..8fbabbc 100755 --- a/copri4/main/src/Tpl/Liste3.pm +++ b/copri4/main/src/Tpl/Liste3.pm @@ -224,7 +224,7 @@ sub tpl(){ #Faktura actions if($node_meta->{template_id} =~ /208|209|218/){ $main_id = $dbt->{shareedms_conf}->{faktura}; - $tplids = "208,218"; + $tplids = "208,209,218"; if($node_meta->{node_name} =~ /OPOS/){ $R::detail_search="suchen"; @@ -766,7 +766,9 @@ sub tpl(){ #checkboxes #permissions if($users_dms_primary->{int03} == 2 && $users_dms->{int03} == 2){ - print $q->td({-style=>"background-color:silver;"}, $q->checkbox(-name=>"ck4ex", -checked=>'', -value=>"$ct4rel->{$id}->{c_id}", -label=>'')),"\n"; + my $checked = 0; + $checked = 1 if($ct4rel->{$id}->{template_id} == 209 && $ct4rel->{$id}->{int01} > 0 && $ct4rel->{$id}->{state} =~ /payone/i && !$ct4rel->{$id}->{int14}); + print $q->td({-style=>"background-color:silver;"}, $q->checkbox(-name=>"ck4ex", -checked=>"$checked", -value=>"$ct4rel->{$id}->{c_id}", -label=>'')),"\n"; }else{ print $q->td({-style=>"background-color:silver;"}," "),"\n"; } diff --git a/copri4/main/src/Tpl/MandantConf.pm b/copri4/main/src/Tpl/MandantConf.pm index f2950e4..622be67 100755 --- a/copri4/main/src/Tpl/MandantConf.pm +++ b/copri4/main/src/Tpl/MandantConf.pm @@ -48,16 +48,18 @@ sub tpl(){ $path =~ s/\/user|\/manager|\/admin//; my $lang = "de"; my $dbh = ""; + my $dbh_primary = $dbt->dbconnect_extern("sharee_primary"); + my $users_dms_primary = { u_id => 0 }; + $users_dms_primary = $dbt->select_users($dbh_primary,$users_dms->{u_id},"and int02 >= 1"); + my $rel = {}; my $ct = {}; if($node_meta->{ct_table} eq "contentuser"){ - if(($node_meta->{node_name} eq "Firma") && ($users_dms->{u_id} eq $varenv{superu_id})){ - $rel = $db->get_rel4tpl($node_meta->{main_id},$lang,"","201","","",">0"); + #Firma alias Kunden-Faktura and Operator-Faktura config + if(($node_meta->{template_id} =~ /196|201/) && $users_dms_primary->{int02} >= 1){ + $rel = $db->get_rel4tpl($node_meta->{main_id},$lang,"","$node_meta->{template_id}","","",">0"); $ct = $db->get_content1("contentuser",$rel->{content_id}); - }elsif(($node_meta->{node_name} eq "System") && ($users_dms->{u_id} eq $varenv{superu_id})){ - $rel = $db->get_rel4tpl($node_meta->{main_id},$lang,"","215","","",">0"); - $ct = $db->get_content1("contentuser",$rel->{content_id}); - }elsif($node_meta->{node_name} eq "Kontakt-Hotline" && $users_dms->{int08} >= 1){ + }elsif($node_meta->{template_id} == 197 && $users_dms->{int08} >= 1){ $rel = $db->get_rel4tpl($node_meta->{main_id},$lang,"","197","","",">0"); $ct = $db->get_content1("contentuser",$rel->{content_id}); }else{ @@ -68,9 +70,9 @@ sub tpl(){ my $tpl = $db->get_tpl($rel->{template_id}); my @tpl_order = split /,/,$tpl->{tpl_order}; my $u_name = $dbt->sys_username($dbh,$ct->{owner}); - $ct->{change} = $lb->time4de($ct->{mtime},"1"); + $ct->{mtime} = $lb->time4de($ct->{mtime},"1"); - print "
"; + print "
"; print $q->div({-class=>"copri_header",-style=>"background-color:#cccccc;"},"Pfad: $path"); print $q->div({-style=>'background-color:silver;height:10px;'},""),"\n"; print $q->start_form(); @@ -91,12 +93,12 @@ sub tpl(){ print $q->a({-class=>"editnav",-href=>"$script$path?config2edit=1",-title=>'bearbeiten'}, $q->img({-src=>"$varenv{metahost}/glyphicons/glyphicons-151-edit.png"})); print "\n"; } - print $q->td({-style=>"background-color:white;padding-right:10px;border-bottom: 1px solid silver;text-align:right;font-size:12px;"}, "$u_name / $ct->{change}"); + print $q->td({-style=>"background-color:white;padding-right:10px;border-bottom: 1px solid silver;text-align:right;font-size:12px;"}, "$u_name / $ct->{mtime}"); my $i=0; foreach (@tpl_order){ $i++; - my ($key,$des,$size) = split /=/,$_; + my ($key,$des,$size,$unit) = split /=/,$_; $size = "60" if($key =~ /ct_name|txt|img/ && !$size); $ct->{$key} = $q->unescapeHTML("$ct->{$key}"); $des .= " ($key)" if($users_dms->{u_id} eq $varenv{superu_id}); @@ -104,7 +106,7 @@ sub tpl(){ if($R::config2edit){ $ct->{$key} = $lb->newline($ct->{$key},"","1"); if($size eq "area"){ - $value = ""; + $value = ""; }elsif($size =~ /\w\+\w/){ my ($a,$b) = split /\+/,$size; my $a_checked; @@ -128,7 +130,7 @@ sub tpl(){ print $q->td({-class=>'tdval2'},"$dbt->{operator}->{$varenv{dbname}}->{title} | $dbt->{operator}->{$varenv{dbname}}->{oprefix} | $dbt->{operator}->{$varenv{dbname}}->{database}->{dbname}"),"\n"; }else{ print $q->td({-class=>'tdescr2'},"$des"),"\n"; - print $q->td({-class=>'tdval2'}, "$value"),"\n"; + print $q->td({-class=>'tdval2'}, "$value $unit"),"\n"; } } print $q->end_table; diff --git a/copri4/main/src/Tpl/SubListe.pm b/copri4/main/src/Tpl/SubListe.pm index 0bdffb4..ada05ff 100755 --- a/copri4/main/src/Tpl/SubListe.pm +++ b/copri4/main/src/Tpl/SubListe.pm @@ -325,6 +325,7 @@ EOF my $j = 0; foreach (@tpl_order){ my ($key,$val,$size,$interval) = split /=/,$_; + $val .= " ($key)" if($users_dms->{u_id} eq $varenv{superu_id}); my $divstyle = ""; if($node_meta->{tpl_id} == 199 && $val =~ /int\d+/){ diff --git a/copri4/main/src/Tpl/TransInvoices.pm b/copri4/main/src/Tpl/TransInvoices.pm index 7195fff..13f38d1 100755 --- a/copri4/main/src/Tpl/TransInvoices.pm +++ b/copri4/main/src/Tpl/TransInvoices.pm @@ -51,27 +51,23 @@ sub tpl(){ my %ib = $but->ibuttons(); my $today = strftime "%d.%m.%Y",localtime; my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime; - my $dbh = ""; - my $channel_map = $dbt->channel_map(); my $coo = $q->cookie(-name=>'domcookie'); - my $mapref = {}; - my $ct_users = $dbt->users_map($dbh,$mapref);#get serviceAPP and DMS users from contentadr + my $dbh = ""; my $line_count2 = 0; my $k=0; - my $spart_ct_name = $R::spart_ct_name || ""; - my $c_idpos = $R::c_idpos || $R::pos_id || ""; - my $ctf = $db->get_content1("contentuser",$dbt->{shareedms_conf}->{parent_id}); + my $ctf = $db->get_content1("contentuser","2");#Operator-Faktura config my $ctt = $db->get_content1("contenttrans",$rel4tpl->{content_id}); my $ctadr = $db->get_content1("contentadr",$ctt->{int10}); - my $buchen_mtime = $lb->time4de($ctt->{mtime}); my $vibuchen_mtime = ""; $vibuchen_mtime = "payone post " . $lb->time4de($ctt->{pay_time},1) . " . " if($ctt->{pay_time}); - my @tpl_order = ("txt01=Bezeichnung/Leistung","int03=Anzahl","int02=Einzelpreis","int01=Betrag"); - my $tplf = $db->get_tpl("201");#Firma tpl + #int9x are not in db + my @tpl_order = ("ct_name=Rechnung","int01=Summe payone Einzug","state=Zahlungsart","int91=TeilRad Gebühren","int92=Disagio","int93=Transaktion","int02=Summe Auszahlung"); + + my $tplf = $db->get_tpl("196");#Operator-Faktuar my @tplf_order = split /,/,$tplf->{tpl_order}; my $txt20 = $R::txt20 || $ctt->{txt20} || "";#Leistungsdatum @@ -79,9 +75,10 @@ sub tpl(){ my $cttpos = { c_id => 0 }; my $rows = 0; + #collects invoices ($cttpos,$rows) = $dbt->collect_contenttrans($dbh,$rel4tpl->{content_id}); - #TODO collect payment types + #maybe sum payment types #foreach my $id (keys(%$cttpos)){ # if(ref($cttpos->{$id}) eq "HASH"){ # if($cttpos->{$id}->{int26}){ @@ -102,15 +99,14 @@ sub tpl(){ foreach (@tpl_order){ my ($key,$val) = split /=/,$_; $k++ if($val); + $val .= " ($key)" if($users_dms->{u_id} eq $varenv{superu_id}); print $q->th("$val"); } print $q->start_form(-name=>'transposform'),"\n"; - #Tablecontent (buttons and ct_name(primary key)) - #my $scol = "c_id";#changed to itime because of Storno resorts - my $scol = "itime"; + my $scol = "c_id"; my $sum_parts19=0; my $diff19 = 100 + 19; my $sum_umst19=0; @@ -118,32 +114,14 @@ sub tpl(){ my $accounting_start = ""; my $accounting_end = ""; - foreach my $id (sort { $cttpos->{$b}->{$scol} cmp $cttpos->{$a}->{$scol} } keys(%$cttpos)){ + foreach my $id (sort { $cttpos->{$b}->{$scol} <=> $cttpos->{$a}->{$scol} } keys(%$cttpos)){ - my $gesamt = 0; - my $pricing = {}; - my $counting = {}; - my $rental_feed = {}; + my $oac = $pri->operator_accounting2calc(\%varenv,$cttpos->{$id},$ctf,$tplf); + #$sum_parts19 += $oac->{int01};#payone Einzug + $sum_parts19 += $oac->{int02};#Auszahlung + #$oac->{int01} = $pri->round($oac->{int01}); + $oac->{int01} = sprintf('%.2f', $oac->{int01}); - #accounting prices - if($cttpos->{$id}->{int35} && $cttpos->{$id}->{start_time} && $cttpos->{$id}->{end_time}){ - $cttpos->{$id}->{end_time} = $now_dt if($cttpos->{$id}->{int10} == 3); - ($pricing,$counting) = $pri->counting_rental(\%varenv,$cttpos->{$id},"calc_price"); - $rental_feed = $pri->fetch_rentalfeed(\%varenv,$cttpos->{$id},$counting); - $sum_parts19 += $pricing->{total_price}; - $gesamt = $pri->round($pricing->{total_price}); - $gesamt = sprintf('%.2f', $gesamt); - }else{ - ($gesamt,my $rabatt) = $pri->price2calc($cttpos->{$id}); - $sum_parts19 += $gesamt; - $gesamt = $pri->round($gesamt); - $gesamt = sprintf('%.2f', $gesamt); - } - - my $set_style=""; - my $occupied_style = ""; - my $time_style = ""; - $occupied_style = "color:#ff1493" if($cttpos->{$id}->{int10} == 2 ||$cttpos->{$id}->{int10} == 3 || $cttpos->{$id}->{int10} == 6); if(1==1){ $i++; @@ -163,136 +141,32 @@ sub tpl(){ #1. Spalte print $q->Tr(),"\n"; - print $q->td({-class=>'tdint'},"$cttpos->{$id}->{c_id}"),"\n"; + print $q->td({-class=>'tdint'},"$i"),"\n"; #Tablecontent (parameter) foreach (@tpl_order){ - my ($key,$val,$inputsize) = split /=/,$_; + my ($key,$val) = split /=/,$_; $cttpos->{$id}->{$key} = $q->unescapeHTML($cttpos->{$id}->{$key}); - $cttpos->{$id}->{$key} = $lb->newline($cttpos->{$id}->{$key},"",$R::trans2edit) if($R::trans2edit); - my $ct_pos = "$cttpos->{$id}->{ct_name}"; - my $txtstyle = "text-align:left;min-width:130px;"; - my $isize = "30"; - $isize = $inputsize if($inputsize); + my $txtstyle = "text-align:left;min-width:100px;"; if($key =~ /int\d+/){ $txtstyle = "text-align:right;min-width:50px;"; - $isize = "5"; } if(1==1){ if($key =~ /ct_name/){ - #print $q->td({-class=>'tdint',-style=>"min-width:60px;"},"$ct_pos"); - my $stamm_style = "background-color:#98c13b;padding:2px;"; - my $article = $cttpos->{$id}->{ct_name}; - if($cttpos->{$id}->{int09}){ - print $q->td({-class=>'tdint',-style=>"min-width:60px;padding-top:5px;"}, $q->a({-class=>"linknav3",-style=>"$stamm_style",-href=>"/DMS/Waren/?detail_search=1&s_barcode=$cttpos->{$id}->{barcode}",-title=>"Im Warenstamm"},"$article")),"\n"; - }else{ - print $q->td({-class=>'tdint'},"$article"),"\n"; - } - }elsif($key eq "int26"){ - my $co2saving = ""; - if($cttpos->{$id}->{int26}){ - $co2saving = "Einsparung
"; - my $co2diff = $pri->co2calc($cttpos->{$id}); - my $sprit_price = $pri->sprit2calc($cttpos->{$id}); - $co2saving .= "$co2diff kg CO²
"; - $co2saving .= "$sprit_price EUR
"; - $cttpos->{$id}->{int26} =~ s/\./,/; - $co2saving .= "bei $cttpos->{$id}->{int26} KM"; - } - print $q->td({-class=>'tdint'},"$co2saving"); - + print $q->td({-class=>'tdtxt'},"\# $cttpos->{$id}->{ct_name} $cttpos->{$id}->{txt01}"),"\n"; } - #yes, int03=Menge on parts, int35=unit_price1 on rental - elsif($key =~ /int03/){ - if($cttpos->{$id}->{int35} && $cttpos->{$id}->{start_time} && $cttpos->{$id}->{end_time}){ - print $q->td({-class=>'tdint',-nowrap=>1},"$pricing->{real_clock} $pricing->{freed_time}"),"\n"; - }else{ - $cttpos->{$id}->{$key} =~ s/\./,/; - print $q->td({-class=>'tdint'},"$cttpos->{$id}->{$key}"),"\n"; - } - }elsif($key =~ /int02/){ - if($cttpos->{$id}->{int35} && $cttpos->{$id}->{start_time} && $cttpos->{$id}->{end_time}){ - print "\n"; - foreach my $fid (sort keys(%{ $rental_feed->{rental_description}->{tarif_elements} })){ - if(ref($rental_feed->{rental_description}->{tarif_elements}->{$fid}) eq "ARRAY"){ - print "$rental_feed->{rental_description}->{tarif_elements}->{$fid}[0]: $rental_feed->{rental_description}->{tarif_elements}->{$fid}[1]
\n"; - } - } - print "\n"; - }else{ - $cttpos->{$id}->{$key} =~ s/\./,/; - print $q->td({-class=>'tdint'},"$cttpos->{$id}->{$key} €"),"\n"; - } - }elsif($key =~ /int04/){ - $gesamt =~ s/\./,/; - print $q->td({-class=>'tdint',-nowrap=>1},"$gesamt €"),"\n"; - }elsif($key =~ /int07/){ - my $proz=""; - $proz = "%" if($cttpos->{$id}->{$key} && $cttpos->{$id}->{$key} != 0); - $proz = "€" if($cttpos->{$id}->{$key} && $cttpos->{$id}->{$key} != 0 && $cttpos->{$id}->{int08} && $cttpos->{$id}->{int08} == 1); - $cttpos->{$id}->{$key} =~ s/\./,/; - print $q->td({-class=>'tdint',-nowrap=>"1"},"$cttpos->{$id}->{$key} $proz"),"\n"; - }elsif($key =~ /txt01/){ - $cttpos->{$id}->{$key} = $q->unescapeHTML("$cttpos->{$id}->{$key}"); - $cttpos->{$id}->{$key} = $lb->newline($cttpos->{$id}->{$key},"",""); - print "\n"; - if($cttpos->{$id}->{barcode} && $cttpos->{$id}->{int09}){#bike with tariff-nr - my $u_name = $cttpos->{$id}->{owner}; - my $u_name_end = $cttpos->{$id}->{owner_end}; - foreach my $ctu_id (keys (%$ct_users)){ - if($channel_map->{$u_name}){ - $u_name = $channel_map->{$u_name}; - }elsif($cttpos->{$id}->{owner} eq $ct_users->{$ctu_id}->{c_id}){ - $u_name = $ct_users->{$ctu_id}->{txt01}; - } - if($channel_map->{$u_name_end}){ - $u_name_end = $channel_map->{$u_name_end}; - }elsif($cttpos->{$id}->{owner_end} eq $ct_users->{$ctu_id}->{c_id}){ - $u_name_end = $ct_users->{$ctu_id}->{txt01}; - } - } - if($cttpos->{$id}->{itime} =~ /(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2})/){ - print $q->span("$dbt->{copri_conf}->{bike_state}->{$cttpos->{$id}->{int10}} → $dbt->{copri_conf}->{lock_state}->{$cttpos->{$id}->{int20}} → $u_name / $u_name_end"),"\n"; - my $pos_raw = ""; - if($users_dms->{u_id} && $users_dms->{u_id} =~ /1842/){ - my $pos_details = ""; - foreach my $did (sort keys (%{$pricing->{rentalog}})){ - $pos_details .= $did . " = " . $pricing->{rentalog}->{$did} . "
" if($pricing->{rentalog}->{$did}); - } - #$pos_details = Dumper($pricing->{rentalog}); - $pos_raw = $q->div({-class=>"popup",-onclick=>"toggle_box('$id')"},"$cttpos->{$id}->{c_id}", $q->span({-class=>"popuptext",-id=>"$id"},"$pos_details")); - print "(raw $pos_raw)
\n"; - } - } - print "
\n"; - } - if($cttpos->{$id}->{txt01} || $cttpos->{$id}->{int09}){ - #$line_count2++; - $cttpos->{$id}->{txt01} =~ s/fixed/\fixed\<\/span\>/; - $cttpos->{$id}->{txt01} =~ s/defect/\defect\<\/span\>/; - my $bike=""; - my $tariff = ""; - $bike = "$cttpos->{$id}->{$key}" if($cttpos->{$id}->{$key}); - $tariff = ", Tarif: $cttpos->{$id}->{int09} $cttpos->{$id}->{txt04}" if($cttpos->{$id}->{txt04}); - print $q->span("$bike $tariff
"),"\n"; - } - if($cttpos->{$id}->{int06} || $cttpos->{$id}->{int04}){ - print $q->span("Start/End Station: $cttpos->{$id}->{int06} / $cttpos->{$id}->{int04}, GPS: $cttpos->{$id}->{txt06}"),"\n"; - } - if($cttpos->{$id}->{start_time} && $cttpos->{$id}->{end_time}){ - my $start_time = $lb->time4de($cttpos->{$id}->{start_time},"1"); - my $end_time = $lb->time4de($cttpos->{$id}->{end_time},"1"); - print "
\n"; - print $q->span({-style=>"$time_style"}, "Mietzeit: $start_time → $end_time"),"\n"; - } - print "\n"; - }elsif($key =~ /txt/){ - print $q->td({-class=>'tdtxt'},"$cttpos->{$id}->{$key}"); - }elsif($key =~ /int/){ - print $q->td({-class=>'tdint',-nowrap=>"1"}," \n"); + elsif($key =~ /int/){ + $oac->{$key} =~ s/\./,/; + print $q->td({-class=>'tdint',-nowrap=>1},"$oac->{$key} €"),"\n"; } - }#end view position + elsif($key =~ /state/){ + print $q->td({-class=>'tdint',-nowrap=>1},"$cttpos->{$id}->{$key}"),"\n"; + } + elsif($key =~ /txt/){ + print $q->td({-class=>'tdtxt'},"$cttpos->{$id}->{$key}"),"\n"; + } + } } } @@ -344,7 +218,7 @@ sub tpl(){ print $q->Tr("\n"); print $q->td(" "); - if($node_meta->{node_name} !~ /steuerfrei/){ + if(1==1){ print $q->Tr("\n"); $line_count2++; print $q->td({-class=>'tdint'},"Nettobetrag:"); print $q->td({-class=>'tdint',-nowrap=>"1"},"$sum_netto19 €"); @@ -378,7 +252,7 @@ sub tpl(){ print $q->hidden(-name=>'set_main_id', -value=>"$set_main_id", -override=>'1'); - if($users_dms->{int03} == 2){ + if($users_dms->{int03} == 2){ #only if user is also a primary DMS user with invoice rw print $q->hidden(-name=>'printer_id', -value=>"PDF", -override=>'1'); my $dbh_primary = $dbt->dbconnect_extern("sharee_primary"); @@ -386,19 +260,8 @@ sub tpl(){ $users_dms_primary = $dbt->select_users($dbh_primary,$users_dms->{u_id},"and int03=2"); if($users_dms_primary->{u_id} && $users_dms_primary->{int03} == 2 && !$ctt->{close_time}){ - my @_paymentstate = split(/\|/,$dbt->{shareedms_conf}->{payment_state}); - push @_paymentstate, ""; + my @_paymentstate = ("","Überweisung"); my $kind_of_payment = ""; - if($ctadr->{int03} == 1 && ($ctadr->{ct_name} =~ /PO-\d+/ || $ctadr->{ct_name} =~ /TM-\d+/)){ - $kind_of_payment = "$_paymentstate[0]"; - }else{ - undef $_paymentstate[0]; - } - if($ctadr->{int03} == 2 && length($ctadr->{ct_name}) >= 19){ - $kind_of_payment = "$_paymentstate[1]"; - }else{ - undef $_paymentstate[1]; - } $kind_of_payment = "$ctt->{state}" if($ctt->{state} && $ctt->{int01}); @@ -410,16 +273,8 @@ sub tpl(){ $but->singlesubmit1("set_state","buchen"), $but->selector("state","250px",$kind_of_payment,@_paymentstate)),"\n"; } - #further payone capture are only allowed if OPOS && sequence && TXID is set - if($ctt->{int14} && $ctt->{int18} && $ctt->{txt16}){ - print $q->div({-class=>'element6',-style=>'clear:both;'},"Weitere Payone Einzüge über die vorhandene TXID $ctt->{txt16} (vorautorisiert Summe beachten) durch manuelle inkrement der Sequencenr mit +1", $q->textfield(-class=>'etxt',-name=>"payone_sequence",-default=>"", -override=>'1',-size=>"1",-maxlength=>1)),"\n"; - } - #Payone reset if OPOS and TXID - if($ctt->{int14} && $ctt->{txt16}){ - print $q->div({-class=>'element6',-style=>'clear:both;'},"Payone reset löscht den Vorgang mit der TXID $ctt->{txt16} und versucht einen erneuten Einzug", $but->checkbox("1","payone_reset","0","Payone reset","")),"\n"; - } - } + } print $q->end_form; my $praefix = "$ctt->{txt00}-$varenv{praefix}"; @@ -434,28 +289,21 @@ sub tpl(){ print $q->div({-style=>"padding:0.5em;font-size:0.81em;width:98%;text-align:right;"}, "eMail wurde nicht versandt! Rechnung eMail ", $but->singlesubmit1("ct_trans","send_invoice_again","send_invoice_again")),"\n" if($users_dms->{u_id} == $dbt->{copri_conf}->{superu_id}); print $q->end_form; } - if($ctt->{state} && $ctt->{int01}){ + + if($ctt->{state} && $ctt->{int01}){ $ctt->{int01} =~ s/\./,/; my $style = "color:red;" if($ctt->{int01} ne $sum_paid); my $opos = ""; $opos = "OPOS" if($ctt->{int14} && $ctt->{int14} > 0); print $q->div({-style=>"padding:0.5em;font-size:0.81em;width:98%;text-align:right;"},"$opos $vibuchen_mtime Gebucht $ctt->{int01} € \"$ctt->{state}\"") if($ctt->{state}); - } + } if( -f "$varenv{basedir}/pdfinvoice/$praefix-$ctt->{ct_name}.pdf"){ - #print $q->div({-style=>"padding:0.5em;font-size:0.81em;width:98%;text-align:right;"}, "Download: ", $q->a({-href=>"$varenv{metahost}/pdf/$praefix-$ctt->{ct_name}.pdf", -target=>'_blank'},"$praefix-$ctt->{ct_name}.pdf")); print $q->div({-style=>'padding:0.5em;font-size:0.81em;width:98%;text-align:right;'}, "Download: ", $q->a({-href=>"$varenv{wwwhost}/FileOut?file=$praefix-$ctt->{ct_name}.pdf&sessionid=$coo", -target=>"_blank" , -type=>'application/octet-stream', -style=>'text-decoration:underline;'}), "Rechnung $ctt->{ct_name}.pdf"),"\n"; } - - if($ctt->{state} && $ctt->{state} =~ /payone/ && $ctt->{txt28} && $ctt->{txt28} =~ /error/i){ - print $q->div({-style=>"clear:both;padding:0.5em;font-size:0.81em;width:98%;text-align:right;color:red;"}, "Payone error: $ctt->{txt28}"),"\n"; - }elsif($ctt->{txt28} =~ /settleaccount=yes/i){ - print $q->div({-style=>"clear:both;padding:0.5em;font-size:0.81em;width:98%;text-align:right;color:green;"}, "Payone SEPA-Lastschrifteinzug war erfolgreich"),"\n"; - } - $db->updater("contenttrans","c_id","$rel4tpl->{content_id}","txt20","$accounting_start - $accounting_end","","","","","no_time") if(!$int05 && $accounting_start && $accounting_end); - $db->updater("contenttrans","c_id","$rel4tpl->{content_id}","int15","$sum_preauth","","","","","no_time") if($sum_preauth || $sum_preauth == 0); + return "$line_count2"; } 1; diff --git a/copri4/main/src/Tpl/TransPositionen.pm b/copri4/main/src/Tpl/TransPositionen.pm index 9b828ef..06291dc 100755 --- a/copri4/main/src/Tpl/TransPositionen.pm +++ b/copri4/main/src/Tpl/TransPositionen.pm @@ -72,7 +72,7 @@ sub tpl(){ $vibuchen_mtime = "payone post " . $lb->time4de($ctt->{pay_time},1) . " . " if($ctt->{pay_time}); my @tpl_order = ("txt01=Beschreibung","ct_name=Nummer","date_time=timerange","int03=Menge (Miet - Gratis Zeit)","int02=Preis","int07=Rabatt","int04=Gesamt"); - my $tplf = $db->get_tpl("201");#Firma tpl + my $tplf = $db->get_tpl("201");#Kunden-Faktura, ex Firma my @tplf_order = split /,/,$tplf->{tpl_order}; my $txt20 = $R::txt20 || $ctt->{txt20} || "";#Leistungsdatum diff --git a/copri4/main/src/scripts/Ilockit_CSV2DB.pl b/copri4/main/src/scripts/Ilockit_CSV2DB.pl index 1beb57b..ab6d56e 100755 --- a/copri4/main/src/scripts/Ilockit_CSV2DB.pl +++ b/copri4/main/src/scripts/Ilockit_CSV2DB.pl @@ -62,7 +62,8 @@ my $template_id = 205; #'quote_char' => "\"", 'escape_char' => undef, 'file' => $csv_file, - 'col_names' => ["serialnr","ilockit_id","ilockit_key","c1","c2","c3","c4","c5","c6"] + #'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-%'"); @@ -75,12 +76,13 @@ my $template_id = 205; if($csv->{$id}->{serialnr}){ $csv->{$id}->{ilockit_id} =~ s/\+/\-/; - $csv->{$id}->{c1} =~ s/Rot/red/;$csv->{$id}->{c1} =~ s/Blau/blue/;$csv->{$id}->{c1} =~ s/Gr.+n/green/; - $csv->{$id}->{c2} =~ s/Rot/red/;$csv->{$id}->{c2} =~ s/Blau/blue/;$csv->{$id}->{c2} =~ s/Gr.+n/green/; - $csv->{$id}->{c3} =~ s/Rot/red/;$csv->{$id}->{c3} =~ s/Blau/blue/;$csv->{$id}->{c3} =~ s/Gr.+n/green/; - $csv->{$id}->{c4} =~ s/Rot/red/;$csv->{$id}->{c4} =~ s/Blau/blue/;$csv->{$id}->{c4} =~ s/Gr.+n/green/; - $csv->{$id}->{c5} =~ s/Rot/red/;$csv->{$id}->{c5} =~ s/Blau/blue/;$csv->{$id}->{c5} =~ s/Gr.+n/green/; - $csv->{$id}->{c6} =~ s/Rot/red/;$csv->{$id}->{c6} =~ s/Blau/blue/;$csv->{$id}->{c6} =~ s/Gr.+n/green/; + $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}); @@ -92,15 +94,15 @@ my $template_id = 205; txt22 => "$csv->{$id}->{serialnr}", txt18 => "$csv->{$id}->{ilockit_id}", byte01 => "\\x$csv->{$id}->{ilockit_key}", - int04 => "0",#station Werkstatt - int10 => "5",#defect + 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 - int20 => "2",#unlocked - txt01 => "Mietrad neu", #Bezeichnung #TODO - txt04 => "", #Besonderheiten - txt15 => "", #Firmware - txt17 => "", #GUID from APP - txt23 => "$csv->{$id}->{c1} $csv->{$id}->{c2} $csv->{$id}->{c3} $csv->{$id}->{c4} $csv->{$id}->{c5} $csv->{$id}->{c6}", + txt04 => "", #Sonstiges mtime => "now()", owner => "1842", }; diff --git a/copri4/main/src/scripts/sms_message.pl b/copri4/main/src/scripts/sms_message.pl index 507f875..0d4e69f 100755 --- a/copri4/main/src/scripts/sms_message.pl +++ b/copri4/main/src/scripts/sms_message.pl @@ -137,6 +137,6 @@ if($todo eq "fraud_rental" && $pos_id){ my $booking = { c_id => 0 }; $booking = $dbt->fetch_tablerecord($dbh,$booking_pos); - #$smstrans->sms_message($todo,"",$sms_to,$booking->{ct_name}); + $smstrans->sms_message($todo,"",$sms_to,$booking->{ct_name}); }#end diff --git a/copri4/shareedms-operator/src/Lib/Mlogic.pm b/copri4/shareedms-operator/src/Lib/Mlogic.pm index 1dcd125..4f67e80 100755 --- a/copri4/shareedms-operator/src/Lib/Mlogic.pm +++ b/copri4/shareedms-operator/src/Lib/Mlogic.pm @@ -200,16 +200,15 @@ sub tpl(){ } #1. submenue - #if($subs1 && ($node->{$id}->{node_name} !~ /Einstellung/ || $users_dms->{u_group} =~ /maintainer/)){ if($subs1){ - #if(ref($node1) eq "HASH"){ print "