MT#5879 Datatables is shown now for invoice data but search doesn't work. Anyway switch now to invoices generation and will return to datatables later.

Done:
1.Form separated for future possible load through ajax.
2.Activity switch in invoice templates table
ipeshinskaya/InvoiceTemplate5
Irina Peshinskaya 12 years ago committed by Victor Seva
parent 26142a1431
commit f6fe84df61

@ -827,10 +827,76 @@ sub invoice_data :Chained('base') :PathPart('invoice') :CaptureArgs(0) {
etime => $etime, etime => $etime,
); );
#TODO: FAKE FAKE FAKE FAKE #TODO: FAKE FAKE FAKE FAKE
$invoice_details = [$invoice_details->all()]; my $invoice_details_raw = $invoice_details;
$invoice_details = [$invoice_details_raw->all()];
my $i = 1; my $i = 1;
$invoice_details = [map{[$i++,$_]} (@$invoice_details) x 21]; $invoice_details = [map{[$i++,$_]} (@$invoice_details) x 21];
$c->stash(invoice_details => $invoice_details ); $c->stash( invoice_details => $invoice_details );
$c->stash( invoice_details_raw => $invoice_details_raw );
}
sub invoice_details_ajax :Chained('base') :PathPart('invoice/details/ajax') :Args(0) {
my ($self, $c) = @_;
my $dt_columns_json = $c->request->parameters->{dt_columns};
use JSON;
#use irka;
#use Data::Dumper;
#irka::loglong(Dumper($dt_columns));
$c->forward( 'invoice_data' );
my $dt_columns = from_json($dt_columns_json);
NGCP::Panel::Utils::Datatables::process($c, $c->stash->{invoice_details_raw}, $dt_columns );
$c->detach( $c->view("JSON") );
}
sub invoice_template_activate :Chained('base') :PathPart('invoice_template/activate') :Args(1) {
my ($self, $c) = @_;
$c->log->debug('invoice_template_activate');
my($validator,$backend,$in,$out);
(undef,undef,@$in{qw/tt_id/}) = @_;
#check that this id really belongs to specified contract? or just add contract condition to delete query?
#checking is more universal
#this is just copy-paste from method above
#of course we are chained and we can put in and out to stash
#input
$in->{contract_id} = $c->stash->{contract}->id;
#output
$out={};
#storage
#pass scheme here is ugly, and should be moved somehow to DB::Base
$backend = NGCP::Panel::Model::DB::InvoiceTemplate->new( schema => $c->model('DB') );
#input checking & simple preprocessing
$validator = NGCP::Panel::Form::Customer::InvoiceTemplate->new( backend => $backend );
# $form->schema( $c->model('DB::InvoiceTemplate')->schema );
#to common form package ? removing is necessary due to FormHandler param presence evaluation - it is based on key presence, not on defined/not defined value
#in future this method should be called by ControllerBase
$validator->remove_undef_in($in);
#really, we don't need a form here at all
#just use as already implemented fields checking and defaults applying
#$validator->setup_form(
$validator->process(
posted => 1,
params => $in,
);
#$validator->validate_form();
#multi return...
$c->log->debug("validated=".$validator->validated.";\n");
if(!$validator->validated){
return;
}
my $in_validated = $validator->fif;
#dirty hack 1
#really model logic should recieve validated input, but raw input also should be saved somewhere
$in = $in_validated;
#think about it more
$backend->activateCustomerInvoiceTemplate(%$in);
$c->forward( 'invoice_template_list' );
} }
sub invoice_template_delete :Chained('base') :PathPart('invoice_template/delete') :Args(1) { sub invoice_template_delete :Chained('base') :PathPart('invoice_template/delete') :Args(1) {
my ($self, $c) = @_; my ($self, $c) = @_;
@ -883,6 +949,7 @@ sub invoice_template_delete :Chained('base') :PathPart('invoice_template/delete'
$backend->deleteCustomerInvoiceTemplate(%$in); $backend->deleteCustomerInvoiceTemplate(%$in);
$c->forward( 'invoice_template_list' ); $c->forward( 'invoice_template_list' );
} }
sub invoice_template_list_data :Chained('invoice_data') :PathPart('') :CaptureArgs(0) { sub invoice_template_list_data :Chained('invoice_data') :PathPart('') :CaptureArgs(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
$c->log->debug('invoice_template_list_data'); $c->log->debug('invoice_template_list_data');

@ -96,13 +96,7 @@ sub storeCustomerInvoiceTemplate{
}); });
} }
if($is_active && $tt_id){ if($is_active && $tt_id){
$self->schema->resultset('invoice_template')->search({ $self->deactivateOtherTemplates($contract_id,$tt_id);
reseller_id => $contract_id,
type => $tt_type,
id => {'!=' => $tt_id },
})->update_all({
is_active => 0,
});
} }
}); });
return { tt_id => $tt_id }; return { tt_id => $tt_id };
@ -112,6 +106,10 @@ sub getCustomerInvoiceTemplateList{
my (%params) = @_; my (%params) = @_;
my ($contract_id,$tt_sourcestate,$tt_type, $tt_string, $tt_id) = @params{qw/contract_id tt_sourcestate tt_type tt_string_sanitized tt_id/}; my ($contract_id,$tt_sourcestate,$tt_type, $tt_string, $tt_id) = @params{qw/contract_id tt_sourcestate tt_type tt_string_sanitized tt_id/};
#return [
#$self->schema->resultset('invoice_template_fake')->find(\'select * from invoice_template')->all
#$self->schema->resultset('invoice_template')->name(\'(select * from invoice_template)')->all
#];
return [ $self->schema->resultset('invoice_template')->search({ return [ $self->schema->resultset('invoice_template')->search({
reseller_id => $contract_id, reseller_id => $contract_id,
})->all ]; })->all ];
@ -125,6 +123,31 @@ sub deleteCustomerInvoiceTemplate{
id => $tt_id, id => $tt_id,
})->delete_all; })->delete_all;
} }
sub activateCustomerInvoiceTemplate{
my $self = shift;
my (%params) = @_;
my ($contract_id,$tt_id) = @params{qw/contract_id tt_id/};
$self->schema->txn_do(sub {
$self->schema->resultset('invoice_template')->search({
reseller_id => $contract_id,
id => $tt_id,
})->update({
is_active => 1,
});
$self->deactivateOtherTemplates($contract_id,$tt_id);
});
}
sub deactivateOtherTemplates{
my $self = shift;
my ($contract_id,$tt_id) = @_;
$self->schema->resultset('invoice_template')->search({
reseller_id => $contract_id,
id => {'!=' => $tt_id },
is_active => 1,
})->update_all({
is_active => 0,
});
}
sub checkCustomerInvoiceTemplateContract{ sub checkCustomerInvoiceTemplateContract{
my $self = shift; my $self = shift;
my (%params) = @_; my (%params) = @_;

@ -18,35 +18,34 @@ sub process {
# check if we need to join more tables # check if we need to join more tables
# TODO: can we nest it deeper than once level? # TODO: can we nest it deeper than once level?
unless ($use_rs_cb) { set_columns($c, $cols);
for my $c(@{ $cols }) { for my $c(@{ $cols }) {
my @parts = split /\./, $c->{name}; my @parts = split /\./, $c->{name};
if($c->{literal_sql}) { if($c->{literal_sql}) {
$rs = $rs->search_rs(undef, { $rs = $rs->search_rs(undef, {
'+select' => [ \[$c->{literal_sql}] ], '+select' => [ \[$c->{literal_sql}] ],
'+as' => [ $c->{accessor} ], '+as' => [ $c->{accessor} ],
}); });
} elsif(@parts == 2) { } elsif(@parts == 2) {
$rs = $rs->search_rs(undef, { $rs = $rs->search_rs(undef, {
join => $parts[0], join => $parts[0],
'+select' => [ $c->{name} ], '+select' => [ $c->{name} ],
'+as' => [ $c->{accessor} ], '+as' => [ $c->{accessor} ],
}); });
} elsif(@parts == 3) { } elsif(@parts == 3) {
$rs = $rs->search_rs(undef, { $rs = $rs->search_rs(undef, {
join => { $parts[0] => $parts[1] }, join => { $parts[0] => $parts[1] },
'+select' => [ $parts[1].'.'.$parts[2] ], '+select' => [ $parts[1].'.'.$parts[2] ],
'+as' => [ $c->{accessor} ], '+as' => [ $c->{accessor} ],
}); });
} elsif(@parts == 4) { } elsif(@parts == 4) {
$rs = $rs->search_rs(undef, { $rs = $rs->search_rs(undef, {
join => { $parts[0] => { $parts[1] => $parts[2] } }, join => { $parts[0] => { $parts[1] => $parts[2] } },
'+select' => [ $parts[2].'.'.$parts[3] ], '+select' => [ $parts[2].'.'.$parts[3] ],
'+as' => [ $c->{accessor} ], '+as' => [ $c->{accessor} ],
}); });
} elsif(@parts > 4) { } elsif(@parts > 4) {
# TODO throw an error for now as we only support up to 3 levels # TODO throw an error for now as we only support up to 3 levels
}
} }
} }

@ -0,0 +1,124 @@
//constructor
var svgCanvasEmbed = null;
function init_embed() {
var svgEditFrameName = 'svgedit';
var frame = document.getElementById(svgEditFrameName);
svgCanvasEmbed = new EmbeddedSVGEdit(frame);
// Hide main button, as we will be controlling new/load/save etc from the host document
var doc = frame.contentDocument;
if (!doc)
{
doc = frame.contentWindow.document;
}
//var mainButton = doc.getElementById('main_button');
//mainButton.style.display = 'none';
}
//private
function getSvgString(){
return svgCanvasEmbed.frame.contentWindow.svgCanvas.getSvgString();
}
function setSvgStringToEditor( svgParsedString ){
//alert('setSvgStringToEditor: '+svgParsedString);
svgCanvasEmbed.setSvgString( svgParsedString )(
function(data,error){
if(error){
}else{
svgCanvasEmbed.zoomChanged('', 'canvas');
}
}
);
}
function setSvgStringToPreview( svgParsedString, q, data ) {
var previewIframe = document.getElementById('svgpreview');
//alert('setSvgStringToPreview: svgParsedString='+svgParsedString+';');
if ($.browser.msie) {
//we need to repeat query to server for msie if we don't want send template string via GET method
if(!q){
var dataPreview = data;
dataPreview.tt_viewmode = 'parsed';
dataPreview.tt_type = 'svg';
dataPreview.tt_sourcestate = dataPreview.tt_sourcestate || 'saved';
q = uriForAction( dataPreview, 'invoice_template' );
}
previewIframe.src = q;
}else{
previewIframe.src = "data:text/html," + encodeURIComponent(svgParsedString);
}
}
function fetchSvgToEditor( data ) {
var q = uriForAction( data, 'invoice_template' );
//alert('fetchSvgToEditor: q='+q+';');
$.ajax({
url: q,
}).done( function ( httpResponse ){
setSvgStringToEditor( httpResponse );
});
}
function refreshTemplateList ( contract_id ){
fetch_into(
'collapse_invoice_template_list',
uriForAction( {'contract_id': contract_id}, 'invoice_template_list' ),
'',
function(){ mainWrapperInit(); }
);
}
//public
function fetchInvoiceTemplateData( data ){
//params spec: tt_type=[svg|html]/tt_viewmode[parsed|raw]/tt_sourcestate[saved|previewed|default]/tt_output_type[svg|pdf|html|json|svgzip|pdfzip|htmlzip]/tt_id
//tt_output_type=svg really outputs text/html mimetype. But it will be couple of <svg> tags (<svg> per page).
data.tt_output_type = 'json';
var q = uriForAction( data, 'invoice_template' );
//alert('fetchInvoiceTemplateData: q='+q+';');
$.ajax({
url: q,
datatype: "json",
//}).done( function( jsonres ){
}).done( function( templatedata ){
//alert(templatedata);
//alert(templatedata.aaData);
if(templatedata.aaData){
if( templatedata.aaData.template ){
setSvgStringToEditor( templatedata.aaData.template.raw );
setSvgStringToPreview( templatedata.aaData.template.parsed );
}
if( templatedata.aaData.form ){
$('form[name=invoice_template]').loadJSON(templatedata.aaData.form);
}
}
});
}
function savePreviewedAndShowParsed( data ){
var svgString = getSvgString();
var q = uriForAction( data, 'invoice_template_previewed' );
//alert('savePreviewedAndShowParsed: svgString='+svgString+'; q='+q+';');
//alert('savePreviewedAndShowParsed: q='+q+';');
//save
q=formToUri(q);
$.post( q, { template: svgString } )
.done( function( httpResponse ){
// & show template
//alert('savePreviewedAndShowParsed: httpResponse='+httpResponse+';');
setSvgStringToPreview( httpResponse, q )
//refresh list after saving
refreshTemplateList( data.contract_id );
} );
}
function saveTemplate( data ) {
var svgString = getSvgString();
data.tt_sourcestate='saved';
data.tt_output_type = 'json';
var q = uriForAction( data, 'invoice_template_saved' );
q=formToUri(q);
alert('saveTemplate: q='+q+';');
$.ajax( {
url: q,
type: "POST",
datatype: 'json',
data: { template: svgString },
} ).done( function( jsonResponse ) {
if(jsonResponse.aaData && jsonResponse.aaData.form){
$('form[name=invoice_template]').loadJSON(jsonResponse.aaData.form);
}
refreshTemplateList( data.contract_id );
});
}

@ -20,25 +20,6 @@
<script type="text/javascript" src="/js/background.js"></script> <script type="text/javascript" src="/js/background.js"></script>
<script type="text/javascript" src="/js/jquery.loadJSON.js"></script> <script type="text/javascript" src="/js/jquery.loadJSON.js"></script>
<script type="text/javascript"> <script type="text/javascript">
//constructor
var svgCanvasEmbed = null;
function init_embed() {
var svgEditFrameName = 'svgedit';
var frame = document.getElementById(svgEditFrameName);
svgCanvasEmbed = new EmbeddedSVGEdit(frame);
// Hide main button, as we will be controlling new/load/save etc from the host document
var doc = frame.contentDocument;
if (!doc)
{
doc = frame.contentWindow.document;
}
//var mainButton = doc.getElementById('main_button');
//mainButton.style.display = 'none';
}
//private
function getSvgString(){
return svgCanvasEmbed.frame.contentWindow.svgCanvas.getSvgString();
}
var uriForAction = function( data, type ){ var uriForAction = function( data, type ){
//also we can think about getting URI's via ajax ) //also we can think about getting URI's via ajax )
var q_template; var q_template;
@ -69,114 +50,13 @@ var uriForAction = function( data, type ){
q_template=q_template.replace(key,data[key]); q_template=q_template.replace(key,data[key]);
}); });
q_template=q_template.replace(/\/+$/,''); q_template=q_template.replace(/\/+$/,'');
q_template=q_template+'?'+$('form[name=invoice_template]').serialize(); //q_template=q_template+'?'+$('form[name=invoice_template]').serialize();
//alert('q_template='+q_template); //alert('q_template='+q_template);
return q_template; return q_template;
} }
function setSvgStringToEditor( svgParsedString ){
//alert('setSvgStringToEditor: '+svgParsedString);
svgCanvasEmbed.setSvgString( svgParsedString )(
function(data,error){
if(error){
}else{
svgCanvasEmbed.zoomChanged('', 'canvas');
}
}
);
}
function setSvgStringToPreview( svgParsedString, q, data ) {
var previewIframe = document.getElementById('svgpreview');
//alert('setSvgStringToPreview: svgParsedString='+svgParsedString+';');
if ($.browser.msie) {
//we need to repeat query to server for msie if we don't want send template string via GET method
if(!q){
var dataPreview = data;
dataPreview.tt_viewmode = 'parsed';
dataPreview.tt_type = 'svg';
dataPreview.tt_sourcestate = dataPreview.tt_sourcestate || 'saved';
q = uriForAction( dataPreview, 'invoice_template' );
}
previewIframe.src = q;
}else{
previewIframe.src = "data:text/html," + encodeURIComponent(svgParsedString);
}
}
function fetchSvgToEditor( data ) {
var q = uriForAction( data, 'invoice_template' );
//alert('fetchSvgToEditor: q='+q+';');
$.ajax({
url: q,
}).done( function ( httpResponse ){
setSvgStringToEditor( httpResponse );
});
}
function refreshTemplateList ( contract_id ){
fetch_into(
'collapse_invoice_template_list',
uriForAction( {'contract_id': contract_id}, 'invoice_template_list' ),
'',
function(){ mainWrapperInit(); }
);
}
//public
function fetchInvoiceTemplateData( data ){
//params spec: tt_type=[svg|html]/tt_viewmode[parsed|raw]/tt_sourcestate[saved|previewed|default]/tt_output_type[svg|pdf|html|json|svgzip|pdfzip|htmlzip]/tt_id
//tt_output_type=svg really outputs text/html mimetype. But it will be couple of <svg> tags (<svg> per page).
data.tt_output_type = 'json';
var q = uriForAction( data, 'invoice_template' );
//alert('fetchInvoiceTemplateData: q='+q+';');
$.ajax({
url: q,
datatype: "json",
//}).done( function( jsonres ){
}).done( function( templatedata ){
//alert(templatedata);
//alert(templatedata.aaData);
if(templatedata.aaData){
if( templatedata.aaData.template ){
setSvgStringToEditor( templatedata.aaData.template.raw );
setSvgStringToPreview( templatedata.aaData.template.parsed );
}
if( templatedata.aaData.form ){
$('form[name=invoice_template]').loadJSON(templatedata.aaData.form);
}
}
});
}
function savePreviewedAndShowParsed( data ){
var svgString = getSvgString();
var q = uriForAction( data, 'invoice_template_previewed' );
//alert('savePreviewedAndShowParsed: svgString='+svgString+'; q='+q+';');
//alert('savePreviewedAndShowParsed: q='+q+';');
//save
$.post( q, { template: svgString } )
.done( function( httpResponse ){
// & show template
//alert('savePreviewedAndShowParsed: httpResponse='+httpResponse+';');
setSvgStringToPreview( httpResponse, q )
//refresh list after saving
refreshTemplateList( data.contract_id );
} );
}
function saveTemplate( data ) {
var svgString = getSvgString();
data.tt_sourcestate='saved';
data.tt_output_type = 'json';
var q = uriForAction( data, 'invoice_template_saved' );
alert('saveTemplate: q='+q+';');
$.ajax( {
url: q,
type: "POST",
datatype: 'json',
data: { template: svgString },
} ).done( function( jsonResponse ) {
if(jsonResponse.aaData && jsonResponse.aaData.form){
$('form[name=invoice_template]').loadJSON(jsonResponse.aaData.form);
}
refreshTemplateList( data.contract_id );
});
}
</script> </script>
<script type="text/javascript" src="/js/invoice_template.js"></script>
<div class="row"> <div class="row">
<span> <span>
@ -198,15 +78,22 @@ function saveTemplate( data ) {
[% [%
#while we don't due to local
clearHelper(); clearHelper();
helper.name = c.loc('Invoice Details'); helper.name = c.loc('Invoice Details');
helper.dt_columns = [
{ name => 'zone', title => c.loc('Zone'), search=> 1 },
{ name => 'number', title => c.loc('Calls amount') },
{ name => 'duration', title => c.loc('Duration') },
{ name => 'free_time', title => c.loc('Free time') },
{ name => 'cost', title => c.loc('Cash') },
];
helper.name_single = c.loc('Invoice Record'); helper.name_single = c.loc('Invoice Record');
helper.identifier = 'invoice_details'; helper.identifier = 'invoice_details_raw';
helper.ajax_uri = c.uri_for_action( '/customer/invoice_details_ajax', [ contract.id ] ) ;
initHelperAuto(); initHelperAuto();
PROCESS 'helpers/datatables.tt'; PROCESS 'helpers/datatables.tt';
-%] -%]
[%Dumper.dump_html(helper.ajax_uri)%]
<table class="table table-bordered table-striped table-highlight table-hover"> <table class="table table-bordered table-striped table-highlight table-hover">
<thead> <thead>
<tr> <tr>
@ -261,62 +148,8 @@ function saveTemplate( data ) {
</div> </div>
</span> </span>
[%#It can be separated later to form template and loaded with ajax and fillinform template::toolkit plugin. %]
[%#It is reliable and easy to implement solution, but requires additional modules. For now populate small form with jquery.%]
[%# USE FillInForm %]
<div style="visibility:visible;" id="invoice_template_form"> <div style="visibility:visible;" id="invoice_template_form">
<script> [%PROCESS 'customer/invoice_template_form.tt' %]
function getTtIdVal(){
return $('form[name=invoice_template] input[name=tt_id]').val();
}
</script>
<form name="invoice_template" id="invoice_template" action="[%- c.uri_for_action('/customer/invoice_template', [contract.id]) -%]" class="form-horizontal" enctype="multipart/form-data" method="post">
<input type="hidden" name="tt_id" value="">
<div class="ngcp-separator"></div>
<div class="control-group">
<label class="control-label" for="name">[%c.loc('Template name')%]</label>
<div class="controls">
<input type="text" name="name" id="name" value="" />
</div>
</div>
<div class="ngcp-separator"></div>
<div class="control-group">
<label class="control-label" for="is_active">[%c.loc('Active')%]</label>
<div class="controls" class="checkbox">
<input type="checkbox" name="is_active" id="is_active" value="1" />
</div>
</div>
<span>
<a class="btn btn-primary btn-large" onclick="
savePreviewedAndShowParsed({
contract_id:'[%contract.id%]',
tt_id: getTtIdVal(),
});void(0);">[% c.loc('Refresh Preview')%] <i class="icon-refresh"></i></a>
</span>
<span>
<a class="btn btn-primary btn-large" onclick="
//alert('tt_id='+getTtIdVal()+';');
saveTemplate({
contract_id:'[%contract.id%]',
tt_id: getTtIdVal(),
});void(0);">[% c.loc('Save template')%] <i class="icon-disk"></i></a>
</span>
<div class="ngcp-separator"></div>
[%initial = 'default'%]
<iframe
type="text/html"
src="/js/libs/svg-edit/svg-editor.htm" id="svgedit" onload="
init_embed();
fetchSvgToEditor({
tt_viewmode: 'raw',
tt_sourcestate: '[%initial%]',
contract_id: '[%contract.id%]',
tt_id: getTtIdVal(),
});" width="550px" height="750px" style="border-width:0px;"></iframe><iframe
src="[%- c.uri_for_action('/customer/invoice_template', [contract.id]) -%]/svg/parsed/[%- initial -%]" id="svgpreview"
width="600px" height="750px" style="border-width:0px;"></iframe>
</div> </div>
</form>
</div> </div>

@ -0,0 +1,69 @@
[%#It can be separated later to form template and loaded with ajax and fillinform template::toolkit plugin. %]
[%#It is reliable and easy to implement solution, but requires additional modules. For now populate small form with jquery.%]
[%# USE FillInForm %]
<script>
function getTtIdVal(){
return $('form[name=invoice_template] input[name=tt_id]').val();
}
function formToUri(q){
return q+'?'+$('form[name=invoice_template]').serialize()
}
</script>
<form name="invoice_template" id="invoice_template" action="[%- c.uri_for_action('/customer/invoice_template', [contract.id]) -%]" class="form-horizontal" enctype="multipart/form-data" method="post">
<input type="hidden" name="tt_id" value="">
<div class="ngcp-separator"></div>
[% IF write_access -%]
<span>
<a class="btn btn-primary btn-large" onclick="fetchInvoiceTemplateData({
tt_sourcestate: 'default',
contract_id: '[%contract.id%]',
});void(0);">[% c.loc('Create from scratch')%] <i class="icon-edit"></i></a>
</span>
<div class="ngcp-separator"></div>
[% END -%]
<div class="control-group">
<label class="control-label" for="name">[%c.loc('Template name')%]</label>
<div class="controls">
<input type="text" name="name" id="name" value="" />
</div>
</div>
<div class="ngcp-separator"></div>
<div class="control-group">
<label class="control-label" for="is_active">[%c.loc('Active')%]</label>
<div class="controls" class="checkbox">
<input type="checkbox" name="is_active" id="is_active" value="1" />
</div>
</div>
<span>
<a class="btn btn-primary btn-large" onclick="
savePreviewedAndShowParsed({
contract_id:'[%contract.id%]',
tt_id: getTtIdVal(),
});void(0);">[% c.loc('Refresh Preview')%] <i class="icon-refresh"></i></a>
</span>
<span>
<a class="btn btn-primary btn-large" onclick="
//alert('tt_id='+getTtIdVal()+';');
saveTemplate({
contract_id:'[%contract.id%]',
tt_id: getTtIdVal(),
});void(0);">[% c.loc('Save template')%] <i class="icon-disk"></i></a>
</span>
<div class="ngcp-separator"></div>
[%initial = 'default'%]
<iframe
type="text/html"
src="/js/libs/svg-edit/svg-editor.htm" id="svgedit" onload="
init_embed();
fetchSvgToEditor({
tt_viewmode: 'raw',
tt_sourcestate: '[%initial%]',
contract_id: '[%contract.id%]',
tt_id: getTtIdVal(),
});" width="550px" height="750px" style="border-width:0px;"></iframe><iframe
src="[%- c.uri_for_action('/customer/invoice_template', [contract.id]) -%]/svg/parsed/[%- initial -%]" id="svgpreview"
width="600px" height="750px" style="border-width:0px;"></iframe>
</div>
</form>

@ -6,15 +6,6 @@
[%END%] [%END%]
<div class="accordion-inner" style="overflow:auto; height: 300px;"> <div class="accordion-inner" style="overflow:auto; height: 300px;">
[% IF write_access -%]
<span>
<a class="btn btn-primary btn-large" onclick="fetchInvoiceTemplateData({
tt_sourcestate: 'default',
contract_id: '[%contract.id%]',
});void(0);">[% c.loc('Create invoice template')%] <i class="icon-edit"></i></a>
</span>
<div class="ngcp-separator"></div>
[% END -%]
[%IF invoice_template_list.size %] [%IF invoice_template_list.size %]
<table class="table table-bordered table-striped table-highlight table-hover"> <table class="table table-bordered table-striped table-highlight table-hover">
<thead> <thead>
@ -30,7 +21,7 @@
[%# Dumper.dump_html(invoice_template_list.as_query)%] [%# Dumper.dump_html(invoice_template_list.as_query)%]
[%# Dumper.dump_html(template)%] [%# Dumper.dump_html(template)%]
<tr class="sw_action_row"> <tr class="sw_action_row">
<td>[% template.get_column('is_active') %]</td> <td><input type="radio" name="is_active" value="[%template.get_column('is_active')%]" [%IF template.get_column('is_active') %] checked [%END%] onclick="javascript:fetch_into('collapse_invoice_template_list', '[%- c.uri_for_action("/customer/invoice_template_activate", [contract.id, template.get_column('id')]) -%]','',function(){ mainWrapperInit(); });void(0);"></td>
<td>[% template.get_column('type') %]</td> <td>[% template.get_column('type') %]</td>
<td>[% template.get_column('name') %]</td> <td>[% template.get_column('name') %]</td>
@ -59,24 +50,24 @@
</a> </a>
[%END%] [%END%]
[%IF !template.is_active%] [%IF !template.is_active%]
<a class="btn btn-small btn-primary" <!--a class="btn btn-small btn-primary"
onclick="switchDefault();void(0);"> onclick="switchDefault();void(0);">
<i class="icon-edit"></i> [% c.loc('Make active') %] <i class="icon-edit"></i> [% c.loc('Make active') %]
</a> </a-->
[%END%] [%END%]
<a class="btn btn-small btn-secondary ngcp-noback-button" data-confirm="Delete" <a class="btn btn-small btn-secondary ngcp-noback-button" data-confirm="Delete"
href="javascript:fetch_into('collapse_invoice_template_list', '[%- c.uri_for_action("/customer/invoice_template_delete", [contract.id, template.get_column('id')]) -%]','',function(){ mainWrapperInit(); });void(0);"> href="javascript:fetch_into('collapse_invoice_template_list', '[%- c.uri_for_action("/customer/invoice_template_delete", [contract.id, template.get_column('id')]) -%]','',function(){ mainWrapperInit(); });void(0);">
<i class="icon-trash"></i> [% c.loc('Delete') %] <i class="icon-trash"></i> [% c.loc('Delete') %]
</a> </a>
[%END%] [%END%]
<a class="btn btn-small btn-primary" <!--a class="btn btn-small btn-primary"
onclick="loadSvg('/svg/raw/saved/zip');void(0);"> onclick="loadSvg('/svg/raw/saved/zip');void(0);">
<i class="icon-download"></i>[% c.loc('Download source') %] <i class="icon-download"></i>[% c.loc('Download source') %]
</a> </a>
<a class="btn btn-small btn-primary" <a class="btn btn-small btn-primary"
onclick="loadSvg('/svg/parsed/saved/pdf');void(0);"> onclick="loadSvg('/svg/parsed/saved/pdf');void(0);">
<i class="icon-download"></i> [% c.loc('Download invoice') %] <i class="icon-download"></i> [% c.loc('Download invoice') %]
</a> </a-->
</div> </div>
</td> </td>
</tr> </tr>

@ -3,6 +3,10 @@
helper.column_titles = []; helper.column_titles = [];
helper.column_fields = []; helper.column_fields = [];
FOR col IN helper.dt_columns; FOR col IN helper.dt_columns;
IF !col.accessor;
col.accessor = col.name;
col.accessor.replace('\.','_');
END;
NEXT UNLESS col.title; NEXT UNLESS col.title;
helper.column_titles.push(col.title); helper.column_titles.push(col.title);
helper.column_fields.push(col.accessor); helper.column_fields.push(col.accessor);
@ -80,7 +84,7 @@ $(document).ready(function() {
"mRender": function ( data, type, full ) { "mRender": function ( data, type, full ) {
if(data == null) if(data == null)
return ''; return '';
return String(data).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); return String(data).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');//"
} }
}, },
[% END -%] [% END -%]

@ -1,3 +1,4 @@
[% USE JSON.Escape( pretty => 0 ) %];
[%- [%-
#USE Dumper; #USE Dumper;
@ -12,12 +13,25 @@ MACRO initHelper(var,value) BLOCK;
identifier = "${helper.identifier}" _ "_" _ var; identifier = "${helper.identifier}" _ "_" _ var;
UNLESS helper.${var}.defined; helper.${var} = helper.${var} || value || ${"${identifier}"} || ${var}; END; UNLESS helper.${var}.defined; helper.${var} = helper.${var} || value || ${"${identifier}"} || ${var}; END;
END; END;
MACRO initDtColumns BLOCK;
FOR col in helper.dt_columns;
IF ! col.accessor;
col.accessor = col.name.replace('\.','_');
END;
END;
END;
MACRO initHelperAuto BLOCK; MACRO initHelperAuto BLOCK;
FOREACH identifier in [ 'messages', 'length_change', 'dt_columns', 'close_target', 'create_flag' ]; FOREACH identifier in [ 'messages', 'length_change', 'dt_columns', 'close_target', 'create_flag' ];
initHelper(identifier); initHelper(identifier);
END; END;
#;
initHelper('form_object',form); initHelper('form_object',form);
initHelper('ajax_uri', c.uri_for( c.controller.action_for('ajax') )); initHelper('ajax_uri', c.uri_for( c.controller.action_for('ajax') ));
IF ! helper.ajax_uri.search('[\?&]dt_columns=');
initDtColumns();
helper.dt_columns_json = helper.dt_columns.json() | url;
helper.ajax_uri = helper.ajax_uri _ '?dt_columns=' _ helper.dt_columns_json;
END;
END; END;
IF !no_auto_helper; IF !no_auto_helper;

Loading…
Cancel
Save