diff --git a/bash b/bash new file mode 100644 index 0000000..6ffcae5 --- /dev/null +++ b/bash @@ -0,0 +1 @@ +ehco @o diff --git a/lib/Dojo.pm b/lib/Dojo.pm index 9cf3515..365032c 100755 --- a/lib/Dojo.pm +++ b/lib/Dojo.pm @@ -3,6 +3,7 @@ use Mojo::Base 'Mojolicious'; use Dojo::Conf; use Dojo::Model::Vuelo; use Dojo::Model::Users; +use Dojo::Model::Vdgproc; # This method will run once at server start sub startup { @@ -13,25 +14,35 @@ use Dojo::Model::Users; $self->helper(dbv => sub { state $dbv = Dojo::Model::Vuelo->new }); $self->helper(dbg => sub { state $dbg = Dojo::Model::Users->new }); - $self->defaults({%Dojo::Conf::def}); + $self->helper(mproc => sub { state $mproc = Dojo::Model::Vdgproc->new }); + $self->defaults({%Dojo::Conf::def}); my $r = $self->routes; #router -# user ======================================================================== +# de la pagina =============================================================== $r->any('/')->to('home#home_'); $r->any('/home')->to('home#home'); - $r->any('/cal')->to('home#cal'); - $r->any('/event/:id'=> [id => qr/\d+/])->to('home#event'); $r->any('/pod')->to('home#podcast'); $r->any('/store')->to('home#store'); $r->any('/tv')->to('home#tv'); $r->any('/contact')->to('home#contact'); $r->any('/contact2')->to('home#contact2'); $r->any('/pang')->to('home#pang'); +# ============================================================================= + +# de la tienda ================================================================ + $r->any('/cal')->to('proc#cal'); + $r->any('/event/:id'=> [id => qr/\d+/])->to('proc#event'); + $r->any('/spay/:class/:id' => [class => qr/\d+/, id => qr/\d+/])->to('proc#spay'); + $r->any('/spay/intentCreate')->to('proc#intentCreate'); + $r->any('/spay/intentConfirm')->to('proc#intentConfirm'); +# ============================================================================= + +# por matar =================================================================== + $r->any('/xpay')->to('misc#stripe'); $r->any('/storep')->to('home#storep'); $r->any('/storep/:id' => [id => qr/\d+/])->to('home#storep'); # ============================================================================= - # candy ======================================================================= $r->any('/json/candy/:command')->to('data#candy'); $r->any('/candy')->to('home#candy'); @@ -41,26 +52,25 @@ use Dojo::Model::Users; $r->any('/json/*dreq')->to('data#simple'); # ============================================================================= -# register user =============================================================== +# usuarios y accesos ========================================================== $r->any('/reg')->to('users#reg'); -# ============================================================================= -# login guest ================================================================= +# login guest ====== $r->any('/login')->to('users#login'); $r->any('/logout')->to('users#logout'); my $logged_in = $r->under('/')->to('users#is_logged'); $logged_in->get('/radio')->to('home#radio'); -# ============================================================================= +# =================== -# login user grulla =========================================================== +# login user grulla = # common grulla user my $user = $r->under('/')->to('users#is_grulla'); $user->any('/ccast')->to('home#bcast'); # personal my $guest = $r->under('/')->to('users#is_grulla_tmp'); $guest->any('/bcast')->to('home#bcast'); -# ============================================================================= +# =================== # admin ======================================================================= my $admin = $r->under('/admin')->to('users#is_admin'); @@ -74,6 +84,8 @@ use Dojo::Model::Users; $admin->any('json/:dreq/:id')->to('home#admin_json'); # ============================================================================= + +# a not foud ================================================================== $r->any('/*whatever' => {whatever => ''} => sub { my $c = shift; diff --git a/lib/Dojo/Controller/Home.pm b/lib/Dojo/Controller/Home.pm index de42a01..796b39d 100755 --- a/lib/Dojo/Controller/Home.pm +++ b/lib/Dojo/Controller/Home.pm @@ -2,9 +2,6 @@ package Dojo::Controller::Home; use Mojo::Base 'Mojolicious::Controller'; use Mojo::Template; use Dojo::Support qw{ log get_names}; -# estos son paypal=======:w -use LWP::UserAgent; -use HTTP::Request::Common; use JSON; use Data::Dumper; #========================= @@ -70,25 +67,6 @@ sub pang { my $h=$c->dbv->pang_md; map { $c->stash( $_ => $h->{$_}) } keys %$h; $c->stash(layout=>'default'); - -} - -sub cal { - my $c = shift; - my $data=$c->dbv->calendar_events; - my $block=$c->dbv->calendar_monthblock; - my %h; - map{ push @{ $h{$_->{bid}} },$_; }(@$data); - $c->stash( r=>\%h, b=>$block); - $c->stash(layout=>'default'); -} - -sub event{ - my $c = shift; - my $data=$c->dbv->event($c->param('id')); - $c->redirect_to('cal') unless ($data->{'cname'}); - $c->stash($data); - $c->stash(layout=> "defaultContact"); } sub contact{ @@ -114,56 +92,6 @@ sub contact2{ $c->stash(layout=>'default'); } -sub store{ - my $c = shift; - $c->stash( r=>$c->dbg->store); - $c->stash(layout=> "defaultContact"); -} - -sub storep{ - my $c=shift; - if( defined($c->req->json) ){ - my $oid = $c->req->json->{'orderID'} //0; - log( $oid ); - #credentials==== - my $client='AQdZ1JJL-GNBgGTI3W6cXChmj6MnZsInRGlWeHw1kbGiE_49eTtZ2fPvEq9ersU2y6O5WpxccdsyAQw7'; - my $secter='EBn8CNOCrJbVZ_fNllXB7oUIm9_vhtqrJMm2zSBGbxSyiiych3cHOIWOLAD5NVw4Z3dmNhmsHQwPsrZ0'; - my $pauth='https://api.sandbox.paypal.com/v1/oauth2/token/'; - my $porder='https://api.sandbox.paypal.com/v2/checkout/orders/'; - #================= - #pre auth ==== - my $ua = LWP::UserAgent->new; - my $req=POST $pauth, ["grant_type"=>"client_credentials"]; - $req->authorization_basic($client,$secter); - $req->content_type('application/x-www-form-urlencoded'); - my $res=$ua->request($req); - log("paypal pre auth error! $res->status_line") unless ($res->is_success ); - my $json = JSON->new->utf8; - my $r=$json->decode($res->decoded_content); - #============== - - #order details ==== - my $ub = LWP::UserAgent->new; - $ub->default_header('Content-Type'=> 'application/json' ); - $ub->default_header('Authorization'=> 'Bearer ' . $r->{access_token} ); - my $resb=$ub->get($porder.$oid); - log("paypal checkout error!") unless ($resb->is_success ); - my $jsonb = JSON->new->utf8; - my $s=$jsonb->decode($resb->decoded_content); - #=================== - $c->rendered(200); #es default,nomas para enfatizar que puede ser 400 o 500 - # interesan create time, id, payer: email address, shippng address - } - else{ - my $data=$c->dbg->store_id($c->param('id')); - $c->redirect_to('cal') if ($c->param('id')==4); - $c->redirect_to('store') unless ($data->{'id'}); - $c->stash($data); - $c->stash(layout=>'default'); - } - -} - sub tv{ my $c = shift; $c->stash( videos=>$c->dbv->tv_videos, table=>$c->dbv->tv_series); @@ -181,21 +109,21 @@ sub bcast{ $c->stash(layout=> "defaultContact"); } - sub radio{ - my $c=shift; - $c->stash(layout=> "defaultContact"); - $c->stash($c->dbv->mod); - $c->stash(nick=>$c->session("nick")); - } +sub radio{ + my $c=shift; + $c->stash(layout=> "defaultContact"); + $c->stash($c->dbv->mod); + $c->stash(nick=>$c->session("nick")); +} - sub candy{ - my $c=shift; - $c->stash( css=>["/ext/candy/libs.min.css","/home/candy/default.css"]); - $c->stash( js=>["/home/candy/loader.js","/ext/candy/libs.min.js","/ext/candy/candy.min.js"]); +sub candy{ + my $c=shift; + $c->stash( css=>["/ext/candy/libs.min.css","/home/candy/default.css"]); + $c->stash( js=>["/home/candy/loader.js","/ext/candy/libs.min.js","/ext/candy/candy.min.js"]); - $c->stash(layout=> "clean"); - $c->stash(nick=>$c->session("nick")); - } + $c->stash(layout=> "clean"); + $c->stash(nick=>$c->session("nick")); +} #============================================================================== @@ -234,55 +162,6 @@ sub bcast{ $c->stash(layout=>"admin"); } - sub admin_eventos{ - my $c=shift; - if ( (my $t=$c->param('type') // "") =~/[ecp]/){ - my $id=$c->param('id'); - my $req=$c->param('req'); - if ( $req eq "Eliminar"){ - $c->dbv->event_del($id) if ($t eq 'e'); - $c->dbv->course_del($id) if ($t eq 'c'); - $c->dbv->place_del($id) if ($t eq 'p'); - } - elsif( $req eq "Aceptar"){ - if($t eq 'e'){ - my @list=map{$c->param($_)}qw/eplace yini mini dini yend mend dend cost promo pen ecourse eimg een id/; - $c->dbv->event_up(@list) if ($id ==0); - $c->dbv->event_ch(@list) if ($id >0); - } - if($t eq 'c'){ - my @list=map{$c->param($_)}qw/cname csubjects cservices cen id/; - $c->dbv->course_up(@list) if ($id ==0); - $c->dbv->course_ch(@list) if ($id >0); - } - if($t eq 'p'){ - my @list=map{$c->param($_)}qw/pname paddr pobs pto pst pco plat plng pen id/; - $c->dbv->place_up(@list) if ($id ==0); - $c->dbv->place_ch(@list) if ($id >0); - } - } - $c->redirect_to("/admin/eventos"); - } - - $c->stash( - courses=>$c->dbv->courses, - places=>$c->dbv->places, - months=>$c->dbv->months, - events=>$c->dbv->events, - img=>$c->dbv->eimgList, - ); - $c->stash(template=>"home/admin/event"); - $c->stash(layout=>"admin"); - } - sub admin_tienda{ - my $c=shift; - $c->stash(u=>$c->dbv->user_heads); - $c->stash(s=>$c->dbv->store_heads); - $c->stash(template=>"home/admin/tienda"); - $c->stash(layout=>"admin"); - - } - sub admin_json{ my $c=shift; my $id = $c->param('id'); @@ -290,10 +169,6 @@ sub bcast{ my $json = "304"; $json = $c->dbv->msg($id) if $req=~/mensaje/; $json = $c->dbv->user($id) if $req=~/usuarios/; - $json = $c->dbv->astore($id) if $req=~/tienda/; - $json = $c->dbv->course($id) if $req=~/course/; - $json = $c->dbv->place($id) if $req=~/place/; - $json = $c->dbv->eventa($id) if $req=~/event/; $c->render(json=>$json); } diff --git a/lib/Dojo/Controller/Misc.pm b/lib/Dojo/Controller/Misc.pm new file mode 100644 index 0000000..b2ccd17 --- /dev/null +++ b/lib/Dojo/Controller/Misc.pm @@ -0,0 +1,107 @@ +package Dojo::Controller::Misc; +use Mojo::Base 'Mojolicious::Controller'; +use Mojo::Template; +use Dojo::Support qw{ log get_names}; +# estos son paypal=======:w +use LWP::UserAgent; +use HTTP::Request::Common; +use JSON; +use Data::Dumper; + +# 4000004840000008 3, 6, 9, 12, and 18 month installment plans available +# "*p4000004840000008 +# 4242424242424242 No installment plans available. +my $sky='sk_test_GXWsfsoxy5336LrSw7SgTXNC00TV9O4Dbq'; +my $api_create_path='https://api.stripe.com/v1/payment_intents'; + +sub stripe { + my $self = shift; + my $request = defined ($self->req->json)? $self->req->json->{'req'}:"start"; + + # item info ====================== + my $header = "Beijing Wisdom
Healing Center"; + my $title = "Retiro Curso de Tercer método de ZhiNengQiGong"; + my $subtitle = "Una experiencia de instrucción del tercer método y profundización con los instructores ZhangQing (Helen) y QiuFuChun (Karl)."; + my ($amount,$description,$max_time) = (1417500,"Tercer método",9); + # ============================== + + if( $request eq "precheck" ){ + my $pmi=$self->req->json->{'payment_method_id'} // 0; + my $t = intentCreate( $pmi, $amount, $description, $max_time); + $self->render(json=>$t); + } + + elsif( $request eq "check" ){ + my $pii = $self->req->json->{'payment_intent_id'}; + my $plan = $self->req->json->{'selected_plan'}//0; + + unless ($plan==0) {if ($plan->{count} > $max_time) { + log("\n\n max time instalment attempt\n\n"); + $self->render(json=>{'error'=>'max time error'}); + return 0; + }} + my $r = intentConfirm($pii,$plan); + $self->render(json=>$r); + } + + else { + $self->stash(header=>$header); + $self->stash(title=>$title); + $self->stash(subtitle=>$subtitle); + $self->stash(layout=>'xpay'); + } +} + +#stripe appi functions +sub intentCreate{ + my ($pmi,$amount,$descriptor,$max_time) = @_; + my $payment_info=[ + 'payment_method'=>$pmi, + 'amount'=>$amount, + 'currency'=>'mxn', + 'description'=>$descriptor, + 'payment_method_options[card][installments][enabled]'=>'true' + ]; + my $r=stripeAppi($api_create_path,$payment_info); + my $t->{intent_id}=$r->{id}; + foreach (@{$r->{payment_method_options}{card}{installments}{available_plans}}){ + push (@{$t->{available_plans}}, $_) unless ($_->{count}>$max_time); + } + return $t; +} + +sub intentConfirm{ + my ($pii,$plan) = @_; + my $api_confirm_path = "https://api.stripe.com/v1/payment_intents/$pii/confirm"; + my $cplan=0; + + $cplan = [ + 'payment_method_options[card][installments][plan][type]'=>'fixed_count', + 'payment_method_options[card][installments][plan][interval]'=>'month', + 'payment_method_options[card][installments][plan][count]'=>$plan->{count}, + ] + unless ($plan==0); + my $r = stripeAppi($api_confirm_path,$cplan); + my $rtt = { + 'status'=>$r->{'status'}, + 'plan' => $r->{'payment_method_options'}{'card'}{'installments'}{'plan'}, + }; + return $rtt; +} + +sub stripeAppi{ + my ($path,$data) = @_; + my $req = POST $path, $data; + $req->authorization_basic($sky,''); + $req->content_type('application/x-www-form-urlencoded'); + my $ua = LWP::UserAgent->new; + my $res=$ua->request($req); + unless ($res->is_success){ + log("stripe error! path=$path\n data=".Dumper($data)."\n $res->status_line "); + return 0; + } + my $json = JSON->new->utf8; + return $json->decode($res->decoded_content); +} + +1; diff --git a/lib/Dojo/Controller/Proc.pm b/lib/Dojo/Controller/Proc.pm new file mode 100644 index 0000000..d1cda06 --- /dev/null +++ b/lib/Dojo/Controller/Proc.pm @@ -0,0 +1,280 @@ +package Dojo::Controller::Proc; +use Mojo::Base 'Mojolicious::Controller'; +use Mojo::Template; +use Dojo::Support qw{ log get_names}; +# estos son paypal=======:w +use LWP::UserAgent; +use HTTP::Request::Common; +use JSON; +use Data::Dumper; +#========================= +sub tst{ + my $c=shift; + if( defined($c->req->json) ){ + my $oid = $c->req->json->{'orderID'} //0; + log( $oid ); + #credentials==== + my $client='AQdZ1JJL-GNBgGTI3W6cXChmj6MnZsInRGlWeHw1kbGiE_49eTtZ2fPvEq9ersU2y6O5WpxccdsyAQw7'; + my $secter='EBn8CNOCrJbVZ_fNllXB7oUIm9_vhtqrJMm2zSBGbxSyiiych3cHOIWOLAD5NVw4Z3dmNhmsHQwPsrZ0'; + my $pauth='https://api.sandbox.paypal.com/v1/oauth2/token/'; + my $porder='https://api.sandbox.paypal.com/v2/checkout/orders/'; + #================= + #pre auth ==== + my $ua = LWP::UserAgent->new; + my $req=POST $pauth, ["grant_type"=>"client_credentials"]; + $req->authorization_basic($client,$secter); + $req->content_type('application/x-www-form-urlencoded'); + my $res=$ua->request($req); + log("paypal pre auth error! $res->status_line") unless ($res->is_success ); + my $json = JSON->new->utf8; + my $r=$json->decode($res->decoded_content); + #============== + + #order details ==== + my $ub = LWP::UserAgent->new; + $ub->default_header('Content-Type'=> 'application/json' ); + $ub->default_header('Authorization'=> 'Bearer ' . $r->{access_token} ); + my $resb=$ub->get($porder.$oid); + log("paypal checkout error!") unless ($resb->is_success ); + my $jsonb = JSON->new->utf8; + my $s=$jsonb->decode($resb->decoded_content); + #=================== + $c->rendered(200); #es default,nomas para enfatizar que puede ser 400 o 500 + # interesan create time, id, payer: email address, shippng address + } + else{ + my $data=$c->dbg->store_id($c->param('id')); + $c->redirect_to('store') unless ($data->{'id'}); + $c->stash($data); + $c->stash(layout=>'default'); + } + #$c->render(text=> $c->config->{radio}{'channel'}); + +} +# User ======================================================================== + +sub cal { + my $c = shift; + my $data=$c->mproc->calendar_events; + my $block=$c->mproc->calendar_monthblock; + my %h; + map{ push @{ $h{$_->{bid}} },$_; }(@$data); + $c->stash( r=>\%h, b=>$block); + $c->stash(layout=>'default'); +} + +sub event{ + my $c = shift; + my $data=$c->mproc->event($c->param('id')); + $c->redirect_to('cal') unless ($data->{'cname'}); + $c->stash($data); + $c->stash(layout=> "defaultContact"); +} + + +sub store{ + my $c = shift; + $c->stash( r=>$c->dbg->store); + $c->stash(layout=> "defaultContact"); +} + +sub storep{ + my $c=shift; + if( defined($c->req->json) ){ + my $oid = $c->req->json->{'orderID'} //0; + log( $oid ); + #credentials==== + my $client='AQdZ1JJL-GNBgGTI3W6cXChmj6MnZsInRGlWeHw1kbGiE_49eTtZ2fPvEq9ersU2y6O5WpxccdsyAQw7'; + my $secter='EBn8CNOCrJbVZ_fNllXB7oUIm9_vhtqrJMm2zSBGbxSyiiych3cHOIWOLAD5NVw4Z3dmNhmsHQwPsrZ0'; + my $pauth='https://api.sandbox.paypal.com/v1/oauth2/token/'; + my $porder='https://api.sandbox.paypal.com/v2/checkout/orders/'; + #================= + #pre auth ==== + my $ua = LWP::UserAgent->new; + my $req=POST $pauth, ["grant_type"=>"client_credentials"]; + $req->authorization_basic($client,$secter); + $req->content_type('application/x-www-form-urlencoded'); + my $res=$ua->request($req); + log("paypal pre auth error! $res->status_line") unless ($res->is_success ); + my $json = JSON->new->utf8; + my $r=$json->decode($res->decoded_content); + #============== + + #order details ==== + my $ub = LWP::UserAgent->new; + $ub->default_header('Content-Type'=> 'application/json' ); + $ub->default_header('Authorization'=> 'Bearer ' . $r->{access_token} ); + my $resb=$ub->get($porder.$oid); + log("paypal checkout error!") unless ($resb->is_success ); + my $jsonb = JSON->new->utf8; + my $s=$jsonb->decode($resb->decoded_content); + #=================== + $c->rendered(200); #es default,nomas para enfatizar que puede ser 400 o 500 + # interesan create time, id, payer: email address, shippng address + } + else{ + my $data=$c->dbg->store_id($c->param('id')); + $c->redirect_to('cal') if ($c->param('id')==4); + $c->redirect_to('store') unless ($data->{'id'}); + $c->stash($data); + $c->stash(layout=>'default'); + } + +} + +sub spay{ + my $c = shift; + my $data=$c->mproc->store_id($c->param('class'),$c->param('id')); + $c->stash($data); + if( ($c->param('id') <= 86) && ($c->param('id') >= 80) ) + { $c->stash(layout=>'xpay');} + else {$c->stash(layout=>'default');} +} + +#stripe appi functions +sub intentCreate{ + my $c = shift; + unless (defined ($c->req->json)){ + $c->stash(layout=>'clean'); + $c->render(template=>'home/not_found', status=>404); + return 0; + } + my $pmi=$c->req->json->{'payment_method_id'} // 0; + my $data=$c->mproc->intentCreate($c->req->json->{'tid'}); + my ($amount,$description,$max_time) = ($data->{'precio'},$data->{'nombre'},9); + my $api_create_path='https://api.stripe.com/v1/payment_intents'; + my $payment_info=[ + 'payment_method'=>$pmi, + 'amount'=>$amount, + 'currency'=>'mxn', + 'description'=>$description, + 'payment_method_options[card][installments][enabled]'=>'true' + ]; + my $r=stripeAppi($api_create_path,$payment_info); + my $t->{intent_id}=$r->{id}; + foreach (@{$r->{payment_method_options}{card}{installments}{available_plans}}){ + push (@{$t->{available_plans}}, $_) unless ($_->{count}>$max_time); + } + $c->render(json=>$t); + return 0; +} + +sub intentConfirm{ + my $c = shift; + my $max_time = 9; + unless (defined ($c->req->json)){ + $c->stash(layout=>'clean'); + $c->render(template=>'home/not_found', status=>404); + return; + } + my $pii = $c->req->json->{'payment_intent_id'}; + my $plan = $c->req->json->{'selected_plan'}//0; + my $api_confirm_path = "https://api.stripe.com/v1/payment_intents/$pii/confirm"; + + unless ($plan==0) {if ($plan->{count} > $max_time) { + log("\n\n max time instalment attempt\n\n"); + $c->render(json=>{'error'=>'max time error'}); + return 0; + }} + my $cplan=0; + + $cplan = [ + 'payment_method_options[card][installments][plan][type]'=>'fixed_count', + 'payment_method_options[card][installments][plan][interval]'=>'month', + 'payment_method_options[card][installments][plan][count]'=>$plan->{count}, + ] + unless ($plan==0); + my $r = stripeAppi($api_confirm_path,$cplan); + my $data=$c->mproc->intentCreate($c->req->json->{'tid'}); + my $rtt = { + 'status'=>$r->{'status'}, + 'plan' => $r->{'payment_method_options'}{'card'}{'installments'}{'plan'}, + }; + $c->render(json=>$rtt); + return 0; +} + +sub stripeAppi{ + my $sky='sk_test_GXWsfsoxy5336LrSw7SgTXNC00TV9O4Dbq'; + my ($path,$data) = @_; + my $req = POST $path, $data; + $req->authorization_basic($sky,''); + $req->content_type('application/x-www-form-urlencoded'); + my $ua = LWP::UserAgent->new; + my $res=$ua->request($req); + unless ($res->is_success){ + log("stripe error! path=$path\n data=".Dumper($data)."\n $res->status_line "); + return 0; + } + my $json = JSON->new->utf8; + return $json->decode($res->decoded_content); +} + +# Admin ======================================================================= + + + sub admin_eventos{ + my $c=shift; + if ( (my $t=$c->param('type') // "") =~/[ecp]/){ + my $id=$c->param('id'); + my $req=$c->param('req'); + if ( $req eq "Eliminar"){ + $c->dbv->event_del($id) if ($t eq 'e'); + $c->dbv->course_del($id) if ($t eq 'c'); + $c->dbv->place_del($id) if ($t eq 'p'); + } + elsif( $req eq "Aceptar"){ + if($t eq 'e'){ + my @list=map{$c->param($_)}qw/eplace yini mini dini yend mend dend cost promo pen ecourse eimg een id/; + $c->dbv->event_up(@list) if ($id ==0); + $c->dbv->event_ch(@list) if ($id >0); + } + if($t eq 'c'){ + my @list=map{$c->param($_)}qw/cname csubjects cservices cen id/; + $c->dbv->course_up(@list) if ($id ==0); + $c->dbv->course_ch(@list) if ($id >0); + } + if($t eq 'p'){ + my @list=map{$c->param($_)}qw/pname paddr pobs pto pst pco plat plng pen id/; + $c->dbv->place_up(@list) if ($id ==0); + $c->dbv->place_ch(@list) if ($id >0); + } + } + $c->redirect_to("/admin/eventos"); + } + + $c->stash( + courses=>$c->dbv->courses, + places=>$c->dbv->places, + months=>$c->dbv->months, + events=>$c->dbv->events, + img=>$c->dbv->eimgList, + ); + $c->stash(template=>"home/admin/event"); + $c->stash(layout=>"admin"); + } + sub admin_tienda{ + my $c=shift; + $c->stash(u=>$c->dbv->user_heads); + $c->stash(s=>$c->dbv->store_heads); + $c->stash(template=>"home/admin/tienda"); + $c->stash(layout=>"admin"); + + } + + sub admin_json{ + my $c=shift; + my $id = $c->param('id'); + my $req = $c->param('dreq'); + my $json = "304"; + $json = $c->dbv->astore($id) if $req=~/tienda/; + $json = $c->dbv->course($id) if $req=~/course/; + $json = $c->dbv->place($id) if $req=~/place/; + $json = $c->dbv->eventa($id) if $req=~/event/; + $c->render(json=>$json); + } + + +#============================================================================== + +1; diff --git a/lib/Dojo/Model/Data/admin/tienda/json/qStore.q b/lib/Dojo/Model/Data/admin/tienda/json/qStore.q old mode 100644 new mode 100755 diff --git a/lib/Dojo/Model/Data/admin/tienda/qStore.q b/lib/Dojo/Model/Data/admin/tienda/qStore.q old mode 100644 new mode 100755 diff --git a/lib/Dojo/Model/Data/cal/q1Block.q b/lib/Dojo/Model/Data/cal/q1Block.q index fed47e7..618d5e5 100755 --- a/lib/Dojo/Model/Data/cal/q1Block.q +++ b/lib/Dojo/Model/Data/cal/q1Block.q @@ -1,10 +1,6 @@ - select distinct - concat(mes.nombre,' ',year(evento.fecha_inicio)) as text, - date_format(evento.fecha_inicio,'%Y%m') as id - from evento - inner join mes on month(evento.fecha_inicio)=mes.id - where evento.estado=1 - order by evento.fecha_inicio - ; - + month(tienda_evento.fecha_inicio) as month, + year(tienda_evento.fecha_inicio) as year, + date_format(tienda_evento.fecha_inicio,'%Y%m') as id +from tienda_evento + where estado=1 and estore = 1; diff --git a/lib/Dojo/Model/Data/cal/q3Event.q b/lib/Dojo/Model/Data/cal/q3Event.q index 38015df..b1ce140 100755 --- a/lib/Dojo/Model/Data/cal/q3Event.q +++ b/lib/Dojo/Model/Data/cal/q3Event.q @@ -1,23 +1,20 @@ select - date_format(evento.fecha_inicio,'%Y%m') as bid, - evento.id as eeid, + date_format(tienda_evento.fecha_inicio,'%Y%m') as bid, + tienda_evento.id as eeid, concat(lugar.municipio,", ",lugar.federativa) as ciudad, concat(lugar.nombre,". ") as lugar, lugar.direccion as dir, - case when month(evento.fecha_inicio) = month(evento.fecha_fin) - then concat("Del ", day(evento.fecha_inicio)," al ",day(evento.fecha_fin)," de ",mi.nombre) - else concat("Del ",day(evento.fecha_inicio)," de ",mi.nombre," al ", - day(evento.fecha_fin)," de ", mo.nombre) - end as fecha, + day(tienda_evento.fecha_inicio) as dini, + day(tienda_evento.fecha_fin) as dfin, + month(tienda_evento.fecha_inicio) as mini, + month(tienda_evento.fecha_fin) as mfin, curso.nombre as nombre, - evento.imagen_chica as imagen_chica -from evento - inner join lugar on evento.lugar_id=lugar.id - inner join curso on evento.curso_id=curso.id - join mes as mi on mi.id=month(evento.fecha_inicio) - join mes as mo on mo.id=month(evento.fecha_fin) -where evento.estado=1 -order by evento.fecha_inicio + tienda_evento.imagen_chica as imagen_chica +from tienda_evento + inner join lugar on tienda_evento.lugar_id=lugar.id + inner join curso on tienda_evento.curso_id=curso.id +where tienda_evento.estado=1 and tienda_evento.estore=1 +order by tienda_evento.fecha_inicio ; diff --git a/lib/Dojo/Model/Data/event/qEvent.q b/lib/Dojo/Model/Data/event/qEvent.q index 3e2e6a9..38b04e9 100755 --- a/lib/Dojo/Model/Data/event/qEvent.q +++ b/lib/Dojo/Model/Data/event/qEvent.q @@ -1,4 +1,4 @@ - + select curso.nombre as cname, @@ -7,23 +7,20 @@ select lugar.direccion as paddr, lugar.observacion as pobs, lugar.municipio as city, - evento.precio as cost, - case evento.promo_estado when 1 then coalesce(evento.promocion,"") else "" end as promo, + tienda_evento.precio as cost, + tienda_evento.spay as spay, + case tienda_evento.promo_estado when 1 then coalesce(tienda_evento.promocion,"") else "" end as promo, curso.temario as csubjects, curso.servicios as cservices, - lugar.nombre as pname, - case when month(evento.fecha_inicio) = month(evento.fecha_fin) - then concat("Del ", day(evento.fecha_inicio)," al ",day(evento.fecha_fin)," de ",mi.nombre) - else concat("Del ",day(evento.fecha_inicio)," de ",mi.nombre," al ", - day(evento.fecha_fin)," de ", mo.nombre) - end as date - + day(tienda_evento.fecha_inicio) as dini, + day(tienda_evento.fecha_fin) as dend, + month(tienda_evento.fecha_inicio) as mini, + month(tienda_evento.fecha_fin) as mend - from evento - inner join lugar on evento.lugar_id=lugar.id - inner join curso on evento.curso_id=curso.id - join mes as mi on mi.id=month(evento.fecha_inicio) - join mes as mo on mo.id=month(evento.fecha_fin) - where evento.estado=1 - and evento.id = ? +from tienda_evento + inner join lugar on tienda_evento.lugar_id=lugar.id + inner join curso on tienda_evento.curso_id=curso.id + where tienda_evento.estado=1 + and tienda_evento.id = ? +; diff --git a/lib/Dojo/Model/Data/store/qEstore.q b/lib/Dojo/Model/Data/store/qEstore.q new file mode 100755 index 0000000..bfc63b7 --- /dev/null +++ b/lib/Dojo/Model/Data/store/qEstore.q @@ -0,0 +1,30 @@ +select + t.id as tid, + c.nombre as nombre, + c.subnombre as subnombre, + c.descripcion as descripcion, + c.maestro as maestro, + c.imagen_a as cimga, + c.imagen_b as cimgb, + c.imagen_c as cimgc, + day(t.fecha_inicio) as dini, + month(t.fecha_inicio) as mini, + day(t.fecha_fin) as dfin, + month(t.fecha_fin) as mfin, + t.precio as precio, + t.promocion as promo, + t.promo_estado as promo_estado, + t.playera_estado as playera_estado, + t.cupo as cupo, + l.nombre as lnombre, + l.federativa as federativa, + l.pais as pais, + l.municipio as municipio +from tienda_evento as t + join curso as c on c.id = t.curso_id + join lugar as l on l.id = t.lugar_id + +where t.id=? and t.estado =1 +; + + diff --git a/lib/Dojo/Model/Vdgproc.pm b/lib/Dojo/Model/Vdgproc.pm new file mode 100644 index 0000000..bff3bc6 --- /dev/null +++ b/lib/Dojo/Model/Vdgproc.pm @@ -0,0 +1,156 @@ +package Dojo::Model::Vdgproc; use Mojo::File 'path'; +use Mojo::JSON qw(decode_json encode_json); +use Dojo::Support qw{month_num2txt log dmph} ; +use Mojo::Base 'Mojolicious::Controller'; + + +use File::Basename; +use Encode qw(decode_utf8 encode_utf8); +use Text::Markdown qw{ markdown }; +use DBI; +use Dojo::Conf; + +sub new { bless {}, shift }; +my $data_path = path('lib/Dojo/Model/Data')->make_path; +#just for fun + + +sub calendar_monthblock { + my $r = _read ($data_path->child("cal/q1Block.q")->slurp); + map { $_->{fecha}=month_num2txt($_->{month})." ".$_->{year} } @$r; + return $r; +} + +sub mtxt { + my ($di, $mi, $df, $mf)=@_; # dini,mini,dfin,mfin + my $txt; + if ($mi == $mf){ + if ($di == $df){ $txt = "$di de ".month_num2txt($mi);} + else{ $txt = "Del $di al $df de ".month_num2txt($mi);} + } + else{ + $txt = "Del $di de ".month_num2txt($mi)." al $df de ".month_num2txt($mf); + } + return $txt; +} +sub calendar_events { + my $r = _read ($data_path->child("cal/q3Event.q")->slurp); + foreach (@$r) { $_->{fecha} = mtxt( $_->{dini},$_->{mini},$_->{dfin},$_->{mfin}) } + return $r; +} + +sub event{ + my ($c,$id)=@_; + my $r = shift @{ _read ($data_path->child("event/qEvent.q")->slurp,$id)}; + $r->{date} = mtxt( $r->{dini},$r->{mini},$r->{dend},$r->{mend}); + return $r; +} + +sub spay { + my ($c,$class,$id) = @_; + return _read ($data_path->child("/store/qIdStore.q")->slurp,$id)->[0]; +} + +# 4000004840000008 3, 6, 9, 12, and 18 month installment plans available +# "*p4000004840000008 +# 4242424242424242 No installment plans available. + +#============================================================================== +sub store_id { + my ($c,$class,$id) = @_; + my $r = _read ($data_path->child("/store/qEstore.q")->slurp,$id)->[0]; + $r->{fecha} = mtxt( $r->{dini},$r->{mini},$r->{dfin},$r->{mfin}); + return $r; +} +sub intentCreate{ + my ($c,$id) = @_; + my $q="select t.precio as precio, c.nombre as nombre from tienda_evento as t inner join curso as c on t.curso_id=c.id where t.id = ? ;"; + return _read ($q,$id)->[0]; +} +sub intentConfirm{ + my ($c,$id) = @_; + my $q="select t.precio as precio, c.nombre as nombre from tienda_evento as t inner join curso as c on t.curso_id=c.id where t.id = ? ;"; + return _read ($q,$id)->[0]; +} + +#============================================================================== + +# admin evets +sub event_del { return _write("delete from evento where id = ?;",pop);} +sub course_del{ return _write("delete from curso where id = ?;",pop); } +sub place_del { return _write("delete from lugar where id = ?;",pop); } + +sub event_up{ + my ($self,@bind)=@_; + return _write($data_path->child("/admin/event/add/qEup.q")->slurp,@bind); +} +sub course_up{ + my ($self,@bind)=@_; + return _write($data_path->child("/admin/event/add/qCup.q")->slurp,@bind); +} +sub place_up{ + my ($self,@bind)=@_; + return _write($data_path->child("/admin/event/add/qPup.q")->slurp,@bind); +} +sub event_ch{ + my ($self,@bind)=@_; + return _write($data_path->child("/admin/event/change/qEup.q")->slurp,@bind); +} +sub course_ch{ + my ($self,@bind)=@_; + return _write($data_path->child("/admin/event/change/qCup.q")->slurp,@bind); +} +sub place_ch{ + my ($self,@bind)=@_; + return _write($data_path->child("/admin/event/change/qPup.q")->slurp,@bind); +} + +#============================================================================== + +#ayudas ===================================== +sub tst{ + + my $c=shift; + my $d=$c->param('n'); + log("------log-------"); + log("$d"); + log("------log-------"); + return 0; +} + +sub _read{ + my ($q,@bind)=@_; + my @empty; + my $dbh = DBI->connect("DBI:mysql:".Dojo::Conf::VDGPROCDB.":".Dojo::Conf::VDGPROCDB_H,Dojo::Conf::VDGPROCDB_UR,Dojo::Conf::VDGPROCDB_URP, {mysql_enable_utf8 => 1}); + return \@empty unless($dbh); + my $h=$dbh->selectall_arrayref($q,{ Slice => {} },@bind)//"error"; + $dbh->disconnect(); + #((col1=>d1,col2=>d1),(col1=>d2,col2=>d2)) + return $h; +} + +sub _write{ + my ($q,@bind)=@_; + my (@empty); + my $dbh = DBI->connect("DBI:mysql:".Dojo::Conf::VDGPROCDB.":".Dojo::Conf::VDGPROCDB_H,Dojo::Conf::VDGPROCDB_UW,Dojo::Conf::VDGPROCDB_UWP,{mysql_enable_utf8 => 1} ); + return 0 unless($dbh); + my $h=$dbh->do($q,{ Slice => {} },@bind)//"error"; + $dbh->disconnect(); + log("db write: $h"); + return $h; +} + +sub load_md{ + return "" unless + my $text = path(shift)->slurp; + return markdown( decode_utf8($text) ); +} + +sub load_txt{ + return "" unless + my $text = path(shift)->slurp; + return decode_utf8($text); +} + +1; + diff --git a/lib/Dojo/Model/Vuelo.pm b/lib/Dojo/Model/Vuelo.pm index 394cadf..c957911 100755 --- a/lib/Dojo/Model/Vuelo.pm +++ b/lib/Dojo/Model/Vuelo.pm @@ -116,7 +116,7 @@ sub contact{ my $q="insert into entrada (nombre,correo,pagina,texto,fecha) values(?,?,?,?,now() )" ; my @a=@_; #simple method to ignore spam - return _writemsg($q,@a) unless $a[3]=~m/http|website|\p{ -margin-bottom: 30px; -color: black; -font-size: .875rem; -font-weight: 400; -line-height: 1.5; -min-width:250px; + margin-bottom: 30px; + color: black; + font-size: .875rem; + font-weight: 400; + line-height: 1.5; + min-width:250px; } p.promo{ -margin: 10px; -color: #c22a39; -font-size: 1.2em; + margin: 10px; + color: #c22a39; + font-size: 1.2em; } section.map{ -background-color:#333333; -overflow:hidden; - height:80vh; - min-height:400px; - position:relative; + background-color:#333333; + overflow:hidden; + height:80vh; + min-height:400px; + position:relative; } section.map > iframe{ - width:70%; - height:70%; - top:15%; - left:15%; - overflow: hidden; - position:absolute; + width:70%; + height:70%; + top:15%; + left:15%; + overflow: hidden; + position:absolute; } p.arrive{ position:absolute; @@ -89,6 +122,6 @@ p.arrive{ top:1%; font-size:1.5em; color:white; - } +} article.contact{ - } +} diff --git a/public/home/spay/grulla_10.jpg b/public/home/spay/grulla_10.jpg new file mode 100755 index 0000000..5e7a690 Binary files /dev/null and b/public/home/spay/grulla_10.jpg differ diff --git a/public/home/spay/storep.css b/public/home/spay/storep.css new file mode 100755 index 0000000..1bcf01a --- /dev/null +++ b/public/home/spay/storep.css @@ -0,0 +1,201 @@ + +section.item{ + background-color:rgba(255,255,255); + max-width: 1000px; + margin: auto; +} + +article.iimage{ + flex:5 1; + margin:auto; + display:inline; + padding:0px 5px; + +} +img.small{ + border-radius:20px; + display:block; + width:auto; + height:100%; + margin:auto; + padding:15px; +} +article.iinfo{ + background-color:white; + flex:4 1; + margin:0px 10px; +} +p.txt{ + font-size:1.2em; +} + +section.ibottom{ + background: #C22A39; + padding-bottom:1px; + padding-bottom:1px; + +} + +section.description{ + background-color:white; + justify-content: center; + -webkit-justify-content: center; +} + +p.promo{ + color: #c22a39; + font-size: 1.4em; + text-align:right; + margin-right:10%; + font-weight:bold; +} + + +p.elow{ + color: black; + font-size: 1.4em; + text-align:right; + margin-right:10%; +} + +p.eldep{ + color: #c22a39; + font-size: 1.4em; + text-align:right; + text-transform: uppercase; + margin-right:10%; + font-weight:bold; +} + +div.ppl{ + background-color: rgba(0,0,0,0.8); + border-radius: 25px; + padding:20px; + text-align: center; +} +p.nombre{ + font-size: 2.2em; + color: white; + text-align: left; + margin: auto; + max-width:850px; + font-weight:bold; +} + +p.tit{ + font-size: 1.8em; + color: white; + text-align: center; + margin: 30px auto; + font-style: italic; +} + +p.total{ + font-weight: bold; + font-size: 1.2em; + text-align: end; +} + +div#cover{ + background: black; + z-index: 100; + position: fixed; + width: 100%; + height: 100%; + transition:opacity .4s linear; + top:0px; + opacity:0; +} + /* * form css based on */ + /* * https://www.sanwebe.com/2014/08/css-html-forms-designs*/ + /* * thaks for make my life a bit easier*/ + /* ***************************************************************/ + +.form-style-1 { + margin:10px auto; + max-width: 400px; + padding: 20px 12px 10px 20px; + font: 13px "Lucida Sans Unicode", "Lucida Grande", sans-serif; +} +.form-style-1 li { + padding: 0; + display: block; + list-style: none; + margin: 10px 0 0 0; +} +.form-style-1 label{ + margin:0 0 3px 0; + padding:0px; + display:block; + font-weight: bold; +} +.form-style-1 input[type=text], +.form-style-1 input[type=date], +.form-style-1 input[type=datetime], +.form-style-1 input[type=number], +.form-style-1 input[type=search], +.form-style-1 input[type=time], +.form-style-1 input[type=url], +.form-style-1 input[type=email], +textarea, +select{ + box-sizing: border-box; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + border:1px solid #BEBEBE; + padding: 7px; + margin:0px; + -webkit-transition: all 0.30s ease-in-out; + -moz-transition: all 0.30s ease-in-out; + -ms-transition: all 0.30s ease-in-out; + -o-transition: all 0.30s ease-in-out; + outline: none; +} +.form-style-1 input[type=text]:focus, +.form-style-1 input[type=date]:focus, +.form-style-1 input[type=datetime]:focus, +.form-style-1 input[type=number]:focus, +.form-style-1 input[type=search]:focus, +.form-style-1 input[type=time]:focus, +.form-style-1 input[type=url]:focus, +.form-style-1 input[type=email]:focus, +.form-style-1 textarea:focus, +.form-style-1 select:focus{ + -moz-box-shadow: 0 0 8px #88D5E9; + -webkit-box-shadow: 0 0 8px #88D5E9; + box-shadow: 0 0 8px #88D5E9; + border: 1px solid #88D5E9; +} +.form-style-1 .field-divided{ + width: 49%; +} +.form-style-1 .field-mini{ + width: 5em; +} +.form-style-1 .field-long{ + width: 100%; +} +.form-style-1 .field-select{ + width: 100%; +} +.form-style-1 .field-textarea{ + height: 100px; +} + +.fbutton, +.form-style-1 input[type=submit], .form-style-1 input[type=button]{ + background: #4B99AD; + padding: 8px 15px 8px 15px; + border: none; + color: #fff; +} +.form-style-1 input[type=submit]:hover, .form-style-1 input[type=button]:hover{ + background: #4691A4; + box-shadow:none; + -moz-box-shadow:none; + -webkit-box-shadow:none; +} +.form-style-1 .required{ + color:red; +} + diff --git a/public/home/spay/stripe.js b/public/home/spay/stripe.js new file mode 100644 index 0000000..72dd88e --- /dev/null +++ b/public/home/spay/stripe.js @@ -0,0 +1,209 @@ +/* some format to numbers */ +var it=1; +var students = new Array(10); + +window.addEventListener('load', function() { + document.getElementById('cu').innerHTML=cu.toLocaleString(); + document.getElementById('gt').innerHTML=cu.toLocaleString(); +}); + +var mq = document.forms["cform"]["mq"]; +mq.addEventListener('change',function() { + var mult = cu*mq.value; + document.getElementById('gt').innerHTML=mult.toLocaleString(); +}); + +/* hide contact form, show card info fields */ +var cinfob = document.getElementById('cinfob'); +var cinfo = document.getElementById('cinfo'); +var cform = document.getElementById('cform'); +var ccard = document.getElementById('ccard'); +cinfob.addEventListener('click', function(ev){ + it --; + atof(); + if (it==1){cinfob.hidden=true;} + +}); + +cinfo.addEventListener('click', function(ev){ + if ( + (document.forms["cform"]["mname"].value =="") || + (document.forms["cform"]["mmail"].value =="") + ){console.log("form incomplete");} + else if ( mq.value > it) { + students[it - 1]=ftoa(); + it ++; + if(typeof students[it - 1]!== "undefined"){ + atof(); + } + cinfob.hidden=false; + } + else { + students[it - 1]=ftoa(); + cform.hidden = true; + ccard.hidden = false; + } +}); + +function ftoa(){ + var rad; + if (document.getElementById('r2').checked) { rad = document.getElementById('r2').value; } + else if(document.getElementById('r1').checked) { rad = document.getElementById('r1').value; } + else { rad = document.getElementById('r3').value; } + + var x= [ + document.forms["cform"]["mname"].value, + document.forms["cform"]["mmail"].value, + document.getElementById('obs').value, + rad + ] + var tmp=mq.value; + document.getElementById("cform").reset(); + mq.value=tmp; + + return x; +} + +function atof(){ + document.forms["cform"]["mname"].value = students[it-1][0]; + document.forms["cform"]["mmail"].value = students[it-1][1]; + document.getElementById('obs').value = students[it-1][2]; + if(document.getElementById('r2').value == students[it-1][3]){ document.getElementById('r2').checked=true;} + if(document.getElementById('r1').value == students[it-1][3]){ document.getElementById('r1').checked=true;} + if(document.getElementById('r3').value == students[it-1][3]){ document.getElementById('r3').checked=true;} +} + +/* stripe magic begins here */ +var stripe = Stripe('pk_test_wxFt0GhsUK2YsprkLXa2iFrQ00nfjAeucu'); +var elements = stripe.elements(); +var cardElement = elements.create('card', { + style: { + base: { + //iconColor: '#c4f0ff', + iconColor: '#64a0af', + color: '#000000', + fontWeight: 500, + fontFamily: 'Roboto, Open Sans, Segoe UI, sans-serif', + fontSize: '18px', + fontSmoothing: 'antialiased', + ':-webkit-autofill': { + color: '#fce883', + }, + '::placeholder': { + // color: '#87BBFD', + color: '#87BBFD', + }, + }, + invalid: { + iconColor: '#8f577e', + color: '#8F577E', + }, + }, +}); + +cardElement.mount('#card-element'); + +var cardholderName = document.getElementById('cardholder-name'); +var cardButton = document.getElementById('card-button'); + +///*y este el codigo de validación de la tarjeta*/ +cardButton.addEventListener('click', function(ev) { + document.getElementById('cover').hidden = false; + document.getElementById("cover").style.opacity = "0.8"; + stripe.createPaymentMethod('card', cardElement, { + billing_details: {name: cardholderName.value} + }) + .then(function(result) { + // Show error in payment form + if (result.error) { + document.getElementById("cover").style.opacity = "0"; + setTimeout(function(){ document.getElementById('cover').hidden = true;},500); + console.log("network error"); + } + // Otherwise send paymentMethod.id to your server (see Step 2) + else { + fetch('/spay/intentCreate', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ payment_method_id: result.paymentMethod.id, req:"precheck", qantity:mq.value, tid:tid}) + }) + .then(function(result) { + // Handle server response (see Step 3) + result.json().then(function(json) { handleInstallmentPlans(json); }) + }); + } + }); +}); + +///*presenta los planes de pago */ +const selectPlanForm = document.getElementById('installment-plan-form'); +let availablePlans = []; + +const handleInstallmentPlans = async (response) => { + if (response.error) { // Show error from server on payment form + console.log("preauth response error"); + } + else { + // Store the payment intent ID. + document.getElementById('payment-intent-id').value = response.intent_id; + availablePlans = response.available_plans; + // Show available installment options + availablePlans.forEach((plan, idx) => { + const newInput = document.getElementById('immediate-plan').cloneNode(); + newInput.setAttribute('value', idx); + newInput.setAttribute('id', ''); + const label = document.createElement('label'); + label.appendChild(newInput); + label.appendChild( + document.createTextNode(`${plan.count} meses`), + ); + selectPlanForm.appendChild(label); + }); + document.getElementById('ccard').hidden = true; + document.getElementById('cplan').hidden = false; + } + document.getElementById("cover").style.opacity = "0"; + setTimeout(function(){ document.getElementById('cover').hidden = true;},500); +}; + +// termina la transacción +const confirmButton = document.getElementById('confirm-button'); +confirmButton.addEventListener('click', async (ev) => { + document.getElementById('cover').hidden = false; + document.getElementById("cover").style.opacity = "0.8"; + const selectedPlanIdx = selectPlanForm.installment_plan.value; + const selectedPlan = availablePlans[selectedPlanIdx]; + const intentId = document.getElementById('payment-intent-id').value; + const response = await fetch('/spay/intentConfirm', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({ + payment_intent_id: intentId, + selected_plan: selectedPlan, + req:"check", + students:students, + mq:mq.value, + tid:tid + }), + }); + const responseJson = await response.json(); + // Show success / error response. + document.getElementById("cover").style.opacity = "0"; + setTimeout(function(){ document.getElementById('cover').hidden = true;},500); + document.getElementById('cmsg').hidden = false; + document.getElementById('cplan').hidden = true; + var message; + if (responseJson.status === "succeeded" && selectedPlan !== undefined) { + message = `¡Tu compra a ${ + selectedPlan.count + } meses sin intereses se ha realizado con éxito! `; + } else if (responseJson.status === "succeeded") { + message = "¡Tu compra se ha realizado con éxito!"; + } else { + message = `Tenemos un problema para verificar tus datos. + Por favor intenta de nuevo o comunícate con nosotros`; + } + + document.getElementById("status-message").innerText = message; +}); + diff --git a/public/home/store/img/China.jpg b/public/home/store/img/China.jpg new file mode 100755 index 0000000..870d653 Binary files /dev/null and b/public/home/store/img/China.jpg differ diff --git a/public/home/store/img/libro.jpg b/public/home/store/img/libro.jpg old mode 100644 new mode 100755 diff --git a/public/misc/stripe.js b/public/misc/stripe.js new file mode 100644 index 0000000..8fae3ec --- /dev/null +++ b/public/misc/stripe.js @@ -0,0 +1,131 @@ + +var stripe = Stripe('pk_test_wxFt0GhsUK2YsprkLXa2iFrQ00nfjAeucu'); +var elements = stripe.elements(); +var cardElement = elements.create('card', { + style: { + base: { + //iconColor: '#c4f0ff', + iconColor: '#64a0af', + color: '#000000', + fontWeight: 500, + fontFamily: 'Roboto, Open Sans, Segoe UI, sans-serif', + fontSize: '18px', + fontSmoothing: 'antialiased', + ':-webkit-autofill': { + color: '#fce883', + }, + '::placeholder': { + // color: '#87BBFD', + color: '#87BBFD', + }, + }, + invalid: { + iconColor: '#8f577e', + color: '#8F577E', + }, + }, +}); +cardElement.mount('#card-element'); + + +var cardholderName = document.getElementById('cardholder-name'); +var cardButton = document.getElementById('card-button'); + +///*y este el codigo de validación de la tarjeta*/ +cardButton.addEventListener('click', function(ev) { + document.getElementById('cover').hidden = false; + document.getElementById("cover").style.opacity = "0.8"; + stripe.createPaymentMethod('card', cardElement, { + billing_details: {name: cardholderName.value} + }) + .then(function(result) { + // Show error in payment form + if (result.error) { + document.getElementById("cover").style.opacity = "0"; + setTimeout(function(){ document.getElementById('cover').hidden = true;},500); + console.log("network error"); + } + // Otherwise send paymentMethod.id to your server (see Step 2) + else { + fetch('/xpay', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ payment_method_id: result.paymentMethod.id, req:"precheck"}) + }) + .then(function(result) { + // Handle server response (see Step 3) + result.json().then(function(json) { handleInstallmentPlans(json); }) + }); + } + }); +}); + +///*presenta los planes de pago */ +const selectPlanForm = document.getElementById('installment-plan-form'); +let availablePlans = []; + +const handleInstallmentPlans = async (response) => { + if (response.error) { // Show error from server on payment form + console.log("preauth response error"); + } + else { + // Store the payment intent ID. + document.getElementById('payment-intent-id').value = response.intent_id; + availablePlans = response.available_plans; + // Show available installment options + availablePlans.forEach((plan, idx) => { + const newInput = document.getElementById('immediate-plan').cloneNode(); + newInput.setAttribute('value', idx); + newInput.setAttribute('id', ''); + const label = document.createElement('label'); + label.appendChild(newInput); + label.appendChild( + document.createTextNode(`${plan.count} meses`), + ); + selectPlanForm.appendChild(label); + }); + document.getElementById('cinfo').hidden = true; + document.getElementById('cplan').hidden = false; + } + document.getElementById("cover").style.opacity = "0"; + setTimeout(function(){ document.getElementById('cover').hidden = true;},500); +}; + +// termina la transacción +const confirmButton = document.getElementById('confirm-button'); +confirmButton.addEventListener('click', async (ev) => { + document.getElementById('cover').hidden = false; + document.getElementById("cover").style.opacity = "0.8"; + const selectedPlanIdx = selectPlanForm.installment_plan.value; + const selectedPlan = availablePlans[selectedPlanIdx]; + const intentId = document.getElementById('payment-intent-id').value; + const response = await fetch('/xpay', { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({ + payment_intent_id: intentId, + selected_plan: selectedPlan, + req:"check" + }), + }); + const responseJson = await response.json(); + // Show success / error response. + document.getElementById("cover").style.opacity = "0"; + setTimeout(function(){ document.getElementById('cover').hidden = true;},500); + document.getElementById('cmsg').hidden = false; + document.getElementById('cplan').hidden = true; + var message; + if (responseJson.status === "succeeded" && selectedPlan !== undefined) { + message = `¡Tu compra a ${ + selectedPlan.count + } meses sin intereses se ha realizado con éxito! `; + } else if (responseJson.status === "succeeded") { + message = "¡Tu compra se ha realizado con éxito!"; + } else { + message = `Tenemos un problema para verificar tus datos. + Por favor intenta de nuevo o comunícate con nosotros`; + } + + document.getElementById("status-message").innerText = message; +}); + diff --git a/public/misc/xpay.css b/public/misc/xpay.css new file mode 100644 index 0000000..b8d6daa --- /dev/null +++ b/public/misc/xpay.css @@ -0,0 +1,44 @@ +html{font-family:"serif";} +section.title{ + /*background-color:#2f2c2c;*/ + /*color:white;*/ +} + +article.title{ +} + +h2{ +} +h1{ +} +div#cover{ + background: black; + z-index: 85; + position: fixed; + width: 100%; + height: 100%; + transition:opacity .4s linear; + top:0px; + opacity:0; +} +section.cardinfo{ +} +div#details{ + min-width:504px; +} +form{ + text-align:center; +} +label{ + text-align:center; + margin:auto; +} +input{ + display:block; + margin:auto; +} + +button{ +} +div#card-element{ +} diff --git a/templates/layouts/xpay.html.ep b/templates/layouts/xpay.html.ep new file mode 100755 index 0000000..4baedbc --- /dev/null +++ b/templates/layouts/xpay.html.ep @@ -0,0 +1,49 @@ + + + + <%= title %> + + + + <%= javascript "/ext/d3.v4.min.js"; %> + <%= stylesheet "/global/layout.css" %> + <%= stylesheet "/global/chaos/c.css" %> + + <% map{%><%= stylesheet "$_"%><%}(@{stash('css')}) if defined(stash('css'));%> + + +

