rebuild merchant select to get colors and init_map

This commit is contained in:
Rainer Gümpelein 2022-01-04 11:49:13 +01:00
parent 0184300a35
commit 1b0ba8f010
8 changed files with 112 additions and 119 deletions

View file

@ -49,6 +49,68 @@ my $lang="de";
my $owner=188;#via API
my $dbh = "";
#fetch merchant_id by request or hostname
sub fetch_merchant {
my $self = shift;
my $varenv = shift;
my $req_sessionid = shift || "";
my $req_authcookie = shift || "";
my $req_merchant_id = shift || "";
my $response = { init_map => {
center => { latitude => "", longitude => "" },
radius => ""
}
};
my $merchanized = 0;
my $aowner = 0;
my $merchant_id = "";
while ((my $merchant_conf, my $value) = each %{ $dbt->{merchant_ids}}) {
if($merchant_conf && (($req_sessionid && $req_sessionid =~ /$merchant_conf$/) || ($req_authcookie && $req_authcookie =~ /$merchant_conf$/) || ($req_merchant_id && $req_merchant_id eq $merchant_conf))){
$aowner = $value->{id};
$merchant_id = $merchant_conf;
$merchanized = 1;
my $lat = "";
my $lng = "";
$value->{initMap} =~ s/\s//g;
($lat,$lng) = split(/,/,$value->{initMap}) if($value->{initMap} && $value->{initMap} =~ /\d+,\d+/);
if($lat && $lng){
$response->{init_map}->{center}->{latitude} = $lat;
$response->{init_map}->{center}->{longitude} = $lng;
$response->{init_map}->{radius} = "2.9";
}
$bw->log("merchant select by session-cookie OR authcookie OR merchant_id: if($merchant_conf && (($req_sessionid && $req_sessionid =~ /$merchant_conf$/) || ($req_authcookie && $req_authcookie =~ /$merchant_conf$/) || ($req_merchant_id && $req_merchant_id eq $merchant_conf))){",$merchant_conf,"");
last;
}
}
if(!$merchanized){
if($varenv->{syshost} eq "shareeapp-primary" || $varenv->{syshost} eq "shareedms-primary"){
$aowner = $dbt->{primary}->{sharee_primary}->{owner};
$merchant_id = $dbt->{primary}->{sharee_primary}->{merchant_id};
$merchanized = 1;
$bw->log("merchant select by primary dbname: sharee_primary:",$merchant_id,"");
}
elsif($varenv->{syshost} =~ /shareeapp-(\w+)/ || $varenv->{syshost} =~ /shareedms-(\w+)/){
$aowner = $dbt->{operator}->{$varenv->{dbname}}->{owner};
$merchant_id = $dbt->{operator}->{$varenv->{dbname}}->{merchant_id};
$merchanized = 1;
$bw->log("merchant select by operator dbname=$varenv->{dbname}:",$merchant_id,"");
}
elsif($varenv->{syshost} =~ /shareeweb-/){
$aowner = $dbt->{website}->{$varenv->{syshost}}->{owner};
$merchant_id = $dbt->{website}->{$varenv->{syshost}}->{merchant_id};
$merchanized = 1;
$bw->log("merchant select by website syshost=$varenv->{syshost}:",$merchant_id,"");
}
}
return ($aowner,$merchant_id,$response);
}
#helper to get template
sub get_node_meta {
my $self = shift;
@ -2127,9 +2189,8 @@ sub auth_verify(){
}else{
$bw->log("auth_verified on operator anchor FAILS by dbname $varenv{dbname}, no authcookie, dump \$q",$q,"");
}
my $agb_checked = 0;
$agb_checked = 1 if($record->{int14});#sharee AGB global
$return->{agb_checked} = "$agb_checked";
$return->{agb_checked} = "0";
$return->{agb_checked} = "1" if($record->{int14});#sharee AGB global
my $last_used_operator = $record->{txt19};#check if this is primary and/or useable
$bw->log("last_used_operator selected by txt19:",$last_used_operator,"");
@ -2295,8 +2356,6 @@ sub authcookie_manager {
new_authcoo => "0",
user_id => "$record->{txt08}",
};
$return = { %$return, debuglevel => "$record->{int11}" } if($record->{int11});
$return = { %$return, Ilockit_admin => "$record->{int19}" } if($record->{int19});
#return new generated authcookie
}else{
@ -2340,12 +2399,15 @@ sub authcookie_manager {
user_id => "$record->{txt08}",
};
$return = { %$return, debuglevel => "$record->{int11}" } if($record->{int11});
$return = { %$return, Ilockit_admin => "$record->{int19}" } if($record->{int19});
}
}
}
$return->{debuglevel} = "$record->{int11}" if($record->{int11});
$return->{Ilockit_admin} = "$record->{int19}" if($record->{int19});
$return->{agb_checked} = "0";
$return->{agb_checked} = "1" if($record->{int14});#sharee AGB global
return $return;
}

