MT#5879 Intermediate state.

Template changes not saved. Separated info form is working, axcept applying renamed fields as form values.
ipeshinskaya/InvoiceTemplate5
Irina Peshinskaya 12 years ago committed by Victor Seva
parent 3c85a2e269
commit 59b1d7fad6

@ -4,14 +4,19 @@ use HTML::FormHandler::Moose;
extends 'NGCP::Panel::Form::ValidatorBase';
use Moose::Util::TypeConstraints;
use HTML::FormHandler::Widget::Block::Bootstrap;
enum 'TemplateType' => [ qw/svg html/ ];#html
enum 'TemplateTypeOutput' => [ qw/svg html pdf json svgzip htmlzip pdfzip/ ];#html
enum 'TemplateViewMode' => [ qw/raw parsed both/ ];
enum 'TemplateSourceState' => [ qw/saved previewed default/ ];
#no Moose::Util::TypeConstraints;
has '+widget_wrapper' => ( default => 'Bootstrap' );
has '+use_fields_for_input_without_param' => ( default => 1 );
sub build_render_list {[qw/fields actions/]}
sub build_form_element_class { [qw/form-horizontal/] }
has_field 'submitid' => ( type => 'Hidden' );
has_field 'tt_type' => (
type => 'Text',
required => 1,
@ -54,7 +59,7 @@ has_field 'tt_string' => (
);
has_field 'contract_id' => (
type => 'Text',
type => 'Hidden',
#default => \&
#apply => [ { check => \&validate_tt_string } ],
required => 1,
@ -68,9 +73,9 @@ has_field 'tt_id' => (
);
has_field 'name' => (
type => 'Text',
default => '',
#default => '',
#apply => [ { check => \&validate_tt_string } ],
required => 0,
required => 1,
);
has_field 'is_active' => (
type => 'Checkbox',
@ -79,6 +84,25 @@ has_field 'is_active' => (
required => 0,
);
has_field 'save' => (
type => 'Button',
value => 'Save',
element_class => [qw/btn btn-primary/],
label => '',
);
has_block 'fields' => (
tag => 'div',
class => [qw/modal-body/],
render_list => [qw/name tt_id is_active submitid contract_id/],
);
has_block 'actions' => (
tag => 'div',
class => [qw/modal-footer/],
render_list => [qw/save/],
);
1;
=head1 NAME

@ -27,19 +27,28 @@ sub getCustomerInvoiceTemplate{
my (%params) = @_;
my ($contract_id,$tt_sourcestate,$tt_type,$tt_id) = @params{qw/contract_id tt_sourcestate tt_type tt_id/};
irka::loglong("getCustomerInvoiceTemplate: tt_id=$tt_id;\n");
#irka::loglong("getCustomerInvoiceTemplate: tt_id=$tt_id;\n");
#irka::loglong(Dumper(\%params));
my $result = '';
my $conditions = $self->getDefaultConditions(\%params);
#my $tt_record = $self->resultset('invoice_templates')->search({
my $tt_record = $self->schema->resultset('invoice_templates')->search($conditions)->first;
my $tt_record = $self->schema->resultset('invoice_templates')->search(
{ id => $tt_id }, {
#'+select' => [{'reseller_id' =>'contract_id','-as'=>'contract_id'},{'id' => 'tt_id','-as'=>'tt_id'}]
'+select' => [
[ 'reseller_id', {'-as'=>'contract_id'}],
[ 'id', {'-as'=>'tt_id'}],
],
#'+select' => [qw/reseller_id id/],
#'+as' => [qw/contract_id tt_id/]
})->first;
#here may be base64 decoding
#here we will rely on form checking and defaults
#if('saved' eq $tt_sourcestate){
if( $tt_record ){
$result = $tt_record->get_column( 'base64_'.$tt_sourcestate );
$tt_sourcestate and $result = $tt_record->get_column( 'base64_'.$tt_sourcestate );
$tt_id = $tt_record->get_column( 'id' );
}
if( $result && exists $params{result} ){
@ -101,6 +110,37 @@ sub storeCustomerInvoiceTemplate{
});
return { tt_id => $tt_id };
}
sub storeInvoiceTemplateInfo{
my $self = shift;
my (%params) = @_;
my ($contract_id,$tt_id,$is_active,$name) = @params{qw/contract_id tt_id is_active name/};
#my $tt_record = $self->resultset('invoice_templates')->search({
$self->schema->txn_do(sub {
my $tt_record_created;
my $tt_record_updated;
if( !$tt_id ){
$tt_record_created = $self->schema->resultset('invoice_templates')->create({
reseller_id => $contract_id,
is_active => $is_active,
name => $name,
});
if($tt_record_created){
$tt_id = $tt_record_created->id();
}
}else{
$tt_record_updated = $self->schema->resultset('invoice_templates')->search({ id => $tt_id });
$tt_record_updated->update({
is_active => $is_active,
name => $name,
});
}
if($is_active && $tt_id){
$self->deactivateOtherTemplates($contract_id,$tt_id);
}
});
return { tt_id => $tt_id };
}
sub getCustomerInvoiceTemplateList{
my $self = shift;
my (%params) = @_;
@ -110,9 +150,6 @@ sub getCustomerInvoiceTemplateList{
#$self->schema->resultset('invoice_template_fake')->find(\'select * from invoice_templates')->all
#$self->schema->resultset('invoice_templates')->name(\'(select * from invoice_templates)')->all
#];
use irka;
use Data::Dumper;
irka::loglong(Dumper(\%INC));
return [ $self->schema->resultset('invoice_templates')->search({
reseller_id => $contract_id,
})->all ];

@ -14,8 +14,13 @@ __PACKAGE__->config(
WRAPPER => '',
FILTERS => {},
ABSOLUTE => 0,
expose_methods => [],
expose_methods => [qw/translate_form/],
);
#copy-paste from html, method is too small to move it to separate class
sub translate_form {
my $self = shift;
NGCP::Panel::Utils::I18N->translate_form(@_);
}
sub process
{

@ -10,8 +10,8 @@ function init_embed() {
{
doc = frame.contentWindow.document;
}
//var mainButton = doc.getElementById('main_button');
//mainButton.style.display = 'none';
var mainButton = doc.getElementById('main_button');
mainButton.style.display = 'none';
}
//private
function getSvgString(){
@ -54,10 +54,11 @@ function fetchSvgToEditor( data ) {
setSvgStringToEditor( httpResponse );
});
}
function refreshTemplateList ( contract_id ){
function refreshAccordionAjaxList ( item, data ){
alert('refreshAccordionAjaxList: q='+uriForAction( data, item + '_list' )+';item='+item);
fetch_into(
'collapse_invoice_template_list',
uriForAction( {'contract_id': contract_id}, 'invoice_template_list' ),
'collapse_' +item + '_list',
uriForAction( data, item + '_list' ),
'',
function(){ mainWrapperInit(); }
);
@ -100,7 +101,7 @@ function savePreviewedAndShowParsed( data ){
//alert('savePreviewedAndShowParsed: httpResponse='+httpResponse+';');
setSvgStringToPreview( httpResponse, q )
//refresh list after saving
refreshTemplateList( data.contract_id );
refreshAccordionAjaxList( 'invoice_template', data );
} );
}
function saveTemplate( data ) {
@ -119,6 +120,56 @@ function saveTemplate( data ) {
if(jsonResponse.aaData && jsonResponse.aaData.form){
$('form[name=invoice_template]').loadJSON(jsonResponse.aaData.form);
}
refreshTemplateList( data.contract_id );
refreshAccordionAjaxList( 'invoice_template', data );
});
}
function processModalFormAjax( form, callback ) {
//preventDefault();
alert(form.attr('action')+'?'+form.serialize());
var item = form.attr('id');
$.ajax( {
url: form.attr('action'),
type: "POST",
data: form.serialize(),
} ).done( function( responseText, textStatus, request ) {
/*
var headers = request.getAllResponseHeaders();
var i =0;
alert('headers='+headers);
for(i=0; i<headers.length; i++){
alert('i='+i+';header='+headers[i]);
}
*/
var status = request.getResponseHeader('X-Form-Status');
//alert('header='+request.getResponseHeader('X-Form-Status'));
var targetNames = [ item + '_messages','messages' ];
if('error' == status){
targetNames.unshift(item+'_form_modal');
}
/*
if(var targetDirect = request.getResponseHeader('X-Ajax-Target')){
targetNames.unshift(targetDirect);
}
*/
var target,i=0;
while( (!target) && ( i < targetNames.length ) ){
target = document.getElementById(targetNames[i++]);
//alert('i='+(i-1)+';name='+targetNames[i-1]+';target='+target);
}
//alert('target='+target);
if(target){
target.innerHTML=responseText;
}
if('error' != status){
refreshAccordionAjaxList( item, form.serializeObject() );
}
if(callback){
if(typeof callback == 'function'){
callback(status);
}else{
eval(callback);
}
}
});
}

@ -0,0 +1,20 @@
/*
http://stackoverflow.com/questions/1184624/convert-form-data-to-js-object-with-jquery
*/
(function ($) {
$.fn.serializeObject = function()
{
var o = {};
$.each(this.serializeArray(), function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};})(jQuery);

@ -0,0 +1,7 @@
[%PROCESS 'helpers/modal.tt'-%]
[%#USE Dumper%]
[%form=translate_form(form)%]
[%modal_header()%]
[%#Dumper.dump_html(form)%]
[%form.render()%]
[%modal_footer()%]

@ -0,0 +1,4 @@
[% FOREACH m IN messages -%]
<div class="alert alert-[% m.type %]">[% m.text %]</div>
[% END -%]
[% messages = [] -%]

@ -28,20 +28,40 @@
[% MACRO modal_script BLOCK %]
<script>
$(function () {
var modalFormScript = function (repeat) {
$('#mod_edit').modal({keyboard: false, backdrop: 'static'});
$('.mod_close').click(function(event) {
[%IF m.close_target_direct%]
[%m.close_target_direct%]
[%ELSIF m.ajax_load%]
$('#mod_edit').modal('hide');
[%ELSE%]
console.log("redirecting to [% m.close_target ? m.close_target : c.uri_for() %]");
window.location.href="[% m.close_target ? m.close_target : c.uri_for() %]";
[%END%]
});
// on clicking a button within the form, add a hidden field "submitid"
// determining the name of the button being clicked
$('input[type=button]').click(function() {
$(this).parents('form').find('#submitid').attr('value', $(this).attr('name'));
[%IF !m.ajax_load%]
$(this).parents('form').submit();
[%ELSE%]
$('#mod_edit').modal('hide');
processModalFormAjax($(this).parents('form'),function(status){
//alert('in callback: status='+status);
if( status == 'error' ){
modalFormScript();
}
[%m.ajax_callback%]
});
[%END%]
});
});
};
[%IF !m.ajax_load%]$(modalFormScript);[%ELSE%]
//$('#'+$(this).parents('form').id()+' :input:enabled:visible:first').focus();
[%END%]
</script>
[% END -%]

@ -1,24 +1,24 @@
[% 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
-%]
[%PROCESS 'helpers/modal.tt' -%]
[%mf_helper = {
ajax_load => 1,
}%]
[%modal_script( m = mf_helper )%]
[% IF c.user.roles == "subscriber" || c.user.roles == "subscriberadmin" -%]
[% site_config.title = c.loc('Invoice template manager') -%]
[% ELSE -%]
[% site_config.title = c.loc('Customer Invoice template for #[_1] ([_2])',contract.id, product.name) -%]
[% END -%]
[% site_config.title = c.loc('Invoice template for [_1]', reseller.first.name) -%]
<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" src="/js/jquery.loadJSON.js"></script>
<script type="text/javascript" src="/js/jquery.serializeObject.js"></script>
<script type="text/javascript">
var uriForAction = function( data, type ){
//also we can think about getting URIs via ajax )
@ -54,7 +54,6 @@ var uriForAction = function( data, type ){
//alert('q_template='+q_template);
return q_template;
}
</script>
<script type="text/javascript" src="/js/invoice_template.js"></script>
@ -62,7 +61,20 @@ var uriForAction = function( data, type ){
<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('/reseller/invoice_create') %]">[% c.loc('Create invoices template')%] <i class="icon-edit"></i></a-->
<a class="btn btn-primary btn-large" onclick="$(this).css('outline', 'none');fetch_into('invoice_template_form_modal', '[%- c.uri_for_action("/reseller/invoice_template_form", [contract.id]) -%]','item=invoice_template',function(){modalFormScript();});void(0);">[% c.loc('Create invoices template')%] <i class="icon-edit"></i></a>
</span>
</div>
[% IF reseller.first.status != "active" -%]
[%messages.unshift( c.loc('Reseller is <b>[_1]</b>', reseller.first.status) ); %]
[% END -%]
<div class="row" id="messages">
[%PROCESS 'helpers/ajax_messages.tt' -%]
</div>
<div class="ngcp-separator"></div>
[% back_created = 1 -%]
@ -111,8 +123,13 @@ var uriForAction = function( data, type ){
</div>
</span>
<div style="visibility:visible;" id="invoice_template_form">
[%PROCESS 'invoice/invoice_template_form.tt' %]
</div>
</div>
</div>
<div id="invoice_template_form_modal">
</div>

@ -3,23 +3,28 @@
[%# USE FillInForm %]
<script>
function getTtIdVal(){
return $('form[name=invoice_template] input[name=tt_id]').val();
return $('form[id=invoice_template] input[name=tt_id]').val();
}
function formToUri(q){
return q+'?'+$('form[name=invoice_template]').serialize()
return q+'?'+$('form[id=invoice_template]').serialize();
}
function formSerialize(){
return $('form[id=invoice_template]').serialize();
}
function getForm(){
return $('form[id=invoice_template]');
}
</script>
<form name="invoice_template" id="invoice_template" action="[%- c.uri_for_action('/reseller/invoice_template', [contract.id]) -%]" class="form-horizontal" enctype="multipart/form-data" method="post">
<form name="invoice_template_old" id="invoice_template_old" action="[%- c.uri_for_action('/reseller/invoice_template', [contract.id]) -%]" class="form-horizontal" enctype="multipart/form-data" method="post">
<input type="hidden" name="tt_id" value="">
<div class="ngcp-separator"></div>
[% IF write_access -%]
<span>
<!--span>
<a class="btn btn-primary btn-large" onclick="fetchInvoiceTemplateData({
tt_sourcestate: 'default',
contract_id: '[%contract.id%]',
});void(0);">[% c.loc('Create from scratch')%] <i class="icon-edit"></i></a>
</span>
</span-->
<div class="ngcp-separator"></div>
[% END -%]
<div class="control-group">

@ -0,0 +1,2 @@
[%m.name = "Invoice Template"%]
[%PROCESS 'helpers/ajax_form_modal.tt'-%]

@ -11,8 +11,8 @@
<thead>
<tr>
<th>[% c.loc('Active') %]</th>
<th>[% c.loc('Type') %]</th>
<th>[% c.loc('Name') %]</th>
<th>[% c.loc('Type') %]</th>
<th class="ngcp-actions-column"></th>
</tr>
</thead>
@ -21,53 +21,34 @@
[%# Dumper.dump_html(invoice_template_list.as_query)%]
[%# Dumper.dump_html(template)%]
<tr class="sw_action_row">
<td><input type="radio" name="is_active" value="[%template.get_column('is_active')%]" [%IF template.get_column('is_active') %] checked [%END%] onclick="javascript:fetch_into('collapse_invoice_template_list', '[%- c.uri_for_action("/reseller/invoice_template_activate", [contract.id, template.get_column('id'),template.get_column('is_active')]) -%]','',function(){ mainWrapperInit(); });void(0);"></td>
<td>[% template.get_column('type') %]</td>
<td style="font-size: 20px;">[%IF template.get_column('is_active') > 0; '✓'; END%]</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 -%]
[%IF template.get_column('base64_previewed')%]
<a class="btn btn-primary btn-small"
onclick="fetchInvoiceTemplateData({
tt_sourcestate: 'previewed',
contract_id: '[%contract.id%]',
tt_id: '[%template.get_column('id')%]',
});">
<i class="icon-edit"></i> [% c.loc('Edit previewed') %]
<a class="btn btn-small btn-primary"
onclick="alert('[%- c.uri_for_action("/reseller/invoice_template_form", [contract.id])%]');fetch_into('invoice_template_form_modal', '[%- c.uri_for_action("/reseller/invoice_template_form", [contract.id]) -%]','item=invoice_template&tt_id=[%template.get_column('id')%]',function(){modalFormScript();});void(0);
">
<i class="icon-edit"></i> [% c.loc('Edit template info') %]
</a>
[%END%]
[%IF template.get_column('base64_saved')%]
<a class="btn btn-small btn-primary"
onclick="fetchInvoiceTemplateData({
tt_sourcestate: 'saved',
contract_id: '[%contract.id%]',
tt_id: '[%template.get_column('id')%]',
});">
<i class="icon-edit"></i> [% c.loc('Edit saved') %]
<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('collapse_invoice_template_list', '[%- c.uri_for_action("/reseller/invoice_template_activate", [contract.id, template.get_column('id'),template.get_column('is_active')]) -%]','',function(){ mainWrapperInit(); });void(0);">
<i class="icon-edit"></i> [%IF template.get_column('is_active'); c.loc('Deactivate'); ELSE; c.loc('Activate'); END%]
</a>
[%END%]
[%IF !template.is_active%]
<!--a class="btn btn-small btn-primary"
onclick="switchDefault();void(0);">
<i class="icon-edit"></i> [% c.loc('Make active') %]
</a-->
[%END%]
<a class="btn btn-small btn-secondary ngcp-noback-button" data-confirm="Delete"
href="javascript:fetch_into('collapse_invoice_template_list', '[%- c.uri_for_action("/reseller/invoice_template_delete", [contract.id, template.get_column('id')]) -%]','',function(){ mainWrapperInit(); });void(0);">
<i class="icon-trash"></i> [% c.loc('Delete') %]
</a>
[%END%]
<!--a class="btn btn-small btn-primary"
onclick="loadSvg('/svg/raw/saved/zip');void(0);">
<i class="icon-download"></i>[% c.loc('Download source') %]
</a>
<a class="btn btn-small btn-primary"
onclick="loadSvg('/svg/parsed/saved/pdf');void(0);">
<i class="icon-download"></i> [% c.loc('Download invoice') %]
</a-->
</div>
</td>
</tr>

@ -230,7 +230,7 @@
</span>
<div class="ngcp-separator"></div>
[%PROCESS 'invoice/invoice_template_list.tt' %]
[%PROCESS 'invoice/invoice_details_list.tt' %]
</div>
</div>

Loading…
Cancel
Save