MT#5879 Separate actions for invoice templates. Saving and view should be separated too. Rename ttemplates: calls to invoice and "template" according to content.

ipeshinskaya/InvoiceTemplate5
Irina Peshinskaya 11 years ago committed by Victor Seva
parent 6fdd7d43ab
commit 3e557152bc

@ -812,13 +812,30 @@ sub edit_balance :Chained('base') :PathPart('balance/edit') :Args(0) {
$c->stash(edit_flag => 1);
}
sub invoice :Chained('base') :PathPart('invoice') :CaptureArgs(0) {
sub invoice_data :Chained('base') :PathPart('invoice') :CaptureArgs(0) {
my ($self, $c) = @_;
$c->stash(template => 'customer/invoice.tt');
}
$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_template_list :Chained('invoice') :PathPart('') :CaptureArgs(0) {
#look, NGCP::Panel::Utils::Contract - it is kind of backend separation here
my $zonecalls_rs = NGCP::Panel::Utils::Contract::get_contract_calls_rs(
c => $c,
contract_id => $contract_id,
stime => $stime,
etime => $etime,
);
#FAKE FAKE FAKE FAKE
$zonecalls_rs = [$zonecalls_rs->all()];
my $i = 1;
$zonecalls_rs = [map{[$i++,$_]} (@$zonecalls_rs) x 21];
$c->stash(zonecalls_rs => $zonecalls_rs );
}
#method separated as some day
sub invoice_template_list :Chained('invoice_data') :PathPart('') :CaptureArgs(0) {
my ($self, $c) = @_;
$c->log->debug('invoice_template_list');
my($validator,$backend,$in,$out);
#this is just copy-paste from method above
@ -861,31 +878,14 @@ sub invoice_template_list :Chained('invoice') :PathPart('') :CaptureArgs(0) {
#think about it more
#$out->{invoice_template_list} = $backend->getCustomerInvoiceTemplateList( %$in );
$c->stash(invoice_template_list => $backend->getCustomerInvoiceTemplateList( %$in ) );
$c->stash( invoice_template_list => $backend->getCustomerInvoiceTemplateList( %$in )->all );
}
sub invoice_data :Chained('invoice_template_list') :PathPart('') :CaptureArgs(0) {
sub invoice :Chained('invoice_template_list') :PathPart('') :Args(0) {
my ($self, $c) = @_;
$c->log->debug('calls_list');
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 $zonecalls_rs = NGCP::Panel::Utils::Contract::get_contract_calls_rs(
c => $c,
contract_id => $contract_id,
stime => $stime,
etime => $etime,
);
#FAKE FAKE FAKE FAKE
$zonecalls_rs = [$zonecalls_rs->all()];
my $i = 1;
$zonecalls_rs = [map{[$i++,$_]} (@$zonecalls_rs) x 21];
$c->stash(zonecalls_rs => $zonecalls_rs );
$c->stash(template => 'customer/invoice.tt');
}
sub invoice_template :Chained('invoice_data') :PathPart('') :CaptureArgs(5) {
sub invoice_template :Chained('invoice_data') :PathPart('template') :Args {
my ($self, $c) = @_;
#$c->log->debug($c->model('DB'));
#return;
@ -894,7 +894,7 @@ sub invoice_template :Chained('invoice_data') :PathPart('') :CaptureArgs(5) {
#my $contract_id = $in->{contract_id} = ;
#no warnings 'uninitialized';
no warnings 'uninitialized';
my($validator,$backend,$in,$out);
@ -949,7 +949,8 @@ sub invoice_template :Chained('invoice_data') :PathPart('') :CaptureArgs(5) {
}elsif($in->{tt_type} eq 'html'){
$in->{tt_output_type} = 'html';
}
#use irka;
#use Data::Dumper;
#irka::loglong(Dumper($in));
#model logic

@ -56,14 +56,14 @@ has_field 'tt_string' => (
);
has_field 'contract_id' => (
type => 'Number',
type => 'Text',
#default => \&
#apply => [ { check => \&validate_tt_string } ],
required => 1,
);
has_field 'tt_id' => (
type => 'Number',
type => 'Text',
#default => \&
#apply => [ { check => \&validate_tt_string } ],
required => 0,

@ -77,5 +77,12 @@ sub storeCustomerInvoiceTemplate{
}
});
}
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({
reseller_id => $contract_id,
});
}
1;

@ -1,4 +1,6 @@
package NGCP::Panel::Utils::InvoiceTemplate;
#it should be part of real model, or subcontroller
use strict;
use warnings;
use Moose;
@ -7,7 +9,7 @@ use Sipwise::Base;
sub getDefaultInvoiceTemplate{
my (%in) = @_;
#in future may be we will store root default in Db too, but now it is convenient to edit template as file
my $result = $in{c}->view('SVG')->getTemplateContent($in{c}, 'customer/calls_'.$in{type}.'.tt');
my $result = $in{c}->view('SVG')->getTemplateContent($in{c}, 'customer/invoice_template_'.$in{type}.'.tt');
#$in{c}->log->debug("result=$result;");

@ -56,7 +56,11 @@ sub getTemplateContent{
}
sub getTemplateProcessed{
my ( $self, $c, $template, $stash ) = @_;
#$c->log->debug("getTemplateProcessed: template=$template;");
#my $result = $self->{template}->context->process($template, $stash);
#$c->log->debug("getTemplateProcessed: result=$result;");
#return $result
return $self->{template}->context->process($template, $stash);
}

@ -399,30 +399,20 @@
</div>
</div>
[%BLOCK accordion_group_internal %]
<div class="accordion-body collapse" id="[%id%]">
<div class="accordion-inner">
<table class="table table-bordered table-striped table-highlight table-hover">
[% content %]
</table>
</div>
</div>
[%END%]
[%BLOCK accordion_group %]
[%# USE Dumper %]
[%# Dumper.dump(zonecalls_rs)%]
[%# zonecalls_rs.size%]
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#customer_details" href="#[%id%]">[% c.loc(title) %]</a>
<a class="accordion-toggle" data-toggle="collapse" data-parent="#customer_details" href="#collapse_calls">[% c.loc('Balance details') %]</a>
</div>
[%content%]
</div>
[%END%]
[% USE Dumper %]
[%# Dumper.dump(zonecalls_rs)%]
[%# zonecalls_rs.size%]
[% WRAPPER accordion_group id="collapse_calls" title=c.loc('Balance details') %]
[% WRAPPER accordion_group_internal id="collapse_calls" title='Balance details' %]
<div class="accordion-body collapse" id="collapse_calls">
<div class="accordion-inner" style="height: 300px; overflow: auto;">
<span>
<a class="btn btn-primary btn-large" href="[% c.uri_for_action('/customer/invoice', [contract.id]) %]">[% c.loc('Invoice Template')%] <i class="icon-edit"></i></a>
</span>
<div class="ngcp-separator"></div>
<table class="table table-bordered table-striped table-highlight table-hover">
<thead>
<tr>
<th>[% c.loc('Zone') %]</th>
@ -430,12 +420,12 @@
<th>[% c.loc('Duration') %]</th>
<th>[% c.loc('Free time') %]</th>
<th>[% c.loc('Cash') %]</th>
<th class="ngcp-actions-column"></th>
</tr>
</thead>
<tbody>
[%# Dumper.dump_html(zonecalls_rs.as_query)%]
[% FOR call IN zonecalls_rs -%]
[%IF call.1; 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') %]
@ -446,14 +436,6 @@
<td><div class="pull-right">[% call.get_column('duration')|format('%.3f') %]</div></td>
<td><div class="pull-right">[% call.get_column('free_time')|format('%d') %]</div></td>
<td><div class="pull-right">[% money_format( call.get_column('cost') / 100 ) %]</div></td>
<td class="ngcp-actions-column">
<div class="sw_actions pull-right">
<a class="btn btn-small btn-primary"
href="[% c.uri_for_action("/customer/calls", [contract.id]) %]">
<i class="icon-edit"></i> [% c.loc('Edit') %]
</a>
</div>
</td>
</tr>
[%END%]
<tr>
@ -462,18 +444,12 @@
<td><div class="pull-right">[% total_duration | format('%.3f') %]</div</td>
<td><div class="pull-right">[% total_free_time | format('%d')%]</div</td>
<td><div class="pull-right">[% money_format( total_cost / 100 ) %]</div></td>
<td class="ngcp-actions-column">
<div class="sw_actions pull-right">
<a class="btn btn-small btn-primary"
href="[% c.uri_for_action("/customer/calls", [contract.id]) %]">
<i class="icon-edit"></i> [% c.loc('Edit') %]
</a>
</div>
</td>
</tr>
</tbody>
[%END%]
[%END%]
</table>
</div>
</div>
</div>
[% IF c.user.roles == 'admin' || c.user.roles == 'reseller' %]
<div class="accordion-group">

@ -1,73 +1,26 @@
[% IF c.user.roles == "subscriber" || c.user.roles == "subscriberadmin" -%]
[% site_config.title = c.loc('Customer Calls') -%]
[% site_config.title = c.loc('Invoice template manager') -%]
[% ELSE -%]
[% site_config.title = c.loc('Customer Calls for #[_1] ([_2])',contract.id, product.name) -%]
[% site_config.title = c.loc('Customer Invoice template for #[_1] ([_2])',contract.id, product.name) -%]
[% END -%]
[% BLOCK accordion_group_internal %]
<div class="accordion-inner">
<table class="table table-bordered table-striped table-highlight table-hover">
[% content %]
</table>
</div>
[% IF !c.user.read_only && (c.user.roles == 'admin' || c.user.roles == 'reseller') -%]
[% write_access = 1 %]
[%END%]
<div class="row">
<span>
<a class="btn btn-primary btn-large" href="[% c.uri_for('/back') %]"><i class="icon-arrow-left"></i> [% c.loc('Back') %]</a>
</span>
</div>
<div class="ngcp-separator"></div>
[% back_created = 1 -%]
[% USE Dumper %]
[% WRAPPER accordion_group_internal id="collapse_calls" title='Balance details' %]
<thead>
<tr>
<th>[% c.loc('Zone') %]</th>
<th>[% c.loc('Calls amount') %]</th>
<th>[% c.loc('Duration') %]</th>
<th>[% c.loc('Free time') %]</th>
<th>[% c.loc('Cash') %]</th>
<th class="ngcp-actions-column"></th>
</tr>
</thead>
<tbody>
[%# Dumper.dump_html(zonecalls_rs.as_query)%]
[% FOR call IN zonecalls_rs -%]
[%IF call.1; 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>[% 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>
<td><div class="pull-right">[% call.get_column('free_time')|format('%d') %]</div></td>
<td><div class="pull-right">[% money_format( call.get_column('cost') / 100 ) %]</div></td>
<td class="ngcp-actions-column">
<div class="sw_actions pull-right">
<a class="btn btn-small btn-primary"
href="[% c.uri_for_action("/customer/calls", [contract.id]) %]">
<i class="icon-edit"></i> [% c.loc('Edit') %]
</a>
</div>
</td>
</tr>
[%END%]
<tr>
<td>[% c.loc('Total') %]</td>
<td><div class="pull-right">[% total_number %]</td>
<td><div class="pull-right">[% total_duration | format('%.3f') %]</div</td>
<td><div class="pull-right">[% total_free_time | format('%d')%]</div</td>
<td><div class="pull-right">[% money_format( total_cost / 100 ) %]</div></td>
<td class="ngcp-actions-column">
<div class="sw_actions pull-right">
<a class="btn btn-small btn-primary"
href="[% c.uri_for_action("/customer/calls", [contract.id]) %]">
<i class="icon-edit"></i> [% c.loc('Edit') %]
</a>
</div>
</td>
</tr>
</tbody>
[%END%]
<script type="text/javascript" src="/js/libs/svg-edit/embedapi.js"></script>
<script type="text/javascript" src="/js/background.js"></script>
<script type="text/javascript">
var svgCanvas = null;
@ -87,13 +40,13 @@ function init_embed() {
}
function loadSvg(params) {
alert('[%- c.uri_for_action("/customer/calls_svg", [contract.id]) -%]'+params);
background( '[%- c.uri_for_action("/customer/calls_svg", [contract.id]) -%]'+params,'',
function(httpResponse){
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){
//alert(httpResponse);
svgCanvas.setSvgString(httpResponse);
}
);
svgCanvas.setSvgString(svgParsedString);
});
//'/customer/[%contract.id%]/calls/svg'
//var svgexample = '<svg width="640" height="480" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><g><title>Layer 1</title><rect stroke-width="5" stroke="#000000" fill="#FF0000" id="svg_1" height="35" width="51" y="35" x="32"/><ellipse ry="15" rx="24" stroke-width="5" stroke="#000000" fill="#0000ff" id="svg_2" cy="60" cx="66"/></g></svg>';
//svgCanvas.setSvgString(svgexample);
@ -102,7 +55,7 @@ function loadSvg(params) {
function showSvgParsed(){
svgCanvas.getSvgString()(handleShowSvgParsedData);
}
function handleShowSvgParsedData(data, error) {
function handleShowSvgParsedData(svgString, error) {
if (error)
{
alert('error ' + error);
@ -111,64 +64,59 @@ function handleShowSvgParsedData(data, error) {
{
//alert('Congratulations. Your SVG string is back in the host page, do with it what you will\n\n' + data);
//alert(encodeURIComponent(data));
var q = '[%- c.uri_for_action("/customer/calls_svg", [contract.id]) -%]'+'/svg/parsed/previewed';
var q = '[%- c.uri_for_action("/customer/invoice_template", [contract.id]) -%]'+'/svg/parsed/previewed';
//alert(q);
//alert(data);
background( q ,'template='+encodeURIComponent(data),
function(httpResponse){
//alert(httpResponse);
var previewIframe = document.getElementById('svgpreview'); //new Image();
var previewDoc = previewIframe.contentWindow.document;
//if(previewIframe.contentDocument) {
// doc = previewIframe.contentDocument;
//} else {
// doc = previewIframe.contentWindow.document;
//}
//previewIframe.contentWindow.document.body.innerHTML='<html></html>';
//alert(doc);
var pages = new Array();
pages = httpResponse.match(/(<svg[\r\n\t\s\S\w\W]*?(?:\/svg>))/gi );
if(!pages){
pages = new Array();
}
alert('images='+previewDoc.images.length+';pages='+pages.length);
if(pages.length > 0 ){
previewIframe.src = '';
previewDoc.body.innerHTML = '<html><body>'+httpResponse+'</body></html>';
alert(previewDoc.body.innerHTML);
/*
var i;
for( i = 0; i < previewDoc.images.length; i++ ){
var img = previewDoc.images[i];
img.parentElement.remove(img);
}
for( i = 0; i < pages.length; i++ ){
img = previewDoc.createElement('img');
//alert(img);
//img.width=215;
//img.heith=297;
img.src = "data:image/svg+xml," + encodeURIComponent(pages[i]);
}
alert('images='+previewDoc.images.length);
alert(previewDoc.body.innerHTML);
*/
}else{
previewIframe.src = "data:image/svg+xml," + encodeURIComponent(httpResponse);
$.post( q, { template: svgString })
.done( function( svgParsedString ) {
//alert(svgParsedString);
var previewIframe = document.getElementById('svgpreview'); //new Image();
var previewDoc = previewIframe.contentWindow.document;
//if(previewIframe.contentDocument) {
// doc = previewIframe.contentDocument;
//} else {
// doc = previewIframe.contentWindow.document;
//}
//previewIframe.contentWindow.document.body.innerHTML='<html></html>';
//alert(doc);
var pages = new Array();
pages = svgParsedString.match(/(<svg[\r\n\t\s\S\w\W]*?(?:\/svg>))/gi );
if(!pages){
pages = new Array();
}
alert('images='+previewDoc.images.length+';pages='+pages.length);
if(pages.length > 0 ){
previewIframe.src = '';
previewDoc.body.innerHTML = '<html><body>'+svgParsedString+'</body></html>';
alert(previewDoc.body.innerHTML);
/*
var i;
for( i = 0; i < previewDoc.images.length; i++ ){
var img = previewDoc.images[i];
img.parentElement.remove(img);
}
//alert(img.outerHTML);
//alert(img.html());
for( i = 0; i < pages.length; i++ ){
img = previewDoc.createElement('img');
//alert(img);
//img.width=215;
//img.heith=297;
img.src = "data:image/svg+xml," + encodeURIComponent(pages[i]);
}
alert('images='+previewDoc.images.length);
alert(previewDoc.body.innerHTML);
*/
}else{
previewIframe.src = "data:image/svg+xml," + encodeURIComponent(svgParsedString);
}
);
}
//alert(img.outerHTML);
//alert(img.html());
});
}
}
function saveSvg() {
svgCanvas.getSvgString()(handleSvgData);
svgCanvas.getSvgString()(handleSaveSvgData);
}
function handleSaveSvgData(data, error) {
if (error)
@ -177,19 +125,147 @@ function handleSaveSvgData(data, error) {
}
else
{
var q = '[%- c.uri_for_action("/customer/invoice_template", [contract.id]) -%]'+'/svg/parsed/saved';
//alert(q);
//alert(data);
//alert('Congratulations. Your SVG string is back in the host page, do with it what you will\n\n' + data);
//alert(encodeURIComponent(data));//works in ie
background('[%- c.uri_for_action("/customer/calls_svg", [contract.id]) -%]'+'/svg/parsed/saved','template='+encodeURIComponent(data));
$.post( q, { template: encodeURIComponent(data) })
.done(function( httpResponse ) {
});
}
}
</script>
<button onclick="loadSvg('/svg/raw/default');">Load system default invoice template</button>
<button onclick="loadSvg('/svg/raw/saved');">Load saved invoice template</button>
<button onclick="loadSvg('/svg/raw/previewed');">Load previewed template</button>
<div class="accordion" id="customer_invoice_template">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#customer_invoice_template" href="#collapse_calls">[% c.loc('Invoice details') %]</a>
</div>
<div class="accordion-body collapse" id="collapse_calls">
<div class="accordion-inner" style="overflow:auto; height: 300px;">
<table class="table table-bordered table-striped table-highlight table-hover">
<thead>
<tr>
<th>[% c.loc('Zone') %]</th>
<th>[% c.loc('Calls amount') %]</th>
<th>[% c.loc('Duration') %]</th>
<th>[% c.loc('Free time') %]</th>
<th>[% c.loc('Cash') %]</th>
<th class="ngcp-actions-column"></th>
</tr>
</thead>
<tbody>
[%# Dumper.dump_html(zonecalls_rs.as_query)%]
[% FOR call IN zonecalls_rs -%]
[%IF call.1; 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>[% 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>
<td><div class="pull-right">[% call.get_column('free_time')|format('%d') %]</div></td>
<td><div class="pull-right">[% money_format( call.get_column('cost') / 100 ) %]</div></td>
</tr>
[%END%]
<tr>
<td>[% 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>
<td><div class="pull-right">[% money_format( total_cost / 100 ) %]</div></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<span>
<div class="accordion-group">
<div class="accordion-heading">
<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">
<div class="accordion-inner" style="overflow:auto; height: 300px;">
[% IF write_access -%]
<span>
<a class="btn btn-primary btn-large" href="[% c.uri_for_action('/customer/invoice', [contract.id]) %]" onclick="loadSvg('/svg/raw/default');void(0);">[% c.loc('Create invoice template')%] <i class="icon-edit"></i></a>
</span>
<div class="ngcp-separator"></div>
[% END -%]
<table class="table table-bordered table-striped table-highlight table-hover">
<thead>
<tr>
<th>[% c.loc('Active') %]</th>
<th>[% c.loc('Type') %]</th>
<th>[%# c.loc('Name') %]</th>
<th class="ngcp-actions-column"></th>
</tr>
</thead>
<tbody>
[%# Dumper.dump_html(invoice_template_list.as_query)%]
[% FOR template IN invoice_template_list -%]
<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 class="ngcp-actions-column">
<div class="sw_actions pull-right">
[% IF write_access -%]
<a class="btn btn-small btn-primary"
href="[% c.uri_for_action("/customer/invoice", [contract.id]) %]" onclick="loadSvg('/svg/raw/previewed');void(0);">
<i class="icon-edit"></i> [% c.loc('Edit previewed') %]
</a>
<a class="btn btn-small btn-primary"
href="[% c.uri_for_action("/customer/invoice", [contract.id]) %]" onclick="loadSvg('/svg/raw/saved');void(0);">
<i class="icon-edit"></i> [% c.loc('Edit saved') %]
</a>
[%IF !template.is_active%]
<a class="btn btn-small btn-primary"
href="[% c.uri_for_action("/customer/invoice", [contract.id]) %]" onclick="makeDefault();void(0);">
<i class="icon-edit"></i> [% c.loc('Make active') %]
</a>
[%END%]
[%END%]
<a class="btn btn-small btn-primary"
href="[% c.uri_for_action("/customer/invoice", [contract.id]) %]" onclick="loadSvg('/svg/raw/saved/zip');void(0);">
<i class="icon-edit"></i> [% c.loc('Download source') %]
</a>
<a class="btn btn-small btn-primary"
href="[% c.uri_for_action("/customer/invoice", [contract.id]) %]" onclick="loadSvg('/svg/parsed/saved/pdf');void(0);">
<i class="icon-edit"></i> [% c.loc('Download invoice') %]
</a>
</div>
</td>
</tr>
[%END%]
</tbody>
</table>
<button onclick="showSvgParsed();">Refresh Preview</button>
<button onclick="saveSvg();">Save template</button>
<!--upload css-->
<!--name-->
<br/>
[%initial = 'saved'%]
<iframe type="text/html" src="/js/libs/svg-edit/svg-editor.htm" width="600px" height="600px" id="svgedit" onload="init_embed();loadSvg('/svg/raw/[%- initial -%]');" class="display:inline;"></iframe><iframe src="[%- c.uri_for_action('/customer/calls_svg', [contract.id]) -%]/svg/parsed/[%- initial -%]" width="550px" height="600px" id="svgpreview" class="display:inline;"><canvas id="svgpreview_canvas" width="200" height="200"></canvas>
<iframe type="text/html" src="/js/libs/svg-edit/svg-editor.htm" width="600px" height="600px" id="svgedit" onload="init_embed();loadSvg('/svg/raw/[%- initial -%]');" class="display:inline;"></iframe><iframe src="[%- c.uri_for_action('/customer/invoice_template', [contract.id]) -%]/svg/parsed/[%- initial -%]" width="550px" height="600px" id="svgpreview" class="display:inline;"><canvas id="svgpreview_canvas" width="200" height="200"></canvas>
</div>
</div>
</div>
</span>
</div>

@ -55,7 +55,7 @@
[% row = get_row(data, rowtype) %]
[% IF tt_type == 'svg' -%]
[% y_re = '(?s)(<text[^>]*\s+y\s?=.*?)(\d+)(.*)' -%]
[% y_re = '(?s)(<(?:g)[^>]*\s+y\s?=.*?)(\d+)(.*)' -%]
[%END%]
[% matches = row.match( y_re ) -%]
[% IF matches.size > 0 -%]

@ -1,4 +1,4 @@
<!--{[%PROCESS 'customer/calls_template.tt' -%]}-->
<!--{[%PROCESS 'customer/invoice_template.tt' -%]}-->
<!--{[%row_vertical_interval = 10 -%]}-->
<!--{[%MACRO document_header BLOCK-%]}-->
@ -578,18 +578,19 @@ g, text, tspan {
fill:#000000;fill-opacity:1;fill-rule:nonzero;
stroke:none;
//font-family: impact, georgia, times, serif;
//font-family:HelveticaNeue;
//font-family:Arial;
//font-family:HelveticaNeue-Light;
//font-weight:300;
//-inkscape-font-specification:HelveticaNeue-Light;
*/
font-family:Times;
*/
font-family:HelveticaNeue;
font-variant:normal;
font-size:2.6pt;
writing-mode:lr;
color: #FF0000;
fill: #FF0000;
}
]]>
</style>
<!--pageSet-->
@ -645,7 +646,9 @@ g, text, tspan {
</text>
<!--{[%END-%]}-->
<!--{[%MACRO datarow(call) BLOCK-%]}-->
<text y="10" text-anchor="end" id="calls[%loop.count-%]" class="datarow">
<g y="10" text-anchor="end" id="calls[%loop.count-%]_group" class="datarow">
<rect width="200" height="10" stroke-width="0.05" stroke="#FF0000" fill="#CCCCCC" id="calls[%loop.count-%]_textborder"/>
<text text-anchor="end" id="calls[%loop.count-%]_text" class="datarow">
<tspan x="5" id="calls_number[%loop.count-%]" text-anchor="start"><!--{[% call.0 %]}--><!--{[%#}-->1<!--{%]}--></tspan>
<!--{[%IF call.1; call = call.1; END%]}-->
<tspan x="15" id="calls_zone[%loop.count-%]" text-anchor="start"><!--{[% call.get_column('zone') %]}--><!--{[%#}-->Example zone<!--{%]}--></tspan>
@ -654,6 +657,7 @@ g, text, tspan {
<tspan x="160" id="calls_freetime[%loop.count-%]"><!--{[% call.get_column('free_time')|format('%d') %]}--><!--{[%#}-->0.0<!--{%]}--></tspan>
<tspan x="190" id="calls_cost[%loop.count-%]"><!--{[% ( call.get_column('cost') / 100 ) |format('%.2f') %]}--><!--{[%#}-->0.00<!--{%]}--></tspan>
</text>
</g>
<!--{[%END-%]}-->
<!--{[%MACRO totalrow BLOCK-%]}-->
<text y="20" text-anchor="end" id="calls_total" class="datarow">

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Loading…
Cancel
Save