Save state with incorrect, but fast svg template apply

agranig/subprof
Irka 12 years ago
parent e923b71022
commit fb891ee0ed

@ -57,9 +57,6 @@ __PACKAGE__->config(
},
'View::HTML' => {
INCLUDE_PATH => [
'/usr/share/ngcp-panel/templates',
'/usr/share/ngcp-panel/layout',
'/usr/share/ngcp-panel/static',
__PACKAGE__->path_to('share', 'templates'),
__PACKAGE__->path_to('share', 'layout'),
__PACKAGE__->path_to('share', 'static'),
@ -67,6 +64,16 @@ __PACKAGE__->config(
ABSOLUTE => 1,
EVAL_PERL => 1,
},
'View::SVG' => {
INCLUDE_PATH => [
__PACKAGE__->path_to('share', 'templates'),
__PACKAGE__->path_to('share', 'layout'),
__PACKAGE__->path_to('share', 'static'),
],
ABSOLUTE => 1,
EVAL_PERL => 1,
WRAPPER => '',
},
'View::JSON' => {
#Set the stash keys to be exposed to a JSON response
#(sEcho iTotalRecords iTotalDisplayRecords aaData) for datatables
@ -75,7 +82,6 @@ __PACKAGE__->config(
'Plugin::Static::Simple' => {
include_path => [
'/usr/share/ngcp-panel/static',
__PACKAGE__->path_to('share', 'static'),
],
mime_types => {

@ -53,30 +53,7 @@ sub list_customer :Chained('/') :PathPart('customer') :CaptureArgs(0) {
{ name => "status", search => 1, title => $c->loc("Status") },
{ name => "max_subscribers", search => 1, title => $c->loc("Max Number of Subscribers") },
]);
my $rs = NGCP::Panel::Utils::Contract::get_contract_rs(
schema => $c->model('DB'));
if($c->user->roles eq "reseller") {
$rs = $rs->search({
'contact.reseller_id' => $c->user->reseller_id,
}, {
join => 'contact',
});
} elsif($c->user->roles eq "subscriberadmin") {
$rs = $rs->search({
'contact.reseller_id' => $c->user->contract->contact->reseller_id,
}, {
join => 'contact',
});
}
$rs = $rs->search({
'-or' => [
'product.class' => 'sipaccount',
'product.class' => 'pbxaccount',
],
}, {
'join' => {'billing_mappings' => 'product'},
});
my $rs = NGCP::Panel::Utils::Contract::get_contracts_rs_sippbx( c => $c );
$c->stash(
contract_select_rs => $rs,
@ -238,7 +215,6 @@ sub base :Chained('list_customer') :PathPart('') :CaptureArgs(1) {
$c->detach('/denied_page');
}
}
unless(defined($contract_rs->first)) {
NGCP::Panel::Utils::Message->error(
c => $c,
@ -252,6 +228,7 @@ sub base :Chained('list_customer') :PathPart('') :CaptureArgs(1) {
my $stime = NGCP::Panel::Utils::DateTime::current_local()->truncate(to => 'month');
my $etime = $stime->clone->add(months => 1);
my $balance = $contract_rs->first->contract_balances
->find({
start => { '>=' => $stime },
@ -280,12 +257,20 @@ sub base :Chained('list_customer') :PathPart('') :CaptureArgs(1) {
});
}
my $zonecalls_rs = NGCP::Panel::Utils::Contract::get_contract_calls_rs(
c => $c,
contract_id => $contract_id,
stime => $stime,
etime => $etime,
);
my $product_id = $contract_rs->first->get_column('product_id');
NGCP::Panel::Utils::Message->error(
c => $c,
error => "No product for customer contract id $contract_id found",
desc => $c->loc('No product for this customer contract found.'),
) unless($product_id);
my $product = $c->model('DB')->resultset('products')->find($product_id);
NGCP::Panel::Utils::Message->error(
c => $c,
@ -318,6 +303,7 @@ sub base :Chained('list_customer') :PathPart('') :CaptureArgs(1) {
$c->stash(template => 'customer/details.tt');
$c->stash(contract => $contract_rs->first);
$c->stash(contract_rs => $contract_rs);
$c->stash(zonecalls_rs => $zonecalls_rs);
$c->stash(billing_mapping => $billing_mapping);
}
@ -715,6 +701,40 @@ sub edit_balance :Chained('base') :PathPart('balance/edit') :Args(0) {
$c->stash(form => $form);
$c->stash(edit_flag => 1);
}
#https://10.15.20.100:1444/customer/3/balance/edit?back=https%3A%2F%2F10.15.20.100%3A1444%2Fcustomer%2F3%2Fdetails
sub calls :Chained('base') :PathPart('calls') :Args(0) {
my ($self, $c) = @_;
# 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);
# my $zonecalls_rs = NGCP::Panel::Utils::Contract::get_contract_calls_rs(
# c => $c,
# contract_id => $contract_id,
# stime => $stime,
# etime => $etime,
# );
$c->stash(template => 'customer/calls.tt');
#$c->stash(zonecalls_rs => $c->stash{zonecalls_rs});
#$c->detach($c->view('SVG'));
# return;
#$c->response->body(JSON::to_json({ methods => $allowed_methods })."\n");
#$c->stash(template => 'customer/calls_svg.tt');
#$c->stash(close_target => $c->uri_for_action("/customer/details", [$c->stash->{contract}->id]));
#$c->stash(template => 'customer/calls.tt');
# $c->stash(contract => $contract_rs->first);
}
sub calls_svg :Chained('base') :PathPart('calls/svg') :Args(0) {
my ($self, $c) = @_;
#die();
#$c->view('SVG');
$c->response->content_type('image/svg+xml');
$c->stash(template => 'customer/calls_svg.tt');
$c->detach($c->view('SVG'));
}
sub pbx_group_ajax :Chained('base') :PathPart('pbx/group/ajax') :Args(0) {
my ($self, $c) = @_;

@ -87,36 +87,9 @@ sub hal_from_customer {
sub customer_by_id {
my ($self, $c, $id) = @_;
# we only return customers, that is, contracts with contacts with a
# reseller
my $customers = NGCP::Panel::Utils::Contract::get_contract_rs(
schema => $c->model('DB'),
my $customers = NGCP::Panel::Utils::Contract::get_contracts_rs_sippbx(
c => $c,
);
$customers = $customers->search({
'contact.reseller_id' => { '-not' => undef },
},{
join => 'contact'
});
$customers = $customers->search({
'-or' => [
'product.class' => 'sipaccount',
'product.class' => 'pbxaccount',
],
},{
join => {'billing_mappings' => 'product' },
'+select' => 'billing_mappings.id',
'+as' => 'bmid',
});
if($c->user->roles eq "admin") {
} elsif($c->user->roles eq "reseller") {
$customers = $customers->search({
'contact.reseller_id' => $c->user->reseller_id,
});
}
return $customers->find($id);
}

@ -191,6 +191,95 @@ sub get_contract_rs {
return $rs;
}
sub get_contracts_rs_sippbx{
my %params = @_;
#pass here $c isn't very good idea, it doesn't allow "simple" call with really relevant information
my $c = $params{c};
# we only return customers, that is, contracts with contacts with a
# reseller
my $customers = get_contract_rs(
schema => $c->model('DB'),
);
#really here we don't need role - we can pass only reseller_id, reseller_id should be tacken according to role in other method
my @reseller_condition = ({ '-not' => undef });
if($c->user->roles eq "reseller") {
push @reseller_condition, $c->user->reseller_id;
} elsif($c->user->roles eq "subscriberadmin") {
push @reseller_condition, $c->user->contract->contact->reseller_id;
} elsif($c->user->roles eq "admin") {
}
my $reseller_condition = $#reseller_condition > 1
? { '-and' => \@reseller_condition }
: $reseller_condition[0];
$customers = $customers->search({
'contact.reseller_id' => $reseller_condition ,
},{
join => 'contact'
});
$customers = $customers->search({
'-or' => [
'product.class' => 'sipaccount',
'product.class' => 'pbxaccount',
],
},{
join => {'billing_mappings' => 'product' },
'+select' => 'billing_mappings.id',
'+as' => 'bmid',
});
return $customers;
}
sub get_contract_calls_rs{
my %params = @_;
(my ($c,$contract_id,$stime,$etime)) = @params{qw/c contract_id stime etime/};
# SELECT 'out' as direction, SUM(c.source_customer_cost) AS cost, b.zone,
# COUNT(*) AS number, SUM(c.duration) AS duration
# FROM accounting.cdr c
# LEFT JOIN billing.voip_subscribers v ON c.source_user_id = v.uuid
# LEFT JOIN billing.billing_zones_history b ON b.id = c.source_customer_billing_zone_id
# WHERE v.contract_id = ?
# AND c.call_status = 'ok'
# $start_time $end_time
# GROUP BY b.zone
my $zonecalls_rs = $c->model('DB')->resultset('cdr')->search( {
# source_user_id => { 'in' => [ map {$_->uuid} @{$contract->{subscriber}} ] },
call_status => 'ok',
source_user_id => { '!=' => '0' },
source_account_id => $contract_id,
# start_time =>
# [ -and =>
# { '>=' => $stime->epoch},
# { '<=' => $etime->epoch},
# ],
# {
# '>=' => ["unix_timestamp(?)", $stime],
# '<=' => ["unix_timestamp(?)",$etime] },
# { '>=' => \[ "unix_timestamp(?)", $stime ] },
# { '<=' => \[ "unix_timestamp(?)", $etime ] },
#requires fix: 757 #$self->_assert_bindval_matches_bindtype(@sub_bind);
#in SQL::Abstract,
},{
'select' => [
{ sum => 'me.source_customer_cost', -as => 'cost', },
{ sum => 'me.source_customer_free_time', -as => 'free_time', } ,
{ sum => 'me.duration', -as => 'duration', } ,
{ count => '*', -as => 'number', } ,
'billing_zones_history.zone',
],
'as' => [qw/cost free_time duration number zone/],
join => 'billing_zones_history',
group_by => 'billing_zones_history.zone',
} );
return $zonecalls_rs;
}
1;
=head1 NAME

@ -0,0 +1,28 @@
package NGCP::Panel::View::SVG;
use Sipwise::Base;
use NGCP::Panel::Utils::I18N;
use strict;
extends 'Catalyst::View::TT';
__PACKAGE__->config(
TEMPLATE_EXTENSION => '.tt',
render_die => 1,
ENCODING => 'UTF-8',
WRAPPER => '',
FILTERS => {},
ABSOLUTE => 0,
expose_methods => [],
);
sub process
{
my ( $self, $c ) = @_;
$c->res->content_type("image/svg+xml");
$self->SUPER::process($c);
return 1;
}
1;

@ -0,0 +1,195 @@
[% IF c.user.roles == "subscriber" || c.user.roles == "subscriberadmin" -%]
[% site_config.title = c.loc('Customer Calls') -%]
[% ELSE -%]
[% site_config.title = c.loc('Customer Calls 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>
[%END%]
[% 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.all -%]
[% 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">
var svgCanvas = null;
function init_embed() {
var frame = document.getElementById('svgedit');
svgCanvas = new embedded_svg_edit(frame);
// Hide main button, as we will be controlling new/load/save etc from the host document
var doc;
doc = frame.contentDocument;
if (!doc)
{
doc = frame.contentWindow.document;
}
var mainButton = doc.getElementById('main_button');
mainButton.style.display = 'none';
loadSvg();
}
function handleSvgData(data, error) {
if (error)
{
alert('error ' + error);
}
else
{
//alert('Congratulations. Your SVG string is back in the host page, do with it what you will\n\n' + data);
return data;
}
}
function showSvgData(data, error) {
if (error)
{
alert('error ' + error);
}
else
{
alert('Congratulations. Your SVG string is back in the host page, do with it what you will\n\n' + data);
var img = document.getElementById('svgpreview'); //new Image();
img.src = "data:image/svg+xml," + encodeURIComponent(data);
}
}
function loadSvg() {
background( '[%- c.uri_for_action("/customer/calls_svg", [contract.id]) -%]','', function(httpResponse){
// alert(httpResponse);
svgCanvas.setSvgString(httpResponse);});
//'/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);
}
function saveSvg() {
svgCanvas.getSvgString()(handleSvgData);
}
// Background fetches a page into the specified element
function fetch_into(div, uri, q, callback) {
var xmlHttpReq = false;
// alert(q);
// Mozilla/Safari
if (window.XMLHttpRequest) {
xmlHttpReq = new XMLHttpRequest();
if (typeof xmlHttpReq.overrideMimeType != 'undefined') {
xmlHttpReq.overrideMimeType('text/xml');
}
}
// IE
else if (window.ActiveXObject) {
xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttpReq.open('POST', uri, true);
// xmlHttpReq.open('GET', uri, true);
xmlHttpReq.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xmlHttpReq.onreadystatechange = function() {
if (xmlHttpReq.readyState == 4) {
document.getElementById(div).innerHTML=xmlHttpReq.responseText;
if(typeof callback == 'function'){
callback.call();
}else{
eval(callback);
}
}
}
// alert(q);
xmlHttpReq.send(q);
}
function background(uri,q,callback) {
var xmlHttpReq = false;
if (window.XMLHttpRequest) {
xmlHttpReq = new XMLHttpRequest();
// xmlHttpReq.overrideMimeType('text/xml');
} else if (window.ActiveXObject) {
xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttpReq.open('POST', uri, true);
xmlHttpReq.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
if(callback)
xmlHttpReq.onreadystatechange = function(){
if (xmlHttpReq.readyState == 4) {
if(typeof callback == 'function'){
// alert(xmlHttpReq.responseText);
callback(xmlHttpReq.responseText);
}else{
eval(callback);
}
}
}
xmlHttpReq.send(q);
}
function showSvg(){
svgCanvas.getSvgString()(showSvgData);
}
</script>
<button onclick="loadSvg();">Reload invoice template</button>
<button onclick="showSvg();">Refresh Preview</button>
<button onclick="saveSvg();">Save template</button>
<br/>
<iframe type="text/html" src="/js/libs/svg-edit/svg-editor.htm" width="700px" height="600px" left="50px" id="svgedit" onload="init_embed();loadSvg();"></iframe><iframe src="[%- c.uri_for_action('/customer/calls_svg', [contract.id]) -%]" width="700px" height="600px" id="svgpreview"><canvas id="svgpreview_canvas" width="200" height="200"></canvas>

@ -0,0 +1,42 @@
<svg width="215mm" height="600mm" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<title>TitlePage</title>
<image xlink:href="images/logo.png" height="20mm" width="20mm" y="15mm" x="15mm" id="titlepage_logo"/>
<text xml:space="preserve" y="15mm" x="40mm" text-anchor="left" stroke-width="0" stroke="#000000" fill="#000000" font-size="24" font-family="serif" id="titlepage_customername">{CustomerName}</text>
<text xml:space="preserve" y="40mm" x="40mm" text-anchor="left" stroke-width="0" stroke="#000000" fill="#000000" font-size="24" font-family="serif" id="titlepage_customeraddress">{CustomerAddress}</text>
<text xml:space="preserve" y="60mm" x="40mm" text-anchor="left" stroke-width="0" stroke="#000000" fill="#000000" font-size="24" font-family="serif" id="titlepage_companyname">{CompanyName}</text>
<text xml:space="preserve" y="80mm" x="40mm" text-anchor="left" stroke-width="0" stroke="#000000" fill="#000000" font-size="24" font-family="serif" id="titlepage_companyaddress">{CompanyAddress}</text>
<g y="95mm" x="40mm" text-anchor="start" stroke-width="1" stroke="#000000" fill="#000000" font-size="24" font-family="serif" xml:space="preserve" id="titlepage_companyaddress_custom_1">
<!--rect x="35mm" y="95mm" height="20mm" width="80mm" stroke-width="0.25mm" stroke="#000000" fill="#FFFFFF" id="titlepage_companyaddress_custom_border"/-->
<text y="95mm" id="titlepage_companyaddress_custom_1">address line 1</text>
<text y="100mm" id="titlepage_companyaddress_custom_2">address line 2</text>
<text y="105mm" id="titlepage_companyaddress_custom_3">address line 3</text>
</g>
<text xml:space="preserve" y="130mm" x="10mm" text-anchor="end" stroke-width="0" stroke="#000000" fill="#000000" font-size="14" font-family="serif" id="calls_title">
<tspan x="15mm" id="calls_zone" text-anchor="start">Zone</tspan>
<tspan x="105mm" id="calls_number">Number</tspan>
<tspan x="140mm" id="calls_duration">Duration</tspan>
<tspan x="170mm" id="calls_freetime">Free time</tspan>
<tspan x="200mm" id="calls_cost">Cost</tspan>
</text>
[%calls_height_start = 130-%]
<!--[% FOR call IN zonecalls_rs.all -%]-->
<!--[% 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') -%]-->
<text xml:space="preserve" y="[% calls_height_start + ( 10 * loop.count ) %]mm" x="10mm" text-anchor="end" stroke-width="0" stroke="#000000" fill="#000000" font-size="14" font-family="serif" id="calls[%loop.count-%]">
<tspan x="15mm" id="calls_zone[%loop.count-%]" text-anchor="start">[% call.get_column('zone') %]</tspan>
<tspan x="105mm" id="calls_number[%loop.count-%]">[% call.get_column('number') %]</tspan>
<tspan x="140mm" id="calls_duration[%loop.count-%]">[% call.get_column('duration')|format('%.3f') %]</tspan>
<tspan x="170mm" id="calls_freetime[%loop.count-%]">[% call.get_column('free_time')|format('%d') %]</tspan>
<tspan x="200mm" id="calls_cost[%loop.count-%]">[% ( call.get_column('cost') / 100 ) |format('%.2f') %]</tspan>
</text>
<!--[%END -%]-->
<rect x="0.25mm" y="296.5mm" height="11.5mm" width="214.5mm" stroke-width="0.5mm" stroke="#000000" fill="#7f7f7f" id="pageseparator_1"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

@ -437,6 +437,83 @@
</div>
</div>
[% MACRO accordion_group BLOCK%]
<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>
</div>
[% MACRO accordion_group_internal BLOCK%]
<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%]
[%content%]
</div>
[%END%]
[% USE Dumper %]
[%# Dumper.dump(zonecalls_rs)%]
[%# zonecalls_rs.size%]
[% WRAPPER accordion_group id="collapse_calls" title='Balance details' %]
[% 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.all -%]
[% 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%]
[%END%]
[% IF c.user.roles == 'admin' || c.user.roles == 'reseller' %]
<div class="accordion-group">
<div class="accordion-heading">

@ -13,6 +13,8 @@ initHelper('close_target');
initHelper('create_flag');
initHelper('form_object',form);
initHelper('ajax_uri', c.uri_for( c.controller.action_for('ajax') ));
#here we can generate couple of variants, selection of proper variant will be exact view responsibility
UNLESS c.user.read_only;
initHelper('dt_buttons',[
{ name = c.loc('Edit'), uri = "/${helper.identifier}'+full[\"id\"]+'/edit", class = 'btn-small btn-primary', icon = 'icon-edit' },
@ -21,33 +23,5 @@ UNLESS c.user.read_only;
{ name = c.loc("Create ${helper.name_single}"), uri = c.uri_for("/${helper.identifier}/create"), icon = 'icon-star' },
] );
END;
#someIndex='blahblahblah';
#initHelper('someIndex');
#Dumper.dump_html(helper);
#UNLESS helper.messages.defined; helper.messages = messages; END;
#UNLESS helper.length_change.defined; helper.length_change = 1; END;
#UNLESS helper.dt_columns.defined; helper.dt_columns = ${"${helper.identifier}_dt_columns"} || dt_columns; END;
#UNLESS helper.close_target.defined; helper.close_target = close_target; END;
#UNLESS helper.create_flag.defined; helper.create_flag = create_flag; END;
# DEFAULT
# helper.messages = messages
# helper.length_change = 1
# helper.dt_columns = ${"${helper.identifier}_dt_columns"} || dt_columns
# helper.close_target = close_target
# helper.create_flag = create_flag
# helper.edit_flag = edit_flag
# helper.form_object = form
# helper.ajax_uri = c.uri_for( c.controller.action_for('ajax') );
# UNLESS c.user.read_only;
# DEFAULT
# helper.dt_buttons = [
# { name = c.loc('Edit'), uri = "/${helper.identifier}'+full[\"id\"]+'/edit", class = 'btn-small btn-primary', icon = 'icon-edit' },
# ]
# helper.top_buttons = [
# { name = c.loc("Create ${helper.name_single}"), uri = c.uri_for("/${helper.identifier}/create"), icon = 'icon-star' },
# ]
# ;
# END;
-%]

@ -1,8 +1,8 @@
[% site_config.title = c.loc('Invoices') -%]
[% site_config.title = c.loc('InvoicePeriods') -%]
[%
helper.name = c.loc('Invoices');
helper.name_single = c.loc('Invoice');
helper.identifier = 'invoice';
helper.name = c.loc('InvoicePeriods');
helper.name_single = c.loc('InvoicePeriod');
helper.identifier = 'InvoicePeriod';
helper.top_buttons = "";
PROCESS 'helpers/datatables_vars.tt';

Loading…
Cancel
Save