View file

@ -52,6 +52,8 @@ sub loop_sharees {
}elsif($_ eq "project"){
my $val = $q->param($_);
$project = $val if($val eq "Bayern");#restricted map view only on lastenrad bayern iframe
$project = $val if($val eq "Konstanz");
$project = $val if($val eq "Demo");
}
}
$rest =~ s/\&$//;

View file

@ -49,7 +49,6 @@ sub handler {
my $oprefix = $dbt->{operator}->{$varenv{dbname}}->{oprefix};
my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime;
my $lang="de";
my $owner=188;#default via API if authcookie doesn't match merchant_id
my @keywords = $q->param;
my $debug=1;
my $user_agent = $q->user_agent();
@ -60,7 +59,7 @@ print $q->header(-type => "application/json", -charset => "utf-8", -'Access-Cont
my $respreq = $q->param('request') || "";
my $apiserver = $q->url(-base=>1) || "";
my $copri_version = "4.1.8.31";
my $copri_version = "4.1.8.41";
my $response = {
apiserver => "$apiserver",
@ -75,15 +74,11 @@ my $response = {
uri_primary => "$varenv{uri_primary}",
copri_version => "$copri_version",
response_state => "OK, nothing todo",
privacy_html => "site/privacy.html",
privacy_html => "site/privacy_1.html",
agb_html => "site/agb.html",
impress_html => "site/impress.html",
tariff_info_html => "site/tariff_info_1.html",
bike_info_html => "site/bike_info.html",
initMap => {
center => { latitude => "", longitude => "" },
radius => ""
},
last_used_operator => {
operator_name => "sharee.bike | TeilRad GmbH",
operator_color => "#009699",
@ -93,39 +88,10 @@ my $response = {
},
lang => "DE"
};
#user_agent => "$user_agent"
my $merchanized = 0;
my $merchant_conf = "";
#while (($merchant_conf, my $value) = each %{ $dbt->{merchant_ids}}) {
# if($merchant_conf && $value->{user_agent} && $user_agent && $user_agent =~ /$value->{user_agent}/){
# #$owner = join("", map { $_ } keys %{ $value });
# $owner = $value->{id};
# $merchanized = 1;
# $response->{initMap} = "$value->{initMap}";
# $bw->log("APIjsonserver merchant select by user_agent: if($value->{user_agent} && $user_agent && $user_agent =~ /$value->{user_agent}/){",$merchant_id,"");
# last;
# }
#}
(my $aowner,$varenv{merchant_id},$response) = $apif->fetch_merchant(\%varenv,"",$R::authcookie,$R::merchant_id);
if(!$merchanized){
while (($merchant_conf, my $value) = each %{ $dbt->{merchant_ids}}) {
if($merchant_conf && (($R::authcookie && $R::authcookie =~ /$merchant_conf$/) || ($R::merchant_id && $R::merchant_id eq $merchant_conf))){
$owner = $value->{id};
$merchanized = 1;
$value->{initMap} =~ s/\s//g;
my ($lat,$lng) = split(/,/,$value->{initMap});
$response->{initMap}->{center}->{latitude} = $lat;
$response->{initMap}->{center}->{longitude} = $lng;
$response->{initMap}->{radius} = "2.9";
#$response->{initMap} = "$value->{initMap}";
$bw->log("APIjsonserver merchant select by authcookie OR merchant_id: if($merchant_conf && (($R::authcookie && $R::authcookie =~ /$merchant_conf$/) || ($R::merchant_id && $R::merchant_id eq $merchant_conf))){",$merchant_conf,"");
last;
}
}
}
if(!$merchanized && ($R::authcookie || $R::merchant_id)){
if(!$aowner && ($R::authcookie || $R::merchant_id)){
$response->{response_state} = "Failure 9900: no authcookie or merchant_id defined";
$response->{response_text} = "Authentifizierung fehlgeschlagen.";
$bw->log("NO authcookie or merchant_id defined",$R::merchant_id,"");
@ -135,7 +101,7 @@ if(!$merchanized && ($R::authcookie || $R::merchant_id)){
exit 0;
}
#If param>40 || value > 200 then exit
#If param>40 || value > 400 then exit
foreach(@keywords){
if(length($_) > 40 || length($q->param($_)) > 400){
$response->{response_state} = "Failure 9000: amount of characters in $_ exceeds";
@ -183,7 +149,7 @@ elsif($q->param('request') eq "authout"){
}
#authorization
elsif($q->param('request') eq "authorization"){
my ($auth,$authraw) = $apif->authorization($q,"","",$owner);
my ($auth,$authraw) = $apif->authorization($q,"","",$aowner);
if(ref($auth) eq "HASH" && $auth->{authcookie}){
$response = { %$response, %$auth };
$response->{response_text} = "Herzlich willkommen im Fahrradmietsystem";
@ -230,11 +196,11 @@ elsif($q->param('request') eq "booking_request"){
$gps = "$latitude,$longitude" if($latitude && $longitude);
}
my $response_book = $tk->net_booking($authraw,$q->param('bike'),$owner,$gps);
my $response_book = $tk->net_booking($authraw,$q->param('bike'),$aowner,$gps);
#just in time booking
if(ref($response_book) eq "HASH" && $response_book->{response_state} =~ /OK/ && $q->param('state') && $q->param('state') =~ /occupied/){
(my $rows, my $booking_values) = $apif->booking_update($q,$authraw,$owner);
(my $rows, my $booking_values) = $apif->booking_update($q,$authraw,$aowner);
$response = {%$response, %$booking_values};
}else{
$response = {%$response, %$response_book};
@ -283,10 +249,10 @@ elsif($q->param('request') eq "booking_cancel" || $q->param('request') eq "booki
if(ref($auth) eq "HASH" && $auth->{authcookie}){
if($q->param('bike')){
if($q->param('request') eq "booking_update" && $q->param('state') && $q->param('state') =~ /canceled/){
($rows, my $booking_values) = $apif->booking_update($q,$authraw,$owner);
($rows, my $booking_values) = $apif->booking_update($q,$authraw,$aowner);
$response = {%$response, %$booking_values};
}elsif($q->param('request') eq "booking_update" && (($q->param('state') && $q->param('state') =~ /occupied|available/) || ($q->param('lock_state') && $q->param('lock_state') =~ /locking|locked|unlocked/))){
($rows, my $booking_values) = $apif->booking_update($q,$authraw,$owner);
($rows, my $booking_values) = $apif->booking_update($q,$authraw,$aowner);
$response = {%$response, %$booking_values};
#keep in mind, it works on operator dependency
@ -389,7 +355,7 @@ elsif($q->param('request') eq "user_bikes_occupied"){
my ($auth,$authraw) = $apif->auth_verify($q);
if(ref($auth) eq "HASH" && $auth->{authcookie}){
$response = { %$response, %$auth };
($response->{bikes_occupied},$response->{uri_operator_array},$response->{user_group},$response->{user_tour}) = $jsc->loop_sharees($q,$auth,$owner);
($response->{bikes_occupied},$response->{uri_operator_array},$response->{user_group},$response->{user_tour}) = $jsc->loop_sharees($q,$auth,$aowner);
}else{
$response->{response_state} = "Failure 1001: authcookie on primary not defined";
$response->{response_text} = "Entschuldigung, die Session wurde unterbrochen";
@ -416,7 +382,7 @@ elsif($q->param('request') eq "bikes_available"){
if($varenv{syshost} eq "shareeapp-primary"){
my ($auth,$authraw) = $apif->auth_verify($q);
$response = { %$response, %$auth };
($response->{bikes},$response->{uri_operator_array},$response->{user_group},$response->{user_tour}) = $jsc->loop_sharees($q,$auth,$owner);
($response->{bikes},$response->{uri_operator_array},$response->{user_group},$response->{user_tour}) = $jsc->loop_sharees($q,$auth,$aowner);
#my $stamp = gettimeofday;
#$bw->log("X bikes_available $varenv{syshost} $stamp: $response->{user_group}",$response,"");
}else{
@ -437,7 +403,7 @@ elsif($q->param('request') eq "bikes_all"){
if($varenv{syshost} eq "shareeapp-primary"){
my ($auth,$authraw) = $apif->auth_verify($q);
$response = { %$response, %$auth };
($response->{bikes},$response->{uri_operator_array},$response->{user_group},$response->{user_tour}) = $jsc->loop_sharees($q,$auth,$owner);
($response->{bikes},$response->{uri_operator_array},$response->{user_group},$response->{user_tour}) = $jsc->loop_sharees($q,$auth,$aowner);
}else{
my ($auth,$authraw) = $apif->auth_verify($q);
$response = { %$response, %$auth };
@ -445,7 +411,7 @@ elsif($q->param('request') eq "bikes_all"){
#on servicetool only stations on user_tour
my $stations_allraw = {};
(my $stations_not_used,$stations_allraw) = $apif->stations_all($q,"",$authraw) if($owner && $owner eq "187");#shareetool
(my $stations_not_used,$stations_allraw) = $apif->stations_all($q,"",$authraw) if($aowner && $aowner eq "187");#shareetool
my ($bikes_all,$bikes_allraw,$bikes_on_station) = $apif->bikes_all($q,$authraw,$stations_allraw);
@ -456,7 +422,7 @@ elsif($q->param('request') eq "bikes_all"){
my $response_work = {};
#shareetool
if($owner && $owner eq "187"){
if($aowner && $aowner eq "187"){
(my $xresponse, $pos_record, my $node_template, my $crecord) = $apif->service_select($q,$authraw,"",$interval);
($response_work, my $node) = $apif->service_work($pos_record,$bikes_allraw,"",$node_template);
@ -481,7 +447,7 @@ elsif($q->param('request') eq "bikes_all"){
#print "bid:$bid|$bikes_allraw->{$bid}->{mtime}\n";
#shareetool disabled, needs also to much cpu-time
#if(ref($response_work->{$biselect}) ne "HASH" || $response_work->{$biselect}->{int01}->{c_id} !~ /\d/ && $owner && $owner eq "187"){
#if(ref($response_work->{$biselect}) ne "HASH" || $response_work->{$biselect}->{int01}->{c_id} !~ /\d/ && $aowner && $aowner eq "187"){
# my $pos_record_bi = $apif->service_work_select($biselect,"","");
# (my $response_work_bi, my $node) = $apif->service_work($pos_record_bi,$bikes_allraw);
# $response_work->{$biselect} = $response_work_bi->{$biselect};
@ -489,7 +455,7 @@ elsif($q->param('request') eq "bikes_all"){
#}
#2019-02-14, fixed
if(ref($response_work->{$biselect}) eq "HASH" && $owner && $owner eq "187"){#shareetool
if(ref($response_work->{$biselect}) eq "HASH" && $aowner && $aowner eq "187"){#shareetool
#print "$biselect: $response_work->{$biselect}->{mtime}\n";
$bikes_allraw->{$bid}->{service_state_exist} = 1;
@ -581,7 +547,7 @@ elsif($q->param('request') eq "stations_all"){
if($varenv{syshost} eq "shareeapp-primary"){
my ($auth,$authraw) = $apif->auth_verify($q);
$response = { %$response, %$auth };
($response->{stations},$response->{uri_operator_array},$response->{user_group},$response->{user_tour}) = $jsc->loop_sharees($q,$auth,$owner);
($response->{stations},$response->{uri_operator_array},$response->{user_group},$response->{user_tour}) = $jsc->loop_sharees($q,$auth,$aowner);
}else{
my ($auth,$authraw) = $apif->auth_verify($q);
$response = { %$response, %$auth };
@ -596,11 +562,11 @@ elsif($q->param('request') eq "stations_available"){
my ($auth,$authraw) = $apif->auth_verify($q);
#Mein konrad App
#if($dbt->{merchant_ids}->{$varenv{merchant_id}}->{id} eq "176"){
if($owner && $owner eq "176"){
if($aowner && $aowner eq "176"){
$response->{merchant_message} = "Herzlich Willkommen bei der neuen konrad App! Die App ist zwar schon installierbar, bis zur vollständigen Umstellung des Systems sind aber noch keine Räder ausleihbar. Das ist erst voraussichtlich Ende Januar der Fall und wird den Nutzern noch mitgeteilt. Danke für Ihr Verständnis! Ihr konrad-Team";
}
$response = { %$response, %$auth };
($response->{stations},$response->{uri_operator_array},$response->{user_group},$response->{user_tour}) = $jsc->loop_sharees($q,$auth,$owner);
($response->{stations},$response->{uri_operator_array},$response->{user_group},$response->{user_tour}) = $jsc->loop_sharees($q,$auth,$aowner);
}else{
my ($auth,$authraw) = $apif->auth_verify($q);
$response = { %$response, %$auth };
@ -625,7 +591,7 @@ elsif($q->param('request') eq "user_feedback" || $q->param('request') eq "user_m
#if(!$back_id){#disabled because of every feedback have to be saved
if(1==1){
#INSERT just dadaset
$back_id = $apif->service_insert($q,$authraw,$node_template,$crecord,$owner);
$back_id = $apif->service_insert($q,$authraw,$node_template,$crecord,$aowner);
$rows = $apif->service_update($q,$authraw,$node_template,$back_id);
if($rows && $rows > 0){
$response->{response_state} = "OK, feedback insert and update";
@ -864,7 +830,7 @@ else{
my $jrout = $json->pretty->encode({shareejson => $response});
print $jrout;
$bw->log("APIjsonserver response by $user_agent mapped owner:$owner",$jrout,"");
$bw->log("APIjsonserver response by $user_agent mapped aowner:$aowner",$jrout,"");
#end JSON ----------------------------------------------------------------------------
return Apache2::Const::OK;

View file

@ -455,10 +455,16 @@ sub checkbox_style() {
#checkbox
sub checkbox(){
my $self = shift;
my ($val,$check_name,$checked,$title,$required) = @_;
my $val = shift;
my $check_name = shift;
my $checked = shift;
my $title = shift || "";
my $required = shift || "";
my $autofocus = shift || "";
$checked = "checked" if($checked);
$required = "required" if($required);
my $checkb = "<input type='checkbox' style='border: 1px solid silver;' name='$check_name' value='$val' title='$title' $checked $required>";
my $checkb = "<input type='checkbox' style='border: 1px solid silver;' name='$check_name' value='$val' title='$title' $checked $required $autofocus>";
return $checkb;
}

View file

@ -79,9 +79,6 @@ sub handler {
$mode = $1;
}
my $aowner = 0;
$varenv{merchant_id} = "";
#main datadir is main config directive like "shareeapp-kn" and catched by syshost name
if($netloc =~ /:\/\/(sharee\w+-\w+)\.copri/){
#$bw->log("Indexsharee merchant select by netloc:",$netloc,"");
@ -112,57 +109,11 @@ sub handler {
print $q->header(-charset=>"$html_charset", -cookie=>$cookie);
}
($api_return,$users_sharee) = $apif->auth_verify($q,$coo,"");
my $merchanized = 0;
my $merchant_conf = "";
#merchant select by user_agent -> disabled
#while (($merchant_conf, my $value) = each %{ $dbt->{merchant_ids}}) {
# if($merchant_conf && $value->{user_agent} && $user_agent && $user_agent =~ /$value->{user_agent}/){
# $aowner = $value->{id};
# $varenv{merchant_id} = $merchant_conf;
# $merchanized = 1;
# $bw->log("Indexsharee merchant select by user_agent: if($merchant_conf && $value->{user_agent} && $user_agent && $user_agent =~ /$value->{user_agent}/){",$varenv{merchant_id},"");
# last;
# }
#}
if(!$merchanized){
while (($merchant_conf, my $value) = each %{ $dbt->{merchant_ids}}) {
if($merchant_conf && (($coo && $coo =~ /$merchant_conf$/) || ($R::sessionid && $R::sessionid =~ /$merchant_conf$/) || ($R::authcookie && $R::authcookie =~ /$merchant_conf$/) || ($R::merchant_id && $R::merchant_id eq $merchant_conf))){
$aowner = $value->{id};
$varenv{merchant_id} = $merchant_conf;
$merchanized = 1;
$bw->log("Indexsharee merchant select by authcookie OR merchant_id: if($merchant_conf && (($R::sessionid && $R::sessionid =~ /$merchant_conf$/) || ($R::authcookie && $R::authcookie =~ /$merchant_conf$/) || ($R::merchant_id && $R::merchant_id eq $merchant_conf))){",$merchant_conf,"");
last;
}
}
}
#TODO, check it will be deleted
if(1==2 && !$merchanized){
if($varenv{syshost} eq "shareeapp-primary" || $varenv{syshost} eq "shareedms-primary"){
$aowner = $dbt->{primary}->{sharee_primary}->{owner};
$varenv{merchant_id} = $dbt->{primary}->{sharee_primary}->{merchant_id};
$merchanized = 1;
$bw->log("Indexsharee merchant select by dbname: sharee_primary:",$varenv{merchant_id},"");
}
elsif($varenv{syshost} =~ /shareedms-(\w+)/){
$aowner = $dbt->{operator}->{$varenv{dbname}}->{owner};
$varenv{merchant_id} = $dbt->{operator}->{$varenv{dbname}}->{merchant_id};
$merchanized = 1;
$bw->log("Indexsharee merchant select by dbname=$varenv{dbname}:",$varenv{merchant_id},"");
}
elsif($varenv{syshost} =~ /shareeweb-/){
$aowner = $dbt->{website}->{$varenv{syshost}}->{owner};
$varenv{merchant_id} = $dbt->{website}->{$varenv{syshost}}->{merchant_id};
$merchanized = 1;
$bw->log("Indexsharee merchant select by syshost=$varenv{syshost}:",$varenv{merchant_id},"");
}
}
(my $aowner,$varenv{merchant_id},my $response) = $apif->fetch_merchant(\%varenv,$coo,"","");
$bw->log("Indexsharee merchant select used with access_owner $aowner",$varenv{merchant_id},"");
($api_return,$users_sharee) = $apif->auth_verify($q,$coo,"");
#login-screen should only be available if auth_verify fails
if($R::login_sharee || $R::login_dms){
@ -659,8 +610,13 @@ if(1==2 && !$merchanized){
}
}
}elsif($users_sharee->{c_id} && ($path =~ /$varenv{mandant}\/Anmelden|$varenv{mandant}\/$varenv{profile}/)){
if(!$users_sharee->{int14}){
print redirect("$varenv{wwwhost}/$varenv{mandant}/Account/$varenv{accounting_1}?cum=2$session_and\&$returnwww");
exit 0;
}else{
print redirect("$varenv{wwwhost}/$varenv{mandant}/Account/$varenv{accounting_3}?cum=2$session_and\&$returnwww");
exit 0;
}
}
###
}

View file

@ -53,7 +53,7 @@ sub sms_ack_digest {
my $email_ack_digest = $1 if($ack_digest =~ /^(.{5})/);
my $sms_ack_digest = $1 if($ack_digest =~ /(.{5})$/);
my $sms_from = "Mietradsystem";
my $sms_from = "Mietradcode";
my $sms_to = $ctadr->{txt07};# || "+491799xxxx72";
my $sms_message = "Ihr Mietradsystem SMS-Bestätigungscode lautet: $sms_ack_digest";
my $message = Encode::encode('iso-8859-1', Encode::decode('utf-8',"$sms_message"));

View file

@ -536,7 +536,7 @@ Weitere Personen aus Ihrem Haushalt profitieren jedoch ebenfalls, falls Sie weit
$required="";
my $sharee_agb = "<button type='button' class='btn btn-primary ' style='padding:1px 40px;border:1px solid #$bgcolor1;background-color:#$bgcolor1;' data-toggle='modal' data-target='#sharee_agb'>$des</button>\n";
print $q->label({-for=>"$key", -style=>'padding-top:20px;'},"$label_des"),"\n";
print $q->div({-id=>"$key"},$but->checkbox("1","$key","$ctrel->{$key}","","$required"), " $sharee_agb"),"\n";
print $q->div({-id=>"$key"},$but->checkbox("1","$key","$ctrel->{$key}","","$required","$autofocus"), " $sharee_agb"),"\n";
print $q->hidden(-name=>"$key",-override=>1,-value=>"null");
}

View file

@ -118,6 +118,7 @@ sub tpl(){
print "</div>\n";
print $q->end_form,"\n";
print $q->span({-style=>'color:white;'},"merchant_id:$varenv->{merchant_id}"),"\n";
print "</div>";
exit 0;