diff --git a/lib/NGCP/Panel/Controller/Customer.pm b/lib/NGCP/Panel/Controller/Customer.pm index 127b700b00..31b9fb15a7 100644 --- a/lib/NGCP/Panel/Controller/Customer.pm +++ b/lib/NGCP/Panel/Controller/Customer.pm @@ -848,11 +848,6 @@ sub calls_svg :Chained('base') :PathPart('calls/template') :Args { $in->{contract_id} = $c->stash->{contract}->id; $in->{tt_string} = $c->request->body_parameters->{template} || ''; - #use irka; - #use Data::Dumper; - #irka::loglong(Dumper($in)); - #return; - #output 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 - #just use as already implemented fields checking and defaults applying + #just use as already implemented fields checking and defaults applying $validator->setup_form( posted => 1, params => $in, ); - + #multi return... $c->log->debug("validated=".$validator->validated.";\n"); + if(!$validator->validated){ + return; + } my $in_validated = $validator->fif; - #dirty hack - $in = $in_validated; + #use irka; + #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? - #real logic + #dirty hack 2 + #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_customer = ''; 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 if($in->{tt_string} || !$tt_string_customer || $tt_string_force_default ){ 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 ); } catch($e) { 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){ #sanitize my $tt_string_sanitized = $in->{tt_string}; + $tt_string_sanitized =~s///gs; my $tokens_re = qr/\[%(.*?)%\]/; my $token_shape_re = qr/\s+/; 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 ){ my $token_shape=$_; $token_shape=~s/$token_shape_re//sg; 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( %$in, 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 $output_string = $tt_string_customer; } - #if($tt_string){ - #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 !~/^/is).";\n"); -##### if( $tt_string !~/^/is ){ -##### (my ($width)) = ($tt_string =~/^/is ); -##### $c->log->debug("width=$width;\n"); -##### (my ($height)) = ($tt_string =~/^/is ); -##### my($replaced) = $output_string =~s/^log->debug("replaced=$replaced;\n"); -##### #storeToDB -##### } - #} + #/model logic #prepare response - $c->response->content_type('image/svg+xml'); - #$c->log->debug("tt_viewmode=".$in->{tt_viewmode}.";\n"); - $c->log->debug("tt_viewmode=;\n"); + #mess,mess,mess here + if($in->{tt_type} eq 'svg'){ + $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'){ #$c->stash->{VIEW_NO_TT_PROCESS} = 1; $c->response->body($output_string); return; }else{ + my $contacts = $c->model('DB')->resultset('contacts')->search({ id => $in->{contract_id} }); #some preprocessing should be done only before showing. So, there will be: #preSaveCustomTemplate prerpocessing @@ -966,11 +971,15 @@ sub calls_svg :Chained('base') :PathPart('calls/template') :Args { } $c->stash( provider => $contacts->first ); - #use irka; - #irka::loglong(\$output_string); - $c->stash( template => \$output_string ); - $c->log->debug("before_detach;\n"); - $c->detach($c->view('SVG')); + + if($in->{tt_type} eq 'svg'){ + #$c->response->content_type('image/svg+xml'); + $c->stash( template => \$output_string ); + $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); + } } } diff --git a/lib/NGCP/Panel/Form/Customer/InvoiceTemplate.pm b/lib/NGCP/Panel/Form/Customer/InvoiceTemplate.pm index 0152513ac3..4b6de5ba95 100644 --- a/lib/NGCP/Panel/Form/Customer/InvoiceTemplate.pm +++ b/lib/NGCP/Panel/Form/Customer/InvoiceTemplate.pm @@ -4,10 +4,11 @@ use HTML::FormHandler::Moose; extends 'HTML::FormHandler'; 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 'TemplateSourceState' => [ qw/saved previewed default/ ]; -no Moose::Util::TypeConstraints; +#no Moose::Util::TypeConstraints; has '+use_fields_for_input_without_param' => ( default => 1 ); @@ -15,8 +16,20 @@ has_field 'tt_type' => ( type => 'Text', required => 1, default => 'svg', - #apply => [ qw/svg/ ], - apply => [ 'TemplateType' ], + apply => [ + { 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' => ( @@ -56,9 +69,33 @@ has_field 'tt_id' => ( 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 +#}; +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; diff --git a/lib/NGCP/Panel/View/SVG.pm b/lib/NGCP/Panel/View/SVG.pm index 30de3f3bfc..3f60ed6a7c 100644 --- a/lib/NGCP/Panel/View/SVG.pm +++ b/lib/NGCP/Panel/View/SVG.pm @@ -38,17 +38,26 @@ sub process } return 1; } -#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{ +sub getTemplate{ my ( $self, $c, $template ) = @_; if(defined $template){ $c->log->debug("getTemplateContent: template=$template;"); } $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; \ No newline at end of file