summaryrefslogtreecommitdiff
path: root/httemplate/edit/part_event.html
diff options
context:
space:
mode:
Diffstat (limited to 'httemplate/edit/part_event.html')
-rw-r--r--httemplate/edit/part_event.html679
1 files changed, 679 insertions, 0 deletions
diff --git a/httemplate/edit/part_event.html b/httemplate/edit/part_event.html
new file mode 100644
index 0000000..6a53222
--- /dev/null
+++ b/httemplate/edit/part_event.html
@@ -0,0 +1,679 @@
+<% include( 'elements/edit.html',
+ 'name' => 'Billing event definition',
+ 'table' => 'part_event',
+ 'fields' => [
+ 'event',
+ { field => 'eventtable',
+ type => 'select',
+ options => [ FS::part_event->eventtables ],
+ labels => $eventtable_labels,
+ onchange => 'eventtable_changed',
+ },
+ { field => 'agentnum',
+ type => 'select-agent',
+ disable_empty => $disable_empty_agent,
+ },
+ { field => 'check_freq',
+ type => 'select',
+ options => [ '1d', '1m' ],
+ labels => $check_freq_labels,
+ },
+ { field => 'disabled',
+ type => 'checkbox',
+ value => 'Y',
+ },
+ { type => 'title',
+ value => 'Event Conditions',
+ },
+ { field => 'conditionname',
+ type => 'selectlayers',
+ options => [ keys %all_conditions ],
+ labels => \%condition_labels,
+ onchange => 'condition_changed(what);',
+ layer_fields => \%condition_fields,
+ layer_values_callback => $condition_layer_values,
+ html_between => n_a('action'),
+ m2name_table => 'part_event_condition',
+ m2name_namecol => 'conditionname',
+ m2_label => 'Condition',
+ m2_new_default => \@implicit_condition_objs,
+ m2_error_callback => $condition_error_callback,
+ m2_remove_warnings => \%condition_remove_warnings,
+ m2_new_js => 'condition_repop',
+ m2_remove_js => 'condition_add',
+ },
+ { type => 'title',
+ value => 'Event Action',
+ },
+ { field => 'action',
+ type => 'selectlayers',
+ options => [ keys %all_actions ],
+ labels => \%action_labels,
+ onchange => 'action_changed(what);',
+ layer_fields => \%action_fields,
+ layer_values_callback => $action_layer_values,
+ html_between => n_a('action'),
+ },
+
+ ],
+ 'labels' => {
+ 'eventpart' => 'Event',
+ 'event' => 'Event name',
+ 'eventtable' => 'Type',
+ 'agentnum' => 'Agent',
+ 'check_freq' => 'Check frequency',
+ 'disabled' => 'Disable event',
+
+ 'conditionname' => 'Add&nbsp;new&nbsp;condition',
+ #'weight',
+ 'action' => 'Action',
+ },
+ 'viewall_dir' => 'browse',
+ 'new_callback' => sub { #start empty for new events only
+ my( $cgi, $object, $fields_listref ) = @_;
+ unshift @{ $fields_listref->[1]{'options'} }, '';
+ },
+ 'error_callback' => $error_callback,
+
+ 'agent_virt' => 1,
+ 'agent_null_right' => 'Edit global billing events',
+ )
+%>
+<SCRIPT TYPE="text/javascript">
+
+ window.onload = function () { eventtable_changed(document.getElementById('eventtable')) };
+ var notonload = 0;
+
+ function eventtable_changed(what) {
+
+% if ( $JS_DEBUG ) {
+ alert('eventtable_changed called on ' + what );
+% }
+
+ var eventtable = what.options[what.selectedIndex].value;
+% if ( $JS_DEBUG ) {
+ alert ("eventtable: " + eventtable);
+% }
+ var eventdesc = what.options[what.selectedIndex].text;
+
+ //remove the ** Select type **
+ if ( what.options[0].value == '' && notonload++ > 0 ) {
+ what.options[0] = null;
+ }
+
+ ////
+ // XXX gray out conditions that can't apply (in addition to the warning)?
+ ////
+
+ ////
+ // update condition selects
+ ////
+
+ for ( var cnum=0; document.getElementById('conditionname'+cnum); cnum++ ) {
+ var cond_id = 'conditionname' + cnum;
+ var cond_select = document.getElementById(cond_id);
+
+% if ( $JS_DEBUG ) {
+ alert('updating ' + cond_id);
+% }
+
+ // save off the current value
+ var conditionname = cond_select.options[cond_select.selectedIndex].value;
+ var cond_desc = cond_select.options[cond_select.selectedIndex].text;
+
+ var seen_condition = condition_repop(cond_select);
+
+ var warning = document.getElementById(cond_id + '_warning');
+% if ( $JS_DEBUG ) {
+ alert('turning off warning; setting style.display of '+ cond_id +
+ '_warning (' + warning + ') to none');
+% }
+ warning.style.display = 'none';
+
+ if ( ! seen_condition && conditionname != '' ) {
+ // add the current (not valid) condition back
+ opt(cond_select, conditionname, cond_desc, true );
+ if ( ! condition_is_implicit(conditionname) ) {
+ cond_select.parentNode.parentNode.style.display = '';
+ cond_select.disabled = '';
+ // turn on a warning and gray out the condition row
+% if ( $JS_DEBUG ) {
+ alert('turning on warning; setting style.display of '+ cond_id +
+ '_warning (' + warning + ') to ""');
+% }
+ warning.innerHTML = 'Not applicable to ' + eventdesc + ' events';
+ warning.style.display = '';
+ } else {
+ if ( ! condition_in_eventtable(conditionname) ) {
+% if ( $JS_DEBUG ) {
+ alert(conditionname + " not in " + eventtable + "; disabling");
+% }
+ cond_select.parentNode.parentNode.style.display = 'none';
+ cond_select.disabled = 'disabled';
+ } else {
+% if ( $JS_DEBUG ) {
+ alert(conditionname + " implicit for " + eventtable + "; enabling");
+% }
+ cond_select.parentNode.parentNode.style.display = '';
+ cond_select.disabled = '';
+ }
+ }
+ }
+
+ }
+
+
+ ////
+ // update action select
+ ////
+
+ // save off the current value first!!
+ var action = what.form.action.options[what.form.action.selectedIndex].value;
+ var a_desc = what.form.action.options[what.form.action.selectedIndex].text;
+ var seen_action = false;
+
+ // blank the current action select
+ for ( var i = what.form.action.length; i >= 0; i-- )
+ what.form.action.options[i] = null;
+
+ if ( action == '' ) {
+ opt(what.form.action, action, a_desc, true );
+ }
+
+ // repopulate it
+% foreach my $eventtable ( FS::part_event->eventtables ) {
+% tie my %actions, 'Tie::IxHash', FS::part_event->actions($eventtable);
+% #use Data::Dumper; warn Dumper(%actions);
+
+ if ( eventtable == '<% $eventtable %>' ) {
+
+% foreach my $action ( keys %actions ) {
+% ( my $description = $actions{$action}->{'description'} ) =~ s/'/\\'/g;
+
+ var sel = false;
+ if ( action == '<% $action %>' ) {
+ seen_action = true;
+ sel = true;
+ }
+ opt( what.form.action, '<% $action %>', '<% $description %>', sel );
+% }
+
+ }
+
+% }
+
+ // by default, turn off warnings and enable the submit button
+ var warning = document.getElementById('action_warning');
+ warning.style.display = 'none';
+ var submit_button = document.getElementById('submit');
+ submit_button.disabled = '';
+
+ if ( ! seen_action && action != '' ) {
+ // add the current (not valid) action back
+ opt( what.form.action, action, a_desc, true );
+ // turn on a warning and disable the submit button
+ //warning.innerHTML = a_desc + ' event not available as a ' +
+ warning.innerHTML = 'Not available as a ' + eventdesc + ' action';
+ warning.style.display = '';
+ submit_button.disabled = 'disabled';
+ }
+
+ }
+
+ function opt(what,value,text,selected) {
+ var optionName = new Option(text, value, false, selected);
+ var length = what.length;
+ what.options[length] = optionName;
+ }
+
+ function action_changed(what) {
+ // remove '** Select new **'
+ if ( what.options[0].value == '' ) {
+ what.options[0] = null;
+ }
+ // remove the warning, remove the invalid action, enable the submit button
+ var warning = document.getElementById('action_warning');
+ if ( warning.style.display == '' ) {
+ warning.style.display = 'none';
+ what.options[what.length-1] = null;
+ document.getElementById('submit').disabled = '';
+ }
+ }
+
+ function condition_changed(what) {
+ // remove '** Select new **'
+ if ( what.options[0].value == '' ) {
+ what.options[0] = null;
+ }
+
+ var previousValue = what.getAttribute('previousValue');
+ var previousText = what.getAttribute('previousText');
+ var value = what.options[what.selectedIndex].value;
+ var text = what.options[what.selectedIndex].text;
+
+% foreach my $value ( keys %condition_remove_warnings ) {
+ if ( previousValue == '<% $value %>' ) {
+ if ( !confirm( <% $condition_remove_warnings{$value} |js_string %> ) ) {
+ for ( var i=0; i < what.length; i++ ) {
+ if ( what.options[i].value == previousValue ) {
+ what.selectedIndex = i;
+ }
+ }
+ return false;
+ }
+ }
+% }
+
+ //alert(previous + ' changed to ' + value);
+
+ var field_regex = /(\d+)$/;
+ var match = field_regex.exec(what.name);
+ if ( !match ) {
+ alert(what.name + " didn't match?!");
+ return;
+ }
+
+ //add the previous condition *back* to all the other selects...
+ condition_add(previousValue, previousText, match[1]);
+
+ what.setAttribute('previousValue', value);
+ what.setAttribute('previousText', text);
+
+ // remove the new condition from all other selects
+ condition_remove(value, match[1]);
+
+ }
+
+ function condition_avail(check_cond, curnum) {
+ for ( var cnum=0; document.getElementById('conditionname'+cnum); cnum++ ) {
+ if ( cnum == curnum ) continue;
+
+ var cond_id = 'conditionname' + cnum;
+ var cond_select = document.getElementById(cond_id);
+
+ //alert("checking " + cond_id + " (" + cond_select.disabled + ")");
+
+ if ( cond_select.disabled ) continue;
+
+ // the current value
+ var conditionname = cond_select.options[cond_select.selectedIndex].value;
+
+ if ( check_cond == conditionname ) return false;
+
+ }
+
+ return true;
+
+ }
+
+ function condition_remove(remove_cond, curnum) {
+
+ if ( remove_cond.length == 0 ) return;
+
+ for ( var cnum=0; document.getElementById('conditionname'+cnum); cnum++ ) {
+ if ( cnum == curnum ) continue;
+
+ var cond_id = 'conditionname' + cnum;
+ var cond_select = document.getElementById(cond_id);
+
+ //for ( var i = cond_select.length; i >= 0; i-- ) {
+ for ( var i=0; i < cond_select.length; i++ ) {
+ if ( cond_select.options[i].value == remove_cond ) {
+ cond_select.options[i] = null;
+ }
+ }
+
+ }
+
+ }
+
+ function condition_add(add_condname, add_conddesc, curnum) {
+
+ if ( add_condname.length == 0 ) return;
+
+ var in_eventtable = condition_in_eventtable(add_condname);
+
+ if ( ! in_eventtable ) return;
+
+ for ( var cnum=0; document.getElementById('conditionname'+cnum); cnum++ ) {
+ if ( cnum == curnum ) continue;
+
+ var cond_id = 'conditionname' + cnum;
+ var cond_select = document.getElementById(cond_id);
+
+ if ( cond_select.disabled ) continue;
+
+ //alert("adding " + add_condname + " to " + cond_id);
+
+ opt(cond_select, add_condname, add_conddesc, false );
+
+ cond_select.parentNode.parentNode.style.display = '';
+
+ }
+
+ }
+
+ function condition_in_eventtable(condname) {
+
+ var eventtable_el = document.getElementById('eventtable');
+ var eventtable = eventtable_el.options[eventtable_el.selectedIndex].value;
+
+ var in_eventtable = false;
+
+% foreach my $eventtable ( FS::part_event->eventtables ) {
+% tie my %conditions, 'Tie::IxHash',
+% FS::part_event_condition->conditions($eventtable);
+
+ if ( eventtable == '<% $eventtable %>' ) {
+
+% foreach my $conditionname ( keys %conditions ) {
+
+ if ( condname == '<% $conditionname %>' ) {
+ in_eventtable = true;
+ }
+
+% }
+
+ }
+
+% }
+
+ return in_eventtable;
+
+ }
+
+ function condition_is_implicit(condname) {
+
+ if ( true <% @implicit_conditions
+ ? ( ' && '. join(' && ', map { "condname != '$_'" }
+ @implicit_conditions
+ )
+ )
+ : ''
+ %> ) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ function condition_repop(cond_select) {
+
+ var eventtable_el = document.getElementById('eventtable');
+ var eventtable = eventtable_el.options[eventtable_el.selectedIndex].value;
+
+ // save off the current value
+ var conditionname = cond_select.options[cond_select.selectedIndex].value;
+ var cond_desc = cond_select.options[cond_select.selectedIndex].text;
+ var seen_condition = false;
+
+ //skip deleted conditions
+ if ( cond_select.disabled && conditionname != '' && ! condition_is_implicit(conditionname) ) {
+ return false;
+ }
+
+ var field_regex = /(\d+)$/;
+ var match = field_regex.exec(cond_select.name);
+ if ( !match ) {
+ alert(what.name + " didn't match?!");
+ return;
+ }
+ var cnum = match[1];
+
+ // blank the current condition select
+ for ( var i = cond_select.length; i >= 0; i-- )
+ cond_select.options[i] = null;
+
+ if ( conditionname == '' ) {
+ opt(cond_select, conditionname, cond_desc, true );
+ }
+
+ // repopulate it
+% foreach my $eventtable ( FS::part_event->eventtables ) {
+% tie my %conditions, 'Tie::IxHash',
+% FS::part_event_condition->conditions($eventtable);
+
+ if ( eventtable == '<% $eventtable %>' ) {
+
+% foreach my $conditionname ( keys %conditions ) {
+% my $description = $conditions{$conditionname}->{'description'};
+% $description =~ s/'/\\'/g;
+
+ var sel = false;
+ if ( conditionname == '<% $conditionname %>' ) {
+ seen_condition = true;
+ sel = true;
+ }
+
+ if ( condition_avail("<% $conditionname %>", cnum) ) {
+ opt(cond_select, '<% $conditionname %>', '<% $description %>', sel);
+ }
+
+% }
+
+ }
+
+% }
+
+ if ( cond_select.length > 1 || cond_select.length == 1 && cond_select.options[0].value.length > 0 ) {
+
+ cond_select.parentNode.parentNode.style.display = '';
+ cond_select.disabled = '';
+
+ } else {
+ cond_select.parentNode.parentNode.style.display = 'none';
+ cond_select.disabled = 'disabled';
+ }
+
+ return seen_condition;
+
+ }
+
+</SCRIPT>
+<%once>
+
+#misc (eventtable, check_freq)
+
+my $eventtable_labels = FS::part_event->eventtable_labels;
+$eventtable_labels->{''} = '** Select type **';
+
+my $check_freq_labels = FS::part_event->check_freq_labels;
+
+#conditions
+
+tie my %all_conditions, 'Tie::IxHash',
+ '' => { 'description' => '*** Select new condition ***', },
+ FS::part_event_condition->conditions();
+
+my %condition_labels = map { $_ => $all_conditions{$_}->{'description'} }
+ keys %all_conditions;
+
+#my %condition_fields = map { $_ => $all_conditions{$_}->{option_fields} }
+# keys %all_conditions;
+my %condition_fields = map { my $c = $_;
+ tie my %opts, 'Tie::IxHash',
+ @{ $all_conditions{$c}->{'option_fields'} || []};
+ %opts = ( map { ( "$c.$_" => $opts{$_} ); }
+ keys %opts
+ );
+ ( $c => [ %opts ] );
+ }
+ keys %all_conditions;
+
+my @implicit_conditions = sort { $all_conditions{$a}->{'implicit_flag'} <=>
+ $all_conditions{$b}->{'implicit_flag'}
+ }
+ grep { $all_conditions{$_}->{'implicit_flag'} }
+ keys %all_conditions;
+
+my @implicit_condition_objs = map {
+ new FS::part_event_condition {
+ 'conditionname' => $_,
+ };
+ }
+ @implicit_conditions;
+
+my %condition_remove_warnings =
+ map { ( $_ => $all_conditions{$_}->{'remove_warning'} ); }
+ grep { $all_conditions{$_}->{'remove_warning'} }
+ keys %all_conditions;
+
+#actions
+
+tie my %all_actions, 'Tie::IxHash',
+ '' => { 'description' => '*** Select event action ***', },
+ FS::part_event->actions();
+
+my %action_labels = map { $_ => $all_actions{$_}->{'description'} }
+ keys %all_actions;
+
+#my %action_fields = map { $_ => $all_actions{$_}->{option_fields} }
+# keys %all_actions;
+my %action_fields = map { my $action = $_;
+ tie my %opts, 'Tie::IxHash',
+ @{ $all_actions{$action}->{option_fields} || [] };
+ %opts = ( map { ( "$action.$_" => $opts{$_} ); }
+ keys %opts
+ );
+ ( $action => [ %opts ] );
+ }
+ keys %all_actions;
+
+#subs
+
+sub n_a {
+ my $t = shift;
+
+ return sub {
+ my $field = shift;
+ qq( <FONT ID="${field}_warning" STYLE="display:none" COLOR="#FF0000">).
+ "Party Party Join us Join us".
+ '</FONT>';
+ };
+}
+
+my $action_layer_values = sub {
+ my( $cgi, $part_event ) = @_;
+ my $action = $cgi->param('action') || $part_event->action;
+ return {} unless $action;
+ scalar( #force hashref
+ {
+ #map { $_ => { $part_event->options } }
+ # keys %action_fields
+ map { my $action = $_;
+ my %fields = @{ $action_fields{$action} };
+ my %obj_opts = $part_event->options;
+ %obj_opts = map { ( "$action.$_" => $obj_opts{$_} ); }
+ keys %obj_opts;
+ my %opts =
+ map { #false laziness w/process/part_event.html
+ my $option = $_;
+ my $value = scalar($cgi->param($_)) || $obj_opts{$_};
+
+ if ( $option =~ /^(.*)\.reasonnum$/ && $value == -1 ) {
+ $value = {
+ 'typenum' => scalar( $cgi->param( "new${option}T" ) ),
+ 'reason' => scalar( $cgi->param( "new${option}" ) ),
+ };
+ }
+
+ ( $option => $value );
+
+ }
+ keys %fields;
+ ( $action => \%opts );
+ }
+ keys %action_fields
+ }
+ );
+};
+
+tie my %cgi_conditions, 'Tie::IxHash';
+
+my $error_callback = sub {
+ my( $cgi, $object, $fields_listref ) = @_;
+
+ my @cond_params = grep /^conditionname\d+$/, $cgi->param;
+
+ %cgi_conditions = map {
+ my $param = $_;
+ my $conditionname = $cgi->param($param);
+ $conditionname => {
+ map {
+
+ my $cgi_key = $_;
+ $cgi_key =~ /^$param\.$conditionname\.(.*)$/ or die 'wtf!';
+ my $key = $1;
+ #my $value = $cgi->param($_);
+
+ #my $info = $all_conditions->{$conditionname}
+ my %cond_opts =
+ @{ $all_conditions{$conditionname}->{'option_fields'} || []};
+ my $info = $cond_opts{$key};
+
+ my $value;
+ #false laziness w/process/part_event.html
+ if ( $info->{'type'} =~ /^(select|checkbox)-?multiple$/
+ or $info->{'type'} =~ /^select/ && $info->{'multiple'} ) {
+ $value = { map { $_ => 1 } $cgi->param($cgi_key) };
+ } elsif ( $info->{'type'} eq 'freq' ) {
+ $value = $cgi->param($cgi_key). $cgi->param($cgi_key.'_units');
+ } else {
+ $value = $cgi->param($cgi_key);
+ }
+
+ $key => $value;
+
+ } grep /^$param\.$conditionname\./, $cgi->param
+ };
+ } grep $cgi->param($_), grep /^conditionname\d+$/, $cgi->param;
+
+};
+
+my $condition_error_callback = sub {
+ map {
+ new FS::part_event_condition { 'conditionname' => $_, };
+ } keys %cgi_conditions;
+};
+
+my $condition_layer_values = sub {
+ #m2_table option causes this to be
+ # part_event_condition instead of part_event
+ my ( $cgi, $part_event_condition, $switches ) = @_;
+ scalar( #force hashref
+ {
+ #map { $_ => { $part_event_condition->options } }
+ # keys %condition_fields
+ map { my $conditionname = $_;
+ my %opts = $switches->{'mode'} eq 'error'
+ ? %{ $cgi_conditions{$conditionname} || {} }
+ : $part_event_condition->options;
+ %opts = (
+ map { ( "$conditionname.$_" => $opts{$_} ); }
+ keys %opts
+ );
+ ( $conditionname => \%opts );
+ }
+ keys %condition_fields
+ }
+ );
+};
+
+
+</%once>
+<%init>
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+
+die "access denied"
+ unless $curuser->access_right('Edit billing events')
+ || $curuser->access_right('Edit global billing events');
+
+my $disable_empty_agent= ! $curuser->access_right('Edit global billing events');
+
+%cgi_conditions = ();
+my $use_cgi_conditions = 0;
+
+my $JS_DEBUG = 0;
+
+</%init>