MT#5879 Redesign invoice template meta handling.

Properly handle create/update/delete of template meta info.
mr3.3.1
Andreas Granig 11 years ago
parent 2d49153102
commit b6533b1a1f

File diff suppressed because it is too large Load Diff

@ -0,0 +1,259 @@
package NGCP::Panel::Controller::InvoiceTemplate;
use Sipwise::Base;
use namespace::sweep;
BEGIN { extends 'Catalyst::Controller'; }
use NGCP::Panel::Form::Invoice::TemplateAdmin;
use NGCP::Panel::Form::Invoice::TemplateReseller;
sub auto :Private {
my ($self, $c) = @_;
$c->log->debug(__PACKAGE__ . '::auto');
NGCP::Panel::Utils::Navigation::check_redirect_chain(c => $c);
return 1;
}
sub template_list :Chained('/') :PathPart('invoicetemplate') :CaptureArgs(0) :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) {
my ( $self, $c ) = @_;
$c->stash->{tmpl_rs} = $c->model('DB')->resultset('invoice_templates');
if($c->user->roles eq "admin") {
} elsif($c->user->roles eq "reseller") {
$c->stash->{tmpl_rs} = $c->stash->{tmpl_rs}->search({
'reseller_id' => $c->user->reseller_id
});
};
$c->stash->{tmpl_dt_columns} = NGCP::Panel::Utils::Datatables::set_columns($c, [
{ name => 'id', search => 1, title => $c->loc('#') },
{ name => 'reseller.name', search => 1, title => $c->loc('Reseller') },
{ name => 'name', search => 1, title => $c->loc('Name') },
{ name => 'type', search => 1, title => $c->loc('Type') },
{ name => 'is_active', search => 1, title => $c->loc('Active') },
]);
$c->stash->{template} = 'invoice/template_list.tt';
}
sub root :Chained('template_list') :PathPart('') :Args(0) {
my ($self, $c) = @_;
}
sub ajax :Chained('template_list') :PathPart('ajax') :Args(0) {
my ($self, $c) = @_;
my $rs = $c->stash->{tmpl_rs};
NGCP::Panel::Utils::Datatables::process($c, $rs, $c->stash->{tmpl_dt_columns});
$c->detach( $c->view("JSON") );
}
sub reseller_ajax :Chained('template_list') :PathPart('ajax/reseller') :Args(1) {
my ($self, $c, $reseller_id) = @_;
my $rs = $c->stash->{tmpl_rs}->search({
reseller_id => $reseller_id,
});
NGCP::Panel::Utils::Datatables::process($c, $rs, $c->stash->{tmpl_dt_columns});
$c->detach( $c->view("JSON") );
}
sub base :Chained('template_list') :PathPart('') :CaptureArgs(1) {
my ($self, $c, $tmpl_id) = @_;
unless($tmpl_id && $tmpl_id->is_integer) {
NGCP::Panel::Utils::Message->error(
c => $c,
log => 'Invalid invoice template id detected',
desc => $c->loc('Invalid invoice template id detected'),
);
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/invoicetemplate'));
}
my $res = $c->stash->{tmpl_rs}->find($tmpl_id);
unless(defined($res)) {
NGCP::Panel::Utils::Message->error(
c => $c,
log => 'Invoice template does not exist',
desc => $c->loc('Invoice template does not exist'),
);
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/invoicetemplate'));
}
$c->stash(tmpl => $res);
}
sub create :Chained('template_list') :PathPart('create') :Args() {
my ($self, $c, $reseller_id) = @_;
if(defined $reseller_id && !$reseller_id->is_integer) {
NGCP::Panel::Utils::Message->error(
c => $c,
log => 'Invalid reseller id detected',
desc => $c->loc('Invalid reseller id detected'),
);
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/reseller'));
}
my $posted = ($c->request->method eq 'POST');
my $params = {};
$params = $params->merge($c->session->{created_objects});
my $form;
if($c->user->roles eq "admin" && !$reseller_id) {
$form = NGCP::Panel::Form::Invoice::TemplateAdmin->new(ctx => $c);
} else {
$form = NGCP::Panel::Form::Invoice::TemplateReseller->new(ctx => $c);
if($c->user->roles eq "admin") {
my $reseller = $c->model('DB')->resultset('resellers')->find($reseller_id);
unless($reseller) {
NGCP::Panel::Utils::Message->error(
c => $c,
log => 'Invalid reseller id detected',
desc => $c->loc('Invalid reseller id detected'),
);
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/reseller'));
}
}
}
$form->process(
posted => $posted,
params => $c->request->params,
item => $params,
);
NGCP::Panel::Utils::Navigation::check_form_buttons(
c => $c,
form => $form,
fields => {
'reseller.create' => $c->uri_for('/reseller/create'),
},
back_uri => $c->req->uri,
);
if($posted && $form->validated) {
try {
my $schema = $c->model('DB');
$schema->txn_do(sub {
if($c->user->roles eq "admin") {
$form->params->{reseller_id} = $reseller_id ? $reseller_id : $form->params->{reseller}{id};
} elsif($c->user->roles eq "reseller") {
$form->params->{reseller_id} = $c->user->reseller_id;
}
delete $form->params->{reseller};
my $tmpl = $c->stash->{tmpl_rs}->create($form->params);
# deactivate other templates if this one got active
if($tmpl->is_active) {
$c->model('DB')->resultset('invoice_templates')->search({
reseller_id => $tmpl->reseller_id,
is_active => 1,
id => { '!=' => $tmpl->id },
})->update({ is_active => 0 });
}
delete $c->session->{created_objects}->{reseller};
});
$c->flash(messages => [{type => 'success', text => $c->loc('Invoice template successfully created')}]);
} catch($e) {
NGCP::Panel::Utils::Message->error(
c => $c,
error => $e,
desc => $c->loc('Failed to create invoice template.'),
);
}
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/invoicetemplate'));
}
$c->stash(form => $form);
$c->stash(create_flag => 1);
}
sub edit_info :Chained('base') :PathPart('editinfo') {
my ($self, $c) = @_;
my $tmpl = $c->stash->{tmpl};
my $posted = ($c->request->method eq 'POST');
my $params = { $tmpl->get_inflated_columns };
$params->{reseller}{id} = delete $params->{reseller_id};
$params = $params->merge($c->session->{created_objects});
my $form;
if($c->user->roles eq "admin") {
$form = NGCP::Panel::Form::Invoice::TemplateAdmin->new(ctx => $c);
} else {
$form = NGCP::Panel::Form::Invoice::TemplateReseller->new(ctx => $c);
}
$form->process(
posted => $posted,
params => $c->request->params,
item => $params,
);
NGCP::Panel::Utils::Navigation::check_form_buttons(
c => $c,
form => $form,
fields => {
'reseller.create' => $c->uri_for('/reseller/create'),
},
back_uri => $c->req->uri,
);
if($posted && $form->validated) {
try {
my $schema = $c->model('DB');
$schema->txn_do(sub {
if($c->user->roles eq "admin") {
$form->params->{reseller_id} = $form->params->{reseller}{id};
} elsif($c->user->roles eq "reseller") {
$form->params->{reseller_id} = $c->user->reseller_id;
}
delete $form->params->{reseller};
my $old_active = $tmpl->is_active;
$tmpl->update($form->params);
# deactivate other templates if this one got active
if($tmpl->is_active && !$old_active) {
$c->model('DB')->resultset('invoice_templates')->search({
reseller_id => $tmpl->reseller_id,
is_active => 1,
id => { '!=' => $tmpl->id },
})->update({ is_active => 0 });
}
# we don't promote another one as active, as we don't know
# for sure which one
delete $c->session->{created_objects}->{reseller};
});
$c->flash(messages => [{type => 'success', text => $c->loc('Invoice template successfully updated')}]);
} catch($e) {
NGCP::Panel::Utils::Message->error(
c => $c,
error => $e,
desc => $c->loc('Failed to update invoice template.'),
);
}
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/invoicetemplate'));
}
$c->stash(form => $form);
$c->stash(edit_flag => 1);
}
sub delete :Chained('base') :PathPart('delete') {
my ($self, $c) = @_;
try {
my $schema = $c->model('DB');
$schema->txn_do(sub{
$c->stash->{tmpl}->delete;
});
$c->flash(messages => [{type => 'success', text => $c->loc('Invoice template successfully deleted')}]);
} catch($e) {
NGCP::Panel::Utils::Message->error(
c => $c,
error => $e,
desc => $c->loc('Failed to delete invoice template.'),
);
}
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for('/invoicetemplate'));
}
__PACKAGE__->meta->make_immutable;
1;
# vim: set tabstop=4 expandtab:

