MT#5879 Save intermediate state with solutions which are going to be removed.

ipeshinskaya/InvoiceTemplate5
Irina Peshinskaya 11 years ago committed by Victor Seva
parent 805e9ee194
commit bf5d8ccf66

@ -812,10 +812,29 @@ sub edit_balance :Chained('base') :PathPart('balance/edit') :Args(0) {
$c->stash(form => $form);
$c->stash(edit_flag => 1);
}
sub invoice_data :Chained('base') :PathPart('invoice') :CaptureArgs(0) {
my ($self, $c) = @_;
$c->log->debug('invoice_data');
my $contract_id = $c->stash->{contract}->id;
my $stime = NGCP::Panel::Utils::DateTime::current_local()->truncate(to => 'month');
my $etime = $stime->clone->add(months => 1);
sub invoice_delete :Chained('base') :PathPart('invoice_template/delete') :CaptureArgs(1) {
#look, NGCP::Panel::Utils::Contract - it is kind of backend separation here
my $invoice_details = NGCP::Panel::Utils::Contract::get_contract_calls_rs(
c => $c,
contract_id => $contract_id,
stime => $stime,
etime => $etime,
);
#FAKE FAKE FAKE FAKE
$invoice_details = [$invoice_details->all()];
my $i = 1;
$invoice_details = [map{[$i++,$_]} (@$invoice_details) x 21];
$c->stash(invoice_details => $invoice_details );
}
sub invoice_template_delete :Chained('base') :PathPart('invoice_template/delete') :Args(1) {
my ($self, $c) = @_;
$c->log->debug('invoice_delete');
$c->log->debug('invoice_template_delete');
my($validator,$backend,$in,$out);
(undef,undef,@$in{qw/tt_id/}) = @_;
@ -862,76 +881,33 @@ sub invoice_delete :Chained('base') :PathPart('invoice_template/delete') :Captur
#think about it more
$backend->deleteCustomerInvoiceTemplate(%$in);
$c->forward( 'invoice_template_list' );
}
sub invoice_template_aux_embedImage :Chained('list_customer') :PathPart('auxembedimage') :Args(0) {
my ($self, $c) = @_;
#I know somewhere is logging of all visited methods
$c->log->debug('invoice_template_aux_handleImageUpload');
sub invoice_template_list_data :Chained('invoice_data') :PathPart('') :CaptureArgs(0) {
my ($self, $c) = @_;
$c->log->debug('invoice_template_list_data');
my($validator,$backend,$in,$out);
#todo
#mime-type and type checking in form
$in = $c->request->parameters;
$in->{svg_file} = $c->request->upload('svg_file');
if($in->{svg_file}) {
my $ft = File::Type->new();
$out->{image_content} = $in->{svg_file}->slurp;
$out->{image_content_mimetype} = $ft->mime_type($out->{image_content});
$out->{image_content_base64} = encode_base64($out->{image_content}, '');
}
$c->log->debug('mime-type '.$out->{image_content_mimetype});
$c->stash(out => $out);
$c->stash(in => $in);
$c->stash(template => 'customer/invoice_template_aux_embedimage.tt');
$c->detach( $c->view('SVG') );
}
sub invoice_data :Chained('base') :PathPart('invoice') :CaptureArgs(0) {
my ($self, $c) = @_;
$c->log->debug('invoice_data');
my $contract_id = $c->stash->{contract}->id;
my $stime = NGCP::Panel::Utils::DateTime::current_local()->truncate(to => 'month');
my $etime = $stime->clone->add(months => 1);
#look, NGCP::Panel::Utils::Contract - it is kind of backend separation here
my $invoice_details = NGCP::Panel::Utils::Contract::get_contract_calls_rs(
c => $c,
contract_id => $contract_id,
stime => $stime,
etime => $etime,
);
#FAKE FAKE FAKE FAKE
$invoice_details = [$invoice_details->all()];
my $i = 1;
$invoice_details = [map{[$i++,$_]} (@$invoice_details) x 21];
$c->stash(invoice_details => $invoice_details );
$in->{contract_id} = $c->stash->{contract}->id;
$backend = NGCP::Panel::Model::DB::InvoiceTemplate->new( schema => $c->model('DB') );
my $records = $backend->getCustomerInvoiceTemplateList( %$in );
$c->stash( invoice_template_list => $records );
}
sub invoice_template_list :Chained('invoice_data') :PathPart('') :CaptureArgs(0) {
sub invoice_template_list :Chained('base') :PathPart('') :Args(0) {
my ($self, $c) = @_;
$c->log->debug('invoice_template_list');
my($validator,$backend,$in,$out);
$in->{contract_id} = $c->stash->{contract}->id;
$backend = NGCP::Panel::Model::DB::InvoiceTemplate->new( schema => $c->model('DB') );
$c->stash( invoice_template_list => $backend->getCustomerInvoiceTemplateList( %$in )->all );
$c->stash( template => 'customer/invoice_template_list.tt' );
$c->forward( 'invoice_template_list_data' );
$c->detach($c->view('SVG'));#just no wrapper - aybe there is some other way?
}
sub invoice :Chained('invoice_template_list') :PathPart('') :Args(0) {
sub invoice :Chained('invoice_template_list_data') :PathPart('') :Args(0) {
my ($self, $c) = @_;
$c->stash(template => 'customer/invoice.tt');
}
sub invoice_template :Chained('invoice_data') :PathPart('template') :Args {
my ($self, $c) = @_;
#$c->log->debug($c->model('DB'));
#return;
#my $db = NGCP::Panel::Model::DB::InvoiceTemplate->new();
$c->log->debug('invoice_template');
#my $contract_id = $in->{contract_id} = ;
no warnings 'uninitialized';
my($validator,$backend,$in,$out);
@ -970,28 +946,11 @@ sub invoice_template :Chained('invoice_data') :PathPart('template') :Args {
return;
}
my $in_validated = $validator->fif;
#use irka;
#use Data::Dumper;
#irka::loglong(Dumper($in));
#irka::loglong(Dumper($in_validated));
#dirty hack 1
#really model logic should recieve validated input, but raw input also should be saved somewhere
$in = $in_validated;
#dirty hack 2
#validate methods in form configuration don't change fields values, will find why later
#for other values see defaults in form
if($in->{tt_type} eq 'svgpdf'){
$in->{tt_type} = 'svg';
$in->{tt_output_type} = 'pdf';
}elsif($in->{tt_type} eq 'html'){
$in->{tt_output_type} = 'html';
}
#use irka;
#use Data::Dumper;
#irka::loglong(Dumper($in));
#model logic
my $tt_string_default = '';
my $tt_string_customer = '';
@ -1000,7 +959,7 @@ sub invoice_template :Chained('invoice_data') :PathPart('template') :Args {
if(!$in->{tt_string} && !$tt_string_force_default){
#here we also may be better should contact model, not DB directly. Will return to this separation later
#at the end - we can figure out rather basic controller behaviour
($out->{tt_id}) = $backend->getCustomerInvoiceTemplate( %$in, result => \$tt_string_customer );
($out->{tt_id},undef,$out->{tt_data}) = $backend->getCustomerInvoiceTemplate( %$in, result => \$tt_string_customer );
}
#we need to get default to 1) sanitize (if in->tt_string) or 2)if not in->tt_string and no customer->tt_string
@ -1032,7 +991,6 @@ sub invoice_template :Chained('invoice_data') :PathPart('template') :Args {
}
#/sanitize - to sub, later
#irka::loglong(Dumper($tt_string_sanitized));
$backend->storeCustomerInvoiceTemplate(
%$in,
tt_string_sanitized => \$tt_string_sanitized,
@ -1052,23 +1010,26 @@ sub invoice_template :Chained('invoice_data') :PathPart('template') :Args {
#mess,mess,mess here
if($in->{tt_output_type} eq 'svg'){
$c->response->content_type('text/html');
#multi-svg document (as well as one-svg documet) is shown ok with text/html
# $c->response->content_type('image/svg+xml');
}elsif($in->{tt_output_type} eq 'pdf'){
$c->response->content_type('application/pdf');
}elsif($in->{tt_output_type} eq 'html'){
$c->response->content_type('text/html');
}elsif($in->{tt_output_type}=~m'zip'){
$c->response->content_type('application/zip');
}
if($in->{tt_viewmode} eq 'raw'){
#$c->stash->{VIEW_NO_TT_PROCESS} = 1;
$c->response->body($out->{tt_string});
return;
}else{
}else{#parsed
my $contacts = $c->model('DB')->resultset('contacts')->search({ id => $in->{contract_id} });
$c->stash( provider => $contacts->first );
#some preprocessing should be done only before showing. So, there will be:
#preSaveCustomTemplate prerpocessing
#preShowCustomTemplate prerpocessing
{
#preShowInvoice
@ -1082,20 +1043,30 @@ sub invoice_template :Chained('invoice_data') :PathPart('template') :Args {
#$c->response->content_type('image/svg+xml');
$c->stash( template => \$out->{tt_string} );
$c->detach( $c->view('SVG') );
}elsif($in->{tt_output_type} eq 'json'){
my $aaData = {
template =>{
raw => $out->{tt_string},
parsed => $c->view('SVG')->getTemplateProcessed($c,\$out->{tt_string}, $c->stash ),
},
form => {
tt_id => $out->{tt_data}->get_column('id'),
}
};
foreach(qw/name is_active/){
$aaData->{form}->{$_} = $out->{tt_data}->get_column($_);
}
#$c->stash( aaData => $out );
$c->detach( $c->view('JSON') );
}elsif($in->{tt_output_type} eq 'pdf'){
$c->response->content_type('application/pdf');
my $svg = $c->view('SVG')->getTemplateProcessed($c,\$out->{tt_string}, $c->stash );
my(@pages) = $svg=~/(<svg.*?(?:\/svg>))/sig;
#$c->log->debug($svg);
#my $kit = PDF::WebKit->new(\$svg, page_size => 'A4');
#push @{ $kit->stylesheets }, "/path/to/css/file";
# Get an inline PDF
#$out->{tt_string} = $kit->to_pdf;
#$c->response->body($out->{tt_string});
my ($tempdirbase,$tempdir );
use File::Temp qw/tempfile tempdir/;
#my($fh, $tempfilename) = tempfile();
#my($fh, $tempfilename) = tempfile();
$tempdirbase = join('/',File::Spec->tmpdir,@$in{qw/contract_id tt_type tt_sourcestate/}, $out->{tt_id});
use File::Path qw( mkpath );
! -e $tempdirbase and mkpath( $tempdirbase, 0, 0777 );
@ -1129,13 +1100,6 @@ sub invoice_template :Chained('invoice_data') :PathPart('template') :Args {
$pagenum++;
}
#$fh->unlink_on_destroy( 0 );
#my $filename = "/tmp/bbb.svg";
#open my $fh, ">$filename";
#binmode $fh;
#print $fh $svg;
#close $fh;
#my $cmd = "/tmp/wkhtmltox/bin/wkhtmltopdf $filename - ";
my $cmd = "rsvg-convert -f pdf ".join(" ", @pagefiles);
$c->log->debug($cmd);
#`chmod ugo+rwx $filename`;
@ -1158,19 +1122,31 @@ sub invoice_template :Chained('invoice_data') :PathPart('template') :Args {
}
}
sub subscriber_ajax :Chained('base') :PathPart('subscriber/ajax') :Args(0) {
sub invoice_template_aux_embedImage :Chained('list_customer') :PathPart('auxembedimage') :Args(0) {
my ($self, $c) = @_;
my $res = $c->stash->{contract}->voip_subscribers->search({
'provisioning_voip_subscriber.is_pbx_group' => 0,
'me.status' => { '!=' => 'terminated' },
},{
join => 'provisioning_voip_subscriber',
});
NGCP::Panel::Utils::Datatables::process($c, $res, $c->stash->{subscriber_dt_columns});
$c->detach( $c->view("JSON") );
#I know somewhere is logging of all visited methods
$c->log->debug('invoice_template_aux_handleImageUpload');
my($validator,$backend,$in,$out);
#todo
#mime-type and type checking in form
$in = $c->request->parameters;
$in->{svg_file} = $c->request->upload('svg_file');
if($in->{svg_file}) {
my $ft = File::Type->new();
$out->{image_content} = $in->{svg_file}->slurp;
$out->{image_content_mimetype} = $ft->mime_type($out->{image_content});
$out->{image_content_base64} = encode_base64($out->{image_content}, '');
}
$c->log->debug('mime-type '.$out->{image_content_mimetype});
$c->stash(out => $out);
$c->stash(in => $in);
$c->stash(template => 'customer/invoice_template_aux_embedimage.tt');
$c->detach( $c->view('SVG') );
}
sub pbx_group_ajax :Chained('base') :PathPart('pbx/group/ajax') :Args(0) {
my ($self, $c) = @_;
my $res = $c->stash->{contract}->voip_subscribers->search({

@ -4,7 +4,7 @@ use HTML::FormHandler::Moose;
extends 'NGCP::Panel::Form::ValidatorBase';
use Moose::Util::TypeConstraints;
enum 'TemplateType' => [ qw/svg html svgpdf/ ];#html
enum 'TemplateType' => [ qw/svg html/ ];#html
enum 'TemplateTypeOutput' => [ qw/svg html pdf svgzip htmlzip pdfzip/ ];#html
enum 'TemplateViewMode' => [ qw/raw parsed/ ];
enum 'TemplateSourceState' => [ qw/saved previewed default/ ];
@ -18,7 +18,6 @@ has_field 'tt_type' => (
default => 'svg',
apply => [
{ type => 'TemplateType' },
#{ transform => sub{ $_[0] eq 'svgpdf' and return 'svg'; } },
],
);
@ -28,7 +27,6 @@ has_field 'tt_output_type' => (
default => 'svg',
apply => [
{ type => 'TemplateTypeOutput' },
#{ when => { tt_type => 'svgpdf' }, transform => sub{ 'pdf' } },
],
);
@ -69,22 +67,6 @@ has_field 'tt_id' => (
required => 0,
);
#sub validate_tt_string{
#here could be following: take default from file and get all variables and validate variables from customer string
#};
#sub validate {
# my ( $self ) = @_; # self is the form
# if( $self->field('tt_type')->value eq 'svgpdf'){
# use irka;
# use Data::Dumper;
# irka::loglong("\n\n\nin validate\nBBBBBBBBBBBBBBBBBBBBB\naaaaaaaaaaaaaaa\n");
# #die();
# $self->field('tt_output_type')->value('pdf');
# $self->field('tt_type')->value('svg');
# }
# return 1;
#};
1;
=head1 NAME

@ -4,17 +4,22 @@ use base NGCP::Panel::Model::DB::Base;
sub getCustomerInvoiceTemplate{
my $self = shift;
my (%params) = @_;
my ($contract_id,$tt_sourcestate,$tt_type) = @params{qw/contract_id tt_sourcestate tt_type/};
my ($contract_id,$tt_sourcestate,$tt_type,$tt_id) = @params{qw/contract_id tt_sourcestate tt_type tt_id/};
my $result = '';
my $tt_id = '';
my $conditions = {};
#my $tt_record = $self->resultset('invoice_template')->search({
my $tt_record = $self->schema->resultset('invoice_template')->search({
reseller_id => $contract_id,
is_active => 1,
type => $tt_type
})->first;
if($tt_id){
$conditions = { id => $tt_id };
}else{
$conditions = {
reseller_id => $contract_id,
is_active => 1,
type => $tt_type
};
}
my $tt_record = $self->schema->resultset('invoice_template')->search($conditions)->first;
#here may be base64 decoding
#here we will rely on form checking and defaults
@ -26,7 +31,7 @@ sub getCustomerInvoiceTemplate{
if( $result && exists $params{result} ){
${$params{result}} = $result;
}
return ( $tt_id,\$result, $tt_record );#sgorila hata, gori i saray
return ( $tt_id, \$result, $tt_record );#sgorila hata, gori i saray
}
sub storeCustomerInvoiceTemplate{
@ -81,9 +86,10 @@ sub getCustomerInvoiceTemplateList{
my $self = shift;
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/};
return $self->schema->resultset('invoice_template')->search({
return [ $self->schema->resultset('invoice_template')->search({
reseller_id => $contract_id,
});
})->all ];
}
sub deleteCustomerInvoiceTemplate{
my $self = shift;

@ -1,4 +1,9 @@
[% USE Dumper %]
[% USE format %]
[% money_format = format('%.2f') %]
[% IF !c.user.read_only && (c.user.roles == 'admin' || c.user.roles == 'reseller') -%]
[% write_access = 1 %]
[%END%]
[%PROCESS 'helpers/datatables_vars.tt'
no_auto_helper = 1
@ -10,9 +15,6 @@
[% site_config.title = c.loc('Customer Invoice template for #[_1] ([_2])',contract.id, product.name) -%]
[% END -%]
[% IF !c.user.read_only && (c.user.roles == 'admin' || c.user.roles == 'reseller') -%]
[% write_access = 1 %]
[%END%]
<script type="text/javascript" src="/js/libs/svg-edit/embedapi.js"></script>
<script type="text/javascript" src="/js/background.js"></script>
@ -22,7 +24,6 @@ function init_embed() {
var svgEditFrameName = 'svgedit';
var frame = document.getElementById(svgEditFrameName);
svgCanvas = new EmbeddedSVGEdit(frame);
//svgCanvas.zoomImage(2);
// Hide main button, as we will be controlling new/load/save etc from the host document
var doc;
doc = frame.contentDocument;
@ -33,42 +34,118 @@ function init_embed() {
//var mainButton = doc.getElementById('main_button');
//mainButton.style.display = 'none';
}
function loadSvg(params) {
//alert('[%- c.uri_for_action("/customer/invoice_template", [contract.id]) -%]'+params);
$.ajax({
url: '[%- c.uri_for_action("/customer/invoice_template", [contract.id]) -%]'+params,
}).done(function(svgParsedString){
svgCanvas.setSvgString(svgParsedString)(
function setSvgStringToEditor( svgParsedString ){
svgCanvas.setSvgString( svgParsedString )(
function(data,error){
if(error){
}else{
//var svgEditIframe = $("#svgedit").contents().find('#fit_to_canvas');
//var objToClick = $("#svgedit").contents().find('#fit_to_canvas');
svgCanvas.zoomChanged('', 'canvas');
//alert('iframe id='+objToClick.attr("someattr")+';');
//alert('mousedown='+objToClick.attr("onmousedown")+';');
//alert('click='+objToClick.attr("onclick")+';');
//alert('mouseup='+objToClick.attr("onmouseup")+';');
//alert($._data(objToClick,'events'));
//.contents().find('#fit_to_canvas')
//alert(jQuery.data($("#svgedit"),'mouseup'));
//objToClick.bind('click',function(){alert('Bound onclick for canvas option.');});
//jQuery.each(objToClick.data('mouseup'), function(i, event){alert('i='+i+';event='+event);});
//alert('iframe id='+$("#svgedit").contents().find('#iframebutton').attr("onclick")+';');
//$("#svgedit").contents().find('#iframebutton').click();
//objToClick.mousedown();
//objToClick.mouseup();
//objToClick.click();
//$("#svgedit").contents().find('#fit_to_canvas').mousedown();
}
}
);
);
}
var uriForAction = function( data, type ){
//also we can think about getting URI's via ajax )
var q_template;
switch(type){
case 'invoice_template_previewed':
//q_template = '[%- c.uri_for_action("/customer/invoice_template", ['contract_id','svg','parsed','previewed','svg','tt_id']) -%]';
q_template = '[%- c.uri_for_action("/customer/invoice_template", ["contract_id"]) -%]'+'/svg/parsed/previewed/svg/tt_id';
break;
case 'invoice_template_saved':
//q_template = '[%- c.uri_for_action("/customer/invoice_template", ['contract_id','svg','parsed','saved','svg','tt_id']) -%]';
q_template = '[%- c.uri_for_action("/customer/invoice_template", ["contract_id"]) -%]'+'/svg/parsed/previewed/svg/tt_id';
break;
case 'invoice_template_list':
q_template = '[%- c.uri_for_action("/customer/invoice_template_list", ['contract_id']) -%]';
break;
case 'invoice_template':
default:
//q_template = '[%- c.uri_for_action("/customer/invoice_template", ['contract_id','tt_type','tt_viewmode','tt_sourcestate','tt_output_type','tt_id']) -%]';
q_template = '[%- c.uri_for_action("/customer/invoice_template", ["contract_id"]) -%]'+'/tt_type/tt_viewmode/tt_sourcestate/tt_output_type/tt_id';
break;
}
//alert('1.q_template='+q_template);
//alert('contract_id='+data.contract_id+';tt_id='+data.tt_id);
if(!data.tt_id){data.tt_id = '';}
if(!data.tt_type){data.tt_type = 'svg';}
if(!data.tt_output_type){data.tt_output_type = 'svg';}
var params = ['contract_id','tt_id','tt_type','tt_output_type','tt_viewmode','tt_sourcestate'];
params.forEach(function(key){
q_template=q_template.replace(key,data[key]);
});
/*
q_template=q_template.replace('contract_id',data.contract_id);
q_template=q_template.replace('tt_id',data.tt_id);
q_template=q_template.replace('tt_type',data.tt_type);
q_template=q_template.replace('tt_output_type',data.tt_output_type);
q_template=q_template.replace('tt_viewmode',data.tt_viewmode);
q_template=q_template.replace('tt_sourcestate',data.tt_sourcestate);
*/
q_template=q_template.replace(/([^:])\/{2,}/g,'$1/');
q_template=q_template.replace(/\/+$/,'');
//alert('2.q_template='+q_template);
return q_template;
}
//function loadInvoiceTemplateData(params) {
//function loadInvoiceTemplateData(tt_type,tt_viewmode,tt_sourcestate,tt_output_type,tt_id,contract_id) {
function loadInvoiceTemplateData( data ){
//params spec: tt_type=[svg|html]/tt_viewmode[parsed|raw]/tt_sourcestate[default|previewed]/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).
var q = uriForAction( data, 'invoice_template' );
alert('loadInvoiceTemplateData: q='+q+';');
$.ajax({
url: q,
datatype: "json",
}).done(function(jsonres){
var templatedata = $.parseJson(res);
svgRawString = templatedata.template.raw;
setSvgStringToEditor( svgRawString );
});
}
function fetchSvgToEditor( data ) {
var q = uriForAction( data, 'invoice_template' );
//alert('fetchSvgToEditor: q='+q+';');
$.ajax({
url: q,
}).done( function ( httpResponse ){
setSvgStringToEditor( httpResponse );
} );
}
function showSvgParsed(){
svgCanvas.getSvgString()(handleShowSvgParsedData);
var setSvgStringToPreview = function( svgParsedString, q ) {
var previewIframe = document.getElementById('svgpreview');
if ($.browser.msie) {
//we need to repeat query to server for msie if we don't want send template string via GET method
previewIframe.src = q;
}else{
previewIframe.src = "data:text/html," + encodeURIComponent(svgParsedString);
}
}
function refreshTemplateList ( contract_id ){
fetch_into(
'collapse_invoice_template_list',
uriForAction( {'contract_id': contract_id}, 'invoice_template_list' ),
'',
function(){ mainWrapperInit(); }
);
}
function savePreviewedAndShowParsed( data ){
var svgString = svgCanvas.getSvgString(handleShowSvgParsedData);
var q = uriForAction( data, 'invoice_template_previewed' );
alert('svgString='+svgString+'; q='+q+';');
//save
$.post( q, { template: svgString } )
.done( function( httpResponse ){
// & show template
alert('httpResponse='+httpResponse+';');
setSvgStringToPreview( httpResponse, q )
//refresh list after saving
refreshTemplateList( data.contract_id );
} );
}
function handleShowSvgParsedData(svgString, error) {
if (error)
{
@ -76,6 +153,8 @@ function handleShowSvgParsedData(svgString, error) {
}
else
{
return svgString;
/*
var q = '[%- c.uri_for_action("/customer/invoice_template", [contract.id]) -%]'+'/svg/parsed/previewed';
$.post( q, { template: svgString })
.done( function( svgParsedString ) {
@ -101,26 +180,16 @@ function handleShowSvgParsedData(svgString, error) {
previewIframe.src = "data:image/svg+xml," + encodeURIComponent(svgParsedString);
}
}
});
});*/
}
}
function saveSvg() {
svgCanvas.getSvgString()(handleSaveSvgData);
}
function handleSaveSvgData(data, error) {
if (error)
{
alert('error ' + error);
}
else
{
var q = '[%- c.uri_for_action("/customer/invoice_template", [contract.id]) -%]'+'/svg/parsed/saved';
$.post( q, { template: encodeURIComponent(data) })
.done(function( httpResponse ) {
});
}
function saveTemplate( contract_id, tt_id ) {
var svgString = svgCanvas.getSvgString();
var q = uriForAction( data, 'invoice_template_saved' );
$.post( q, { template: encodeURIComponent( svgString ) })
.done( function( httpResponse ) {
refreshTemplateList( data.contract_id );
});
}
</script>
@ -145,17 +214,18 @@ function handleSaveSvgData(data, error) {
[%
#while we don't due to local
# clearHelper();
# helper.name = c.loc('Invoice Details');
# helper.name_single = c.loc('Invoice Record');
# helper.identifier = 'invoice_details';
# initHelperAuto();
# PROCESS 'helpers/datatables.tt';
clearHelper();
helper.name = c.loc('Invoice Details');
helper.name_single = c.loc('Invoice Record');
helper.identifier = 'invoice_details';
initHelperAuto();
PROCESS 'helpers/datatables.tt';
-%]
<table class="table table-bordered table-striped table-highlight table-hover">
<thead>
<tr>
<th>[% c.loc('Num') %]</th>
<th>[% c.loc('Zone') %]</th>
<th>[% c.loc('Calls amount') %]</th>
<th>[% c.loc('Duration') %]</th>
@ -167,12 +237,13 @@ function handleSaveSvgData(data, error) {
<tbody>
[%# Dumper.dump_html(invoice_details.as_query)%]
[% FOR call IN invoice_details -%]
[%IF call.1; call = call.1; END%]
[%IF call.1; row_number = call.0; call = call.1; END%]
[% total_number = total_number + call.get_column('number') %]
[% total_duration = total_duration + call.get_column('duration') %]
[% total_free_time = total_free_time + call.get_column('free_time') %]
[% total_cost = total_cost + call.get_column('cost') %]
<tr class="sw_action_row">
<td>[% row_number %]</td>
<td>[% call.get_column('zone') %]</td>
<td><div class="pull-right">[% call.get_column('number') %]</div></td>
<td><div class="pull-right">[% call.get_column('duration')|format('%.3f') %]</div></td>
@ -181,7 +252,7 @@ function handleSaveSvgData(data, error) {
</tr>
[%END%]
<tr>
<td>[% c.loc('Total') %]</td>
<td colspan="2">[% c.loc('Total') %]</td>
<td><div class="pull-right">[% total_number %]</div></td>
<td><div class="pull-right">[% total_duration | format('%.3f') %]</div></td>
<td><div class="pull-right">[% total_free_time | format('%d')%]</div></td>
@ -200,22 +271,43 @@ function handleSaveSvgData(data, error) {
<a class="accordion-toggle" data-toggle="collapse" data-parent="#customer_invoice_template" href="#collapse_invoice_template_list">[% c.loc('Invoice Templates') %]</a>
</div>
<div class="accordion-body collapse" id="collapse_invoice_template_list">
[%PROCESS 'customer/invoice_template_list.tt'%]
[%PROCESS 'customer/invoice_template_list.tt' %]
</div>
</div>
</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">
<form name="invoice_template" id="invoice_template" action="[%- c.uri_for_action('/customer/invoice_template', [contract.id]) -%]">
<input type="hidden" name="tt_id" value="">
<div class="ngcp-separator"></div>
<span>
<a class="btn btn-primary btn-large" onclick="showSvgParsed();void(0);">[% c.loc('Refresh Preview')%] <i class="icon-refresh"></i></a>
<a class="btn btn-primary btn-large" onclick="
savePreviewedAndShowParsed({
contract_id:'[%contract.id%]',
tt_id: $('form[name=invoice_template] input[name=tt_id]').val()
});void(0);">[% c.loc('Refresh Preview')%] <i class="icon-refresh"></i></a>
</span>
<span>
<a class="btn btn-primary btn-large" onclick="saveSvg();void(0);">[% c.loc('Save template')%] <i class="icon-disk"></i></a>
<a class="btn btn-primary btn-large" onclick="saveTemplate({contract_id:'[%contract.id%]',tt_id: $('form[name=invoice_template] input[name=tt_id]').val()});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" width="550px" height="750px" id="svgedit" onload="init_embed();loadSvg('/svg/raw/[%- initial -%]');" style="border-width:0px;"></iframe><iframe src="[%- c.uri_for_action('/customer/invoice_template', [contract.id]) -%]/svg/parsed/[%- initial -%]" width="600px" height="750px" id="svgpreview" style="border-width:0px;"></iframe>
<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: $('form[name=invoice_template] input[name=tt_id]').val()
});" 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>
</div>

@ -1,5 +1,6 @@
[%USE Dumper%]
[%USE Math%]
[% total = {perpage => [], global => {} } -%]
[%MACRO row_y_re(tt_type) BLOCK -%]
[% IF tt_type == 'svg' -%]
@ -50,7 +51,7 @@
[%page%]
[%END%]
[%MACRO adjustrow(data, rowtype, tt_type, row_vertical_interval, rownumber) BLOCK -%]
[%MACRO adjustrow(data, page, rowtype, tt_type, row_vertical_interval, rownumber) BLOCK -%]
[%# y_re = row_y_re(tt_type) %]
[% row = get_row(data, rowtype) %]
@ -65,13 +66,17 @@
[%row%]
[%END -%]
[%MACRO list_calls(callsdata, rowtype, total, tt_type, row_vertical_interval) BLOCK-%]
[%MACRO list_calls(callsdata, page, rowtype, total, tt_type, row_vertical_interval) BLOCK-%]
[% FOR call IN callsdata -%][%#invoice_details%]
[% total.number = total.number + call.get_column('number') -%]
[% total.duration = total.duration + call.get_column('duration') -%]
[% total.free_time = total.free_time + call.get_column('free_time') -%]
[% total.cost = total.cost + call.get_column('cost') -%]
[% adjustrow(call, rowtype, tt_type, row_vertical_interval, loop.count) -%]
[% total.global.number = total.number + call.get_column('number') -%]
[% total.global.duration = total.duration + call.get_column('duration') -%]
[% total.global.free_time = total.free_time + call.get_column('free_time') -%]
[% total.global.cost = total.cost + call.get_column('cost') -%]
[% total.perpage.${page}.number = total.number + call.get_column('number') -%]
[% total.perpage.${page}.duration = total.duration + call.get_column('duration') -%]
[% total.perpage.${page}.free_time = total.free_time + call.get_column('free_time') -%]
[% total.perpage.${page}.cost = total.cost + call.get_column('cost') -%]
[% adjustrow(call, page, rowtype, tt_type, row_vertical_interval, loop.count) -%]
[%END -%]
[%END -%]

@ -1,10 +1,22 @@
[% USE Dumper %]
[% USE format %]
[% money_format = format('%.2f') %]
[% IF !c.user.read_only && (c.user.roles == 'admin' || c.user.roles == 'reseller') -%]
[% write_access = 1 %]
[%END%]
<div class="accordion-inner" style="overflow:auto; height: 300px;">
[% IF write_access -%]
<span>
<a class="btn btn-primary btn-large" onclick="loadSvg('/svg/raw/default');void(0);">[% c.loc('Create invoice template')%] <i class="icon-edit"></i></a>
<a class="btn btn-primary btn-large" onclick="fetchSvgToEditor({
tt_viewmode: 'raw',
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 %]
<table class="table table-bordered table-striped table-highlight table-hover">
<thead>
<tr>
@ -15,32 +27,37 @@
</tr>
</thead>
<tbody>
[%# Dumper.dump_html(invoice_template_list.as_query)%]
[% FOR template IN invoice_template_list -%]
[%# Dumper.dump_html(invoice_template_list.as_query)%]
[%# Dumper.dump_html(template)%]
<tr class="sw_action_row">
<td>[% template.get_column('is_active') %]</td>
<td>[% template.get_column('type') %]</td>
<td>[%# template.get_column('name') %]</td>
<td>=[%template.get_column('id')%]:[%- c.uri_for_action("/customer/invoice_template_delete", [contract.id, template.get_column('id')]) -%]= [%# template.get_column('name') %]</td>
<td class="ngcp-actions-column">
<div class="sw_actions">
[% IF write_access -%]
[%IF template.get_column('base64_previewed')%]
<a class="btn btn-primary btn-small"
onclick="loadSvg('/svg/raw/previewed');void(0);">
onclick="loadSvg('/svg/raw/previewed/svg/[%template.get_column('id')%]');void(0);">
<i class="icon-edit"></i> [% c.loc('Edit previewed') %]
</a>
[%END%]
[%IF template.get_column('base64_saved')%]
<a class="btn btn-small btn-primary"
onclick="loadSvg('/svg/raw/saved');void(0);">
onclick="loadSvg('/svg/raw/saved/svg/[%template.get_column('id')%]');void(0);">
<i class="icon-edit"></i> [% c.loc('Edit saved') %]
</a>
[%END%]
[%IF !template.is_active%]
<a class="btn btn-small btn-primary"
onclick="makeDefault();void(0);">
onclick="switchDefault();void(0);">
<i class="icon-edit"></i> [% c.loc('Make active') %]
</a>
[%END%]
<a class="btn btn-small btn-primary" data-confirm="Delete"
onclick="fetch_into('collapse_invoice_template_list', '[%- c.uri_for_action("/customer/invoice_template", [contract.id]) -%]', q, callback);void(0);">
<a class="btn btn-small btn-secondary" data-confirm="Delete"
onclick="fetch_into('collapse_invoice_template_list', '[%- c.uri_for_action("/customer/invoice_template_delete", [contract.id, template.get_column('id')]) -%]');void(0);">
<i class="icon-trash"></i> [% c.loc('Delete') %]
</a>
[%END%]
@ -58,4 +75,5 @@
[%END%]
</tbody>
</table>
[%END%]
</div>

@ -134,10 +134,9 @@ g, text, tspan {
</text>
<!--{[%END-%]}-->
<!--{[% titlerow -%]}-->
<!--{[% total = {} -%]}-->
<!--{[% list_calls(callsdata, 'datarow', total, 'svg', row_vertical_interval) -%]}-->
<!--{[% adjustrow (total, 'totalrow', 'svg', row_vertical_interval, callsdata.size) -%]}-->
<!--{[% titlerow(page) -%]}-->
<!--{[% list_calls(callsdata, page, 'datarow', total, 'svg', row_vertical_interval) -%]}-->
<!--{[% adjustrow (total, page, 'totalrow', 'svg', row_vertical_interval, callsdata.size) -%]}-->
</g>
@ -181,10 +180,9 @@ g, text, tspan {
<tspan x="190" id="midpage_calls_total_cost"><!--{[% ( total_cost / 100 )|format('%.2f') %]}--><!--{[%#}-->0.00<!--{%]}--></tspan>
</text>
<!--{[%END-%]}-->
<!--{[% titlerow -%]}-->
<!--{[% total = {} -%]}-->
<!--{[% list_calls(callsdata, 'datarow', total, 'svg', row_vertical_interval) -%]}-->
<!--{[% adjustrow (total, 'totalrow', 'svg', row_vertical_interval, callsdata.size) -%]}-->
<!--{[% titlerow(page) -%]}-->
<!--{[% list_calls(callsdata, page, 'datarow', total, 'svg', row_vertical_interval) -%]}-->
<!--{[% adjustrow (total, page, 'totalrow', 'svg', row_vertical_interval, callsdata.size) -%]}-->
</g>
</g>
@ -232,8 +230,8 @@ g, text, tspan {
<!--{[% titlerow -%]}-->
<!--{[% list_calls(callsdata, 'datarow', total, 'svg', row_vertical_interval) -%]}-->
<!--{[% adjustrow (total, 'totalrow', 'svg', row_vertical_interval, callsdata.size) -%]}-->
<!--{[% list_calls(callsdata, page, 'datarow', total, 'svg', row_vertical_interval) -%]}-->
<!--{[% adjustrow (total, page, 'totalrow', 'svg', row_vertical_interval, callsdata.size) -%]}-->
</g>
</g>
<!--/page-->

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Loading…
Cancel
Save