MT#5879 Sub validate in InvoiceTemplate form doesn't work. Start of PDF generation.

ipeshinskaya/InvoiceTemplate5
Irina Peshinskaya 11 years ago committed by Victor Seva
parent 3e537588ee
commit bb69a3ef5f

@ -848,11 +848,6 @@ sub calls_svg :Chained('base') :PathPart('calls/template') :Args {
$in->{contract_id} = $c->stash->{contract}->id; $in->{contract_id} = $c->stash->{contract}->id;
$in->{tt_string} = $c->request->body_parameters->{template} || ''; $in->{tt_string} = $c->request->body_parameters->{template} || '';
#use irka;
#use Data::Dumper;
#irka::loglong(Dumper($in));
#return;
#output #output
my $output_string; my $output_string;
@ -868,21 +863,35 @@ sub calls_svg :Chained('base') :PathPart('calls/template') :Args {
#really, we don't need a form here at all #really, we don't need a form here at all
#just use as already implemented fields checking and defaults applying #just use as already implemented fields checking and defaults applying
$validator->setup_form( $validator->setup_form(
posted => 1, posted => 1,
params => $in, params => $in,
); );
#multi return...
$c->log->debug("validated=".$validator->validated.";\n"); $c->log->debug("validated=".$validator->validated.";\n");
if(!$validator->validated){
return;
}
my $in_validated = $validator->fif; my $in_validated = $validator->fif;
#dirty hack #use irka;
$in = $in_validated; #use Data::Dumper;
#irka::loglong(Dumper($in));
#irka::loglong(Dumper($in_validated));
#dirty hack 1
$in = $in_validated;
#really this is for code for field default in validator. The question is how to pass DB model to validator (formhandler) - ideologically correctly? #dirty hack 2
#real logic #validate methods don't work in form configuration, will find why later
if($in->{tt_type} eq 'svgpdf'){
$in->{tt_type} = 'svg';
$in->{tt_output_type} = 'pdf';
}
#model logic
my $tt_string_default = ''; my $tt_string_default = '';
my $tt_string_customer = ''; my $tt_string_customer = '';
my $tt_string_force_default = $in->{tt_sourcestate} eq 'default'; my $tt_string_force_default = $in->{tt_sourcestate} eq 'default';
@ -895,7 +904,7 @@ sub calls_svg :Chained('base') :PathPart('calls/template') :Args {
#we need to get default to 1) sanitize (if in->tt_string) or 2)if not in->tt_string and no customer->tt_string #we need to get default to 1) sanitize (if in->tt_string) or 2)if not in->tt_string and no customer->tt_string
if($in->{tt_string} || !$tt_string_customer || $tt_string_force_default ){ if($in->{tt_string} || !$tt_string_customer || $tt_string_force_default ){
try{ try{
#Utils... mmm - maybe model? #Utils... mmm - if it were model - there would be no necessity in utils using
NGCP::Panel::Utils::InvoiceTemplate::getDefaultInvoiceTemplate( c => $c, result => \$tt_string_default ); NGCP::Panel::Utils::InvoiceTemplate::getDefaultInvoiceTemplate( c => $c, result => \$tt_string_default );
} catch($e) { } catch($e) {
NGCP::Panel::Utils::Message->error( NGCP::Panel::Utils::Message->error(
@ -907,17 +916,23 @@ sub calls_svg :Chained('base') :PathPart('calls/template') :Args {
if($in->{tt_string} && !$tt_string_force_default){ if($in->{tt_string} && !$tt_string_force_default){
#sanitize #sanitize
my $tt_string_sanitized = $in->{tt_string}; my $tt_string_sanitized = $in->{tt_string};
$tt_string_sanitized =~s/<script.*?\/script>//gs;
my $tokens_re = qr/\[%(.*?)%\]/; my $tokens_re = qr/\[%(.*?)%\]/;
my $token_shape_re = qr/\s+/; my $token_shape_re = qr/\s+/;
my %tokens_valid = map{$_=~s/$token_shape_re//sg; $_ => 1;} ($tt_string_default=~/$tokens_re/sg); my %tokens_valid = map{$_=~s/$token_shape_re//sg; $_ => 1;} ($tt_string_default=~/$tokens_re/sg);
#use irka;
#use Data::Dumper;
#irka::loglong(Dumper(\%tokens_valid));
foreach( $tt_string_sanitized=~/$tokens_re/sg ){ foreach( $tt_string_sanitized=~/$tokens_re/sg ){
my $token_shape=$_; my $token_shape=$_;
$token_shape=~s/$token_shape_re//sg; $token_shape=~s/$token_shape_re//sg;
if(! exists $tokens_valid{$token_shape}){ if(! exists $tokens_valid{$token_shape}){
$tt_string_sanitized=~s/\Q$_\E//g; $c->log->debug('Not allowed token in invoice template:'.$_.";\n");
$tt_string_sanitized=~s/(?:\[%)+\s*\Q$_\E\s*(?:%\])+//g;
} }
} }
#irka::loglong(Dumper($tt_string_sanitized));
$backend->storeCustomerInvoiceTemplate( $backend->storeCustomerInvoiceTemplate(
%$in, %$in,
tt_string_sanitized => \$tt_string_sanitized, tt_string_sanitized => \$tt_string_sanitized,
@ -930,31 +945,21 @@ sub calls_svg :Chained('base') :PathPart('calls/template') :Args {
}else{#we have customer template, we don't have dynamic template string, we weren't requested to show default }else{#we have customer template, we don't have dynamic template string, we weren't requested to show default
$output_string = $tt_string_customer; $output_string = $tt_string_customer;
} }
#if($tt_string){ #/model logic
#sub candidate, preSaveCustomTemplate
#if it is presaving, making it for default isn't necessary, default should contain it
#but while let it be here
##moved to correct place - to js, generating svg
##### $c->log->debug("3.tt_string is empty=".($tt_string?0:1).";viewbox=".($tt_string !~/^<svg.*?viewbox.*?>/is).";\n");
##### if( $tt_string !~/^<svg.*?viewbox.*?>/is ){
##### (my ($width)) = ($tt_string =~/^<svg.*?width.*?(\d+).*?>/is );
##### $c->log->debug("width=$width;\n");
##### (my ($height)) = ($tt_string =~/^<svg.*?height.*?(\d+).*?>/is );
##### my($replaced) = $output_string =~s/^<svg(.*?(?:width.*?height|height.*width).*?\d+.*? )/<svg $1 viewBox="0 0 $width $height" /i;
##### $c->log->debug("replaced=$replaced;\n");
##### #storeToDB
##### }
#}
#prepare response #prepare response
$c->response->content_type('image/svg+xml'); #mess,mess,mess here
#$c->log->debug("tt_viewmode=".$in->{tt_viewmode}.";\n"); if($in->{tt_type} eq 'svg'){
$c->log->debug("tt_viewmode=;\n"); $c->response->content_type('image/svg+xml');
}elsif($in->{tt_type} eq 'pdf'){
$c->response->content_type('application/pdf');
}
if($in->{tt_viewmode} eq 'raw'){ if($in->{tt_viewmode} eq 'raw'){
#$c->stash->{VIEW_NO_TT_PROCESS} = 1; #$c->stash->{VIEW_NO_TT_PROCESS} = 1;
$c->response->body($output_string); $c->response->body($output_string);
return; return;
}else{ }else{
my $contacts = $c->model('DB')->resultset('contacts')->search({ id => $in->{contract_id} }); my $contacts = $c->model('DB')->resultset('contacts')->search({ id => $in->{contract_id} });
#some preprocessing should be done only before showing. So, there will be: #some preprocessing should be done only before showing. So, there will be:
#preSaveCustomTemplate prerpocessing #preSaveCustomTemplate prerpocessing
@ -966,11 +971,15 @@ sub calls_svg :Chained('base') :PathPart('calls/template') :Args {
} }
$c->stash( provider => $contacts->first ); $c->stash( provider => $contacts->first );
#use irka;
#irka::loglong(\$output_string); if($in->{tt_type} eq 'svg'){
$c->stash( template => \$output_string ); #$c->response->content_type('image/svg+xml');
$c->log->debug("before_detach;\n"); $c->stash( template => \$output_string );
$c->detach($c->view('SVG')); $c->detach($c->view('SVG'));
}elsif($in->{tt_type} eq 'pdf'){
#$c->response->content_type('application/pdf');
my $svg = $c->view('SVG')->getTemplateProcessed($c,$output_string);
}
} }
} }

@ -4,10 +4,11 @@ use HTML::FormHandler::Moose;
extends 'HTML::FormHandler'; extends 'HTML::FormHandler';
use Moose::Util::TypeConstraints; use Moose::Util::TypeConstraints;
enum 'TemplateType' => [ qw/svg html/ ];#html enum 'TemplateType' => [ qw/svg html svgpdf/ ];#html
enum 'TemplateTypeOutput' => [ qw/svg html pdf/ ];#html
enum 'TemplateViewMode' => [ qw/raw parsed/ ]; enum 'TemplateViewMode' => [ qw/raw parsed/ ];
enum 'TemplateSourceState' => [ qw/saved previewed default/ ]; enum 'TemplateSourceState' => [ qw/saved previewed default/ ];
no Moose::Util::TypeConstraints; #no Moose::Util::TypeConstraints;
has '+use_fields_for_input_without_param' => ( default => 1 ); has '+use_fields_for_input_without_param' => ( default => 1 );
@ -15,8 +16,20 @@ has_field 'tt_type' => (
type => 'Text', type => 'Text',
required => 1, required => 1,
default => 'svg', default => 'svg',
#apply => [ qw/svg/ ], apply => [
apply => [ 'TemplateType' ], { type => 'TemplateType' },
#{ transform => sub{ $_[0] eq 'svgpdf' and return 'svg'; } },
],
);
has_field 'tt_output_type' => (
type => 'Text',
required => 1,
default => 'svg',
apply => [
{ type => 'TemplateTypeOutput' },
#{ when => { tt_type => 'svgpdf' }, transform => sub{ 'pdf' } },
],
); );
has_field 'tt_viewmode' => ( has_field 'tt_viewmode' => (
@ -56,9 +69,33 @@ has_field 'tt_id' => (
required => 0, required => 0,
); );
sub validate_tt_string{ #sub validate_tt_string{
#here could be following: take default from file and get all variables and validate variables from customer string #here could be following: take default from file and get all variables and validate variables from customer string
#};
sub validate_tt_type {
my ( $self, $field ) = @_; # self is the form
use irka;
use Data::Dumper;
irka::loglong("\n\n\nin validate\naaaaaaaaaaaaaaaaaaaaa\naaaaaaaaaaaaaaa\n");
die();
if( $self->field('tt_type')->value eq 'svgpdf'){
$self->field('tt_output_type')->value('pdf');
$self->field('tt_type')->value('svg');
}
return 1;
}; };
sub validate {
my $self = shift;
use irka;
use Data::Dumper;
irka::loglong("\n\n\nin validate\naaaaaaaaaaaaaaaaaaaaa\naaaaaaaaaaaaaaa\n");
die();
if( $self->field('tt_type')->value eq 'svgpdf'){
$self->field('tt_output_type')->value('pdf');
$self->field('tt_type')->value('svg');
}
return 1;
}
1; 1;

@ -38,17 +38,26 @@ sub process
} }
return 1; return 1;
} }
#method is necessary to apply APP specific template configurations, e.g. path, tt file extensions etc sub getTemplate{
#may be moved to main view class, but as on template_invoice experiments stage it would be ok to leave it in separated class
sub getTemplateContent{
my ( $self, $c, $template ) = @_; my ( $self, $c, $template ) = @_;
if(defined $template){ if(defined $template){
$c->log->debug("getTemplateContent: template=$template;"); $c->log->debug("getTemplateContent: template=$template;");
} }
$template ||= ( $c->stash->{template} || $c->action . $self->config->{TEMPLATE_EXTENSION} ); $template ||= ( $c->stash->{template} || $c->action . $self->config->{TEMPLATE_EXTENSION} );
$c->log->debug("getTemplateContent: template=$template;"); $c->log->debug("getTemplate: template=$template;");
return $template;
}
#method is necessary to apply APP specific template configurations, e.g. path, tt file extensions etc
#may be moved to main view class, but as on template_invoice experiments stage it would be ok to leave it in separated class
sub getTemplateContent{
my ( $self, $c, $template ) = @_;
return $self->{template}->context->insert($self->getTemplate($c,$template));
}
sub getTemplateProcessed{
my ( $self, $c, $template ) = @_;
return $self->{template}->context->insert($template); return $self->{template}->context->process($self->getTemplate($c,$template));
} }
1; 1;
Loading…
Cancel
Save