@ -9,7 +9,7 @@ use NGCP::Panel::Form::NumberBlock::BlockReseller;
use NGCP::Panel::Utils::Message;
use NGCP::Panel::Utils::Navigation;
sub auto :Private{
sub auto :Private {
my ($self, $c) = @_;
$c->log->debug(__PACKAGE__ . '::auto');
NGCP::Panel::Utils::Navigation::check_redirect_chain(c => $c);

@ -154,6 +154,13 @@ sub base :Chained('list_reseller') :PathPart('') :CaptureArgs(1) {
{ name => "domain", search => 1, title => $c->loc('Domain') },
{ name => "domain_resellers.reseller.name", search => 1, title => $c->loc('Reseller') },
]);
$c->stash->{tmpl_dt_columns} = NGCP::Panel::Utils::Datatables::set_columns($c, [
{ name => 'id', search => 1, title => $c->loc('#') },
{ name => 'name', search => 1, title => $c->loc('Name') },
{ name => 'type', search => 1, title => $c->loc('Type') },
{ name => 'is_active', search => 1, title => $c->loc('Active') },
]);
$c->stash(reseller => $c->stash->{resellers}->search_rs({ id => $reseller_id }));
unless($c->stash->{reseller}->first) {
@ -314,10 +321,6 @@ sub _handle_reseller_status_change {
sub details :Chained('base') :PathPart('details') :Args(0) :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) {
my ($self, $c) = @_;
$c->stash(provider => $c->stash->{reseller}->first);
#didn't find a way to make it correct with chain
$c->forward('/invoice/template_list_data');
$c->stash(template => 'reseller/details.tt');
return;
}

@ -0,0 +1,25 @@
package NGCP::Panel::Form::Invoice::TemplateAdmin;
use HTML::FormHandler::Moose;
extends 'NGCP::Panel::Form::Invoice::TemplateReseller';
use Moose::Util::TypeConstraints;
has_field 'reseller' => (
type => '+NGCP::Panel::Field::Reseller',
label => 'Reseller',
validate_when_empty => 1,
element_attr => {
rel => ['tooltip'],
title => ['The reseller id to assign this invoice template to.']
},
);
has_block 'fields' => (
tag => 'div',
class => [qw/modal-body/],
render_list => [qw/reseller name type is_active/],
);
1;
# vim: set tabstop=4 expandtab:

@ -0,0 +1,68 @@
package NGCP::Panel::Form::Invoice::TemplateReseller;
use HTML::FormHandler::Moose;
extends 'HTML::FormHandler';
use Moose::Util::TypeConstraints;
use HTML::FormHandler::Widget::Block::Bootstrap;
has '+widget_wrapper' => ( default => 'Bootstrap' );
has_field 'submitid' => ( type => 'Hidden' );
sub build_render_list {[qw/submitid fields actions/]}
sub build_form_element_class {[qw(form-horizontal)]}
has_field 'name' => (
type => 'Text',
label => 'Name',
required => 1,
element_attr => {
rel => ['tooltip'],
title => ['The name of the invoice template.'],
},
);
has_field 'type' => (
type => 'Select',
label => 'Type',
required => 1,
options => [
{ label => 'SVG', value => 'svg' },
],
element_attr => {
rel => ['tooltip'],
title => ['The invoice template type (only svg for now).'],
},
);
has_field 'is_active' => (
type => 'Boolean',
label => 'Active',
required => 0,
element_attr => {
rel => ['tooltip'],
title => ['Whether this template is used to generate invoices for this reseller.'],
},
);
has_field 'save' => (
type => 'Submit',
value => 'Save',
element_class => [qw/btn btn-primary/],
label => '',
);
has_block 'fields' => (
tag => 'div',
class => [qw/modal-body/],
render_list => [qw/name type is_active/],
);
has_block 'actions' => (
tag => 'div',
class => [qw/modal-footer/],
render_list => [qw/save/],
);
1;
# vim: set tabstop=4 expandtab:

@ -38,20 +38,20 @@ template_variables.description.import({
});
IF 1 || !provider;
DEFAULT provider.bic='ABCDEFG1234';
DEFAULT provider.city='Provider City';
DEFAULT provider.company='Provider Gmbh.';
DEFAULT provider.country='Provider-Country';
DEFAULT provider.email='office@provider.com';
DEFAULT provider.fax='+1 650 1234566';
DEFAULT provider.fn='305595';
DEFAULT provider.company='Providercompany Inc';
DEFAULT provider.street='Providerstreet 99';
DEFAULT provider.city='Providercity';
DEFAULT provider.postcode='12345';
DEFAULT provider.country='Providercountry';
DEFAULT provider.comregnum='12345';
DEFAULT provider.iban='1234567890ABC';
DEFAULT provider.mobile='+1 650 1234568';
DEFAULT provider.phone='+1 650 1234567';
DEFAULT provider.postcode='65104';
DEFAULT provider.street='Provider Street';
DEFAULT provider.bic='ABCDEFG1234';
DEFAULT provider.vat='XY1234567';
DEFAULT provider.email='provider@example.org';
DEFAULT provider.phone='+1 234 567890';
DEFAULT provider.mobile='+1 234 567890';
DEFAULT provider.faxnumber='+1 234 567890';
DEFAULT provider.url='http://www.provider.com/';
DEFAULT provider.vat='UATAA1234AA1234';
ELSE;
FOREACH i in ['bic','city','company','country','email','fax','fn','iban','mobile','phone','postcode','street','url','vat'];
TRY;
@ -73,16 +73,15 @@ template_variables.description.import({
});
IF !client.id;
DEFAULT client.bic='ABCDEFG1234';
DEFAULT client.city='Client City';
DEFAULT client.country='Client-Country';
DEFAULT client.title='Herr Dipl. Ing (FH)';
DEFAULT client.firstname='Client Firstname';
DEFAULT client.firstname='Firstname';
DEFAULT client.lastname='Lastname';
DEFAULT client.street='Clientstreet 12/3/45';
DEFAULT client.city='Clientcity';
DEFAULT client.postcode='98765';
DEFAULT client.country='Clientcountry';
DEFAULT client.id=Math.int(Math.rand(999999))|format('%06d');
DEFAULT client.lastname='Client-Lastname Sr.';
DEFAULT client.postcode='65104';
DEFAULT client.sepa='AT1234567890';
DEFAULT client.street='Client Street';
DEFAULT client.iban='AT1234567890';
DEFAULT client.bic='ABCDEFG1234';
DEFAULT client.vatid='AA1234';
END;
@ -90,7 +89,7 @@ END;
template_variables.description.import({
bp => {
'name' => 'Billing Profile name',
'interval_charge' => 'Constant fee for invoice period.',
'interval_charge' => 'Recurring fee for invoice period',
}
});
@ -110,9 +109,9 @@ DEFAULT bp.fraud_interval_notify = '';
DEFAULT bp.fraud_daily_limit = '';
DEFAULT bp.fraud_daily_lock = '';
DEFAULT bp.fraud_daily_notify = '';
DEFAULT bp.currency = '';
DEFAULT bp.vat_rate = '';
DEFAULT bp.vat_included = '';
DEFAULT bp.currency = 'USD';
DEFAULT bp.vat_rate = '20';
DEFAULT bp.vat_included = 0;
END;
invoice_details_zones = [];
@ -159,4 +158,4 @@ IF !invoice_details_zones.size();
i = i + 1;
END;
END;
%]
%]