Beijing Wisdom

Healing Center

+ <% map{%><%= include "$_"%><%}(@{stash('prepend')}) + if defined(stash('prepend'));%> + <%= content %> + <% map{%><%= include "$_"%><%}(@{stash('apend')}) + if defined(stash('apend'));%> + %= include 'home/htmlChaos' + <% map{%><%= javascript "$_"%><%}(@{stash('js')}) if defined(stash('js'));%> + + + diff --git a/templates/misc/stripe.html.ep b/templates/misc/stripe.html.ep new file mode 100644 index 0000000..ebaecda --- /dev/null +++ b/templates/misc/stripe.html.ep @@ -0,0 +1,56 @@ + +% stash css => ["misc/xpay.css"]; +% stash js => ["misc/stripe.js"]; +
+

<%== $header %>

+
+
+
+

<%= $title %>

+

<%= $subtitle %>

+
+
+ +
+ +
+

Datos de la tarjeta

+
+ + + + +
+ +
+
+ + +
diff --git a/templates/home/cal.html.ep b/templates/proc/cal.html.ep similarity index 97% rename from templates/home/cal.html.ep rename to templates/proc/cal.html.ep index a919d56..1ae5490 100755 --- a/templates/home/cal.html.ep +++ b/templates/proc/cal.html.ep @@ -4,7 +4,7 @@ % foreach (@$b) {

- <%= $_->{text} %> + <%= $_->{fecha} %>

diff --git a/templates/proc/estore.html.ep b/templates/proc/estore.html.ep new file mode 100755 index 0000000..fb80deb --- /dev/null +++ b/templates/proc/estore.html.ep @@ -0,0 +1,24 @@ +%stash css=>["/home/storep/storep.css"]; +
+
+

<%= $nombre %>

+

<%= $lmunicipio %>, <%= $lfederativa %>

+
+
+ +
+
+

<%= $subnombre %>

+

<%= $descripcion %>

+

<%= $promocion %>

+

Precio:$<%= $precio %> pesos

+

+ <% if ($cupo > 10) { =%>

<% } =%> + <% elsif ($cupo >= 5) { =%>

¡Nos quedan pocos lugarel!

<% } =%> + <% elsif ($cupo == 0) { =%>

¡Agotado!

<% } =%> +
+
+
+
+ + diff --git a/templates/home/event.html.ep b/templates/proc/event.html.ep similarity index 87% rename from templates/home/event.html.ep rename to templates/proc/event.html.ep index d115977..9f9b882 100755 --- a/templates/home/event.html.ep +++ b/templates/proc/event.html.ep @@ -5,6 +5,9 @@

<%= $cname %>

<%= $place %>

+ <% if ($spay== 1) { =%> + »Inscríbete + <% } =%>
@@ -13,7 +16,9 @@

<%= $paddr %>

<%= $pobs %>

<%= $city %>

+ <% if ($spay== 1) { =%>

<%= $cost %>

+ <% } =%>

<%= $promo %>

diff --git a/templates/proc/spay.html.ep b/templates/proc/spay.html.ep new file mode 100755 index 0000000..9b34d4b --- /dev/null +++ b/templates/proc/spay.html.ep @@ -0,0 +1,104 @@ +%stash css=>["/home/spay/storep.css"]; +%stash js => ["/home/spay/stripe.js"]; + + +
+

<%= $nombre %>

+

<%= $municipio %>, <%= $federativa %>

+
+ +
+ + +
+

<%= $subnombre %>

+ +

<%= $descripcion %>

+
+ +
+

<%= $fecha %>

+

<%= $promo %>

+

+ <% if ($cupo > 10) { =%>

<% } =%> + <% elsif ($cupo >= 5) { =%>

¡Nos quedan pocos!

<% } =%> + <% elsif ($cupo == 0) { =%>

¡Agotado!

<% } =%> + +
+ +

Costo por asistente: $ pesos

+
    +
  • + + +
  • +
  • + + +
  • +
  • + + +
  • +
  • + + CH + M + G +
  • +
  • + + +
  • +
  • +

    Total = $ pesos

    +
  • +
  • + + +
  • +
+
+ + + + + + + +
+
+
+ diff --git a/templates/home/store.html.ep b/templates/proc/store.html.ep similarity index 100% rename from templates/home/store.html.ep rename to templates/proc/store.html.ep diff --git a/templates/home/storep.html.ep b/templates/proc/storep.html.ep similarity index 100% rename from templates/home/storep.html.ep rename to templates/proc/storep.html.ep diff --git a/templates/users/reg.html.ep b/templates/users/reg.html.ep old mode 100644 new mode 100755