@ -34,13 +34,17 @@
<g y="0" x="0" width="841" height="595" id="titlepage_1" display="none">
<title>TitlePage_1</title>
<text x="65" y="155" class="ps00 ps20">[%provider.company%][%if(', ', provider.postcode _ ' ' _ provider.city ) %][%if(', ', provider.street )%]</text>
<text x="65" y="165" class="ps00 ps23">[%client.title%]</text>
<text x="65" y="155" class="ps00 ps20">[%provider.company%], [%provider.street%], [%provider.postcode%] [% provider.city%], [%provider.country%]</text>
[% IF client.company -%]
<text x="65" y="177" class="ps00 ps23">[%client.company%]</text>
[% ELSE -%]
<text x="65" y="177" class="ps00 ps23">[%client.firstname%] [%client.lastname%]</text>
[% END -%]
<text x="65" y="189" class="ps00 ps23">[%client.street%]</text>
<text x="65" y="201" class="ps00 ps23">[%client.postcode%] [%client.city%]</text>
<text x="65" y="213" class="ps00 ps23">[%client.country%]</text>
<text x="65" y="249" class="ps00 ps23">Anschlussinhaber: [%client.firstname%] [%client.lastname%]</text>
<text x="65" y="249" class="ps00 ps23">Contract Owner: [% client.company ? client.company : client.firstname _ ' ' _ client.lastname%]</text>
<text x="400" y="155" class="ps00 ps21">Rechnung</text>
<text x="400" y="170" class="ps00 ps22">Rechnungsnummer</text>

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

@ -1,63 +1,28 @@
[% 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%]
<script>
var staticContainerId='template_list';
</script>
[%IF template_list.size %]
<table class="table table-bordered table-striped table-highlight table-hover">
<thead>
<tr>
<th>[% c.loc('Active') %]</th>
<th>[% c.loc('Id') %]</th>
<th>[% c.loc('Name') %]</th>
<th>[% c.loc('Type') %]</th>
<th class="ngcp-actions-column"></th>
</tr>
</thead>
<tbody>
[% FOR template IN template_list -%]
[%# Dumper.dump_html(template_list.as_query)%]
[%# Dumper.dump_html(template)%]
<tr class="sw_action_row" data-id="[%template.get_column('id')%]">
<td style="font-size: 20px;">[%IF template.get_column('is_active') > 0; '✓'; END%]</td><!--✓-->
<td>[% template.get_column('id') %]</td>
<td>[% template.get_column('name') %]</td>
<td>[% template.get_column('type') %]</td>
<td class="ngcp-actions-column">
<div class="sw_actions">
[% IF write_access -%]
<a class="btn btn-small btn-primary"
onclick="fetch_into('template_info_form', '[%- c.uri_for_action("/invoice/template_info", [provider.id]) -%]','item=template_info&tt_id=[%template.get_column('id')%]',function(){modalFormScript();});void(0);
">
<i class="icon-edit"></i> [% c.loc('Edit template info') %]
</a>
<a class="btn btn-small btn-primary"
onclick="fetchInvoiceTemplateData({
tt_sourcestate: 'saved',
provider_id: '[%provider.id%]',
tt_id: '[%template.get_column('id')%]',
});listSetCurrentEdit('[%template.get_column('id')%]', $(this).closest('tr') );">
<i class="icon-edit"></i> [% c.loc('Edit template') %]
</a>
<a class="btn btn-small btn-primary ngcp-noback-button" data-confirm="[%IF template.get_column('is_active'); c.loc('Deactivate'); ELSE; c.loc('Activate'); END%]"
href="javascript:fetch_into(staticContainerId, '[%- c.uri_for_action("/invoice/template_activate", [provider.id, template.get_column('id'),template.get_column('is_active')]) -%]','',function(){ refreshMessagesAjax();mainWrapperInit(); listRestoreCurrentEdit('',staticContainerId);});void(0);" cancel-hide="1">
<i class="icon-edit"></i> [%IF template.get_column('is_active'); c.loc('Deactivate'); ELSE; c.loc('Activate'); END%]
</a>
<a class="btn btn-small btn-secondary ngcp-noback-button" data-confirm="Delete"
href="javascript:fetch_into(staticContainerId, '[%- c.uri_for_action("/invoice/template_delete", [provider.id, template.get_column('id')]) -%]','',function(){ refreshMessagesAjax();mainWrapperInit();listRestoreCurrentEdit('',staticContainerId);if('[%template.get_column('id')%]' === getCurrentEditId('', staticContainerId)){clearTemplateForm({provider_id: '[%provider.id%]'});} });void(0);" cancel-hide="1">
<i class="icon-trash"></i> [% c.loc('Delete') %]
</a>
[%END%]
</div>
</td>
</tr>
[%END%]
</tbody>
</table>
[%END%]
[% site_config.title = c.loc('Invoice Templates') -%]
[%
helper.name = c.loc('Invoice Template');
helper.identifier = "InvoiceTemplate";
helper.messages = messages;
helper.dt_columns = tmpl_dt_columns;
helper.paginate = 'true';
helper.filter = 'true';
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_action('/invoicetemplate/ajax');
UNLESS c.user.read_only;
helper.dt_buttons = [
{ name = c.loc('Edit Meta'), uri = "/invoicetemplate/'+full.id+'/editinfo", class = 'btn-small btn-primary', icon = 'icon-edit' },
{ name = c.loc('Edit Content'), uri = "/invoicetemplate/'+full.id+'/editcontent", class = 'btn-small btn-tertiary', icon = 'icon-edit' },
{ name = c.loc('Delete'), uri = "/invoicetemplate/'+full.id+'/delete", class = 'btn-small btn-secondary', icon = 'icon-remove' },
];
helper.top_buttons = [
{ name = c.loc('Create Invoice Template'), uri = c.uri_for_action('/invoicetemplate/create'), class = 'btn-small btn-primary', icon = 'icon-star' },
];
END;
PROCESS 'helpers/datatables.tt';
-%]
[% # vim: set tabstop=4 syntax=html expandtab: -%]

@ -4,9 +4,6 @@
<span>
<a class="btn btn-primary btn-large" href="[% c.uri_for('/back') %]"><i class="icon-arrow-left"></i> [% c.loc('Back') %]</a>
</span>
<span>
<a class="btn btn-primary btn-large" href="[% c.uri_for_action('/invoice/invoice_list', [reseller.first.id]) %]">[% c.loc('Invoices')%] <i class="icon-edit"></i></a>
</span>
</div>
[% back_created = 1 -%]
@ -269,40 +266,48 @@
</div>
</div>
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#reseller_details" href="#collapse_intemplate">[% c.loc('Invoice Templates') %]</a>
</div>
<div class="accordion-body collapse" id="collapse_intemplate">
<div class="accordion-inner">
[%
helper.name = c.loc('Invoice Template');
helper.identifier = "InvoiceTemplate";
helper.messages = messages;
helper.dt_columns = tmpl_dt_columns;
helper.paginate = 'true';
helper.filter = 'true';
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_action('/invoicetemplate/reseller_ajax', [c.req.captures.0] );
[% IF branding_edit_flag != 1 -%]
UNLESS c.user.read_only;
helper.dt_buttons = [
{ name = c.loc('Edit Meta'), uri = "/invoicetemplate/'+full.id+'/editinfo", class = 'btn-small btn-primary', icon = 'icon-edit' },
{ name = c.loc('Edit Content'), uri = "/invoicetemplate/'+full.id+'/editcontent", class = 'btn-small btn-tertiary', icon = 'icon-edit' },
{ name = c.loc('Delete'), uri = "/invoicetemplate/'+full.id+'/delete", class = 'btn-small btn-secondary', icon = 'icon-remove' },
];
helper.top_buttons = [
{ name = c.loc('Create Invoice Template'), uri = c.uri_for('/invoicetemplate/create', c.req.captures.0), class = 'btn-small btn-primary', icon = 'icon-star' },
];
END;
[%PROCESS 'helpers/modal.tt' -%]
[%mf_helper = {
ajax_load => 1,
ajax_list_refresh => 'template',
}%]
[%modal_script( m = mf_helper )%]
[%END%]
<script type="text/javascript" src="/js/background.js"></script>
<script type="text/javascript" src="/js/modalAjax.js"></script>
<script type="text/javascript" src="/js/jquery.serializeObject.js"></script>
[%PROCESS "invoice/uri_wrapper_js.tt"%]
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#invoice_template" href="#collapse_template_list">[% c.loc('Invoice Templates') %]</a>
</div>
<div class="accordion-body collapse" id="collapse_template_list">
<div class="ngcp-separator"></div>
<a class="btn btn-primary btn-large" onclick="$(this).css('outline', 'none');fetch_into('template_info_form', '[%- c.uri_for_action("/invoice/template_info", [provider.id]) -%]','item=template_info',function(){modalFormScript();});void(0);">[% c.loc('Create invoices template')%] <i class="icon-edit"></i></a>
<div class="ngcp-separator"></div>
<div class="accordion-inner" style="overflow:auto; height:300px;" id="template_list">
[%PROCESS 'invoice/template_list_alt.tt' %]
</div>
</div>
</div>
PROCESS 'helpers/datatables.tt';
-%]
</div>
<div id="template_info_form">
</div>
</div>
</div>
</div>
[% IF edit_flag || create_flag -%]
[%PROCESS 'helpers/modal.tt' -%]
[% END -%]
[% IF branding_edit_flag == 1 -%]
[%
IF form.has_for_js;

Loading…
Cancel
Save