diff options
| -rw-r--r-- | FS/FS/AccessRight.pm | 139 | ||||
| -rw-r--r-- | FS/FS/access_group.pm | 57 | ||||
| -rw-r--r-- | FS/FS/access_groupagent.pm | 24 | ||||
| -rw-r--r-- | FS/FS/m2name_Common.pm | 95 | ||||
| -rw-r--r-- | FS/FS/part_pkg.pm | 53 | ||||
| -rw-r--r-- | FS/MANIFEST | 3 | ||||
| -rw-r--r-- | htetc/handler.pl | 4 | ||||
| -rw-r--r-- | httemplate/browse/access_group.html | 45 | ||||
| -rw-r--r-- | httemplate/browse/access_user.html | 2 | ||||
| -rw-r--r-- | httemplate/edit/access_group.html | 36 | ||||
| -rw-r--r-- | httemplate/edit/elements/edit.html | 21 | ||||
| -rwxr-xr-x | httemplate/edit/part_pkg.cgi | 2 | ||||
| -rw-r--r-- | httemplate/edit/process/access_group.html | 10 | ||||
| -rw-r--r-- | httemplate/edit/process/elements/process.html | 15 | ||||
| -rw-r--r-- | httemplate/elements/checkboxes-table-name.html | 85 | ||||
| -rw-r--r-- | httemplate/elements/checkboxes-table.html | 28 | 
16 files changed, 520 insertions, 99 deletions
diff --git a/FS/FS/AccessRight.pm b/FS/FS/AccessRight.pm index 01d63e35d..5229e1e65 100644 --- a/FS/FS/AccessRight.pm +++ b/FS/FS/AccessRight.pm @@ -1,7 +1,7 @@  package FS::AccessRight;  use strict; -user vars qw(@rights %rights); +use vars qw(@rights); # %rights);  use Tie::IxHash;  =head1 NAME @@ -19,59 +19,94 @@ assigned to users and/or groups.  =cut +#@rights = ( +#  'Reports' => [ +#    '_desc' => 'Access to high-level reporting', +#  ], +#  'Configuration' => [ +#    '_desc' => 'Access to configuration', +# +#    'Settings' => {}, +# +#    'agent' => [ +#      '_desc' => 'Master access to reseller configuration', +#      'agent_type'  => {}, +#      'agent'       => {}, +#    ], +# +#    'export_svc_pkg' => [ +#      '_desc' => 'Access to export, service and package configuration', +#      'part_export' => {}, +#      'part_svc'    => {}, +#      'part_pkg'    => {}, +#      'pkg_class'   => {}, +#    ], +# +#    'billing' => [ +#      '_desc' => 'Access to billing configuration', +#      'payment_gateway'  => {}, +#      'part_bill_event'  => {}, +#      'prepay_credit'    => {}, +#      'rate'             => {}, +#      'cust_main_county' => {}, +#    ], +# +#    'dialup' => [ +#      '_desc' => 'Access to dialup configuraiton', +#      'svc_acct_pop' => {}, +#    ], +# +#    'broadband' => [ +#      '_desc' => 'Access to broadband configuration', +#      'router'     => {}, +#      'addr_block' => {}, +#    ], +# +#    'misc' => [ +#      'part_referral'      => {}, +#      'part_virtual_field' => {}, +#      'msgcat'             => {}, +#      'inventory_class'    => {}, +#    ], +# +#  }, +# +#); +# +##turn it into a more hash-like structure, but ordered via IxHash + +#well, this is what we have for now.  could be ordered better, could be lots of +# things better, but this ACL system does 99% of what folks need and the UI +# isn't *that* bad  @rights = ( -  'Reports' => [ -    '_desc' => 'Access to high-level reporting', -  ], -  'Configuration' => [ -    '_desc' => 'Access to configuration', - -    'Settings' => {}, - -    'agent' => [ -      '_desc' => 'Master access to reseller configuration', -      'agent_type'  => {}, -      'agent'       => {}, -    ], - -    'export_svc_pkg' => [ -      '_desc' => 'Access to export, service and package configuration', -      'part_export' => {}, -      'part_svc'    => {}, -      'part_pkg'    => {}, -      'pkg_class'   => {}, -    ], - -    'billing' => [ -      '_desc' => 'Access to billing configuration', -      'payment_gateway'  => {}, -      'part_bill_event'  => {}, -      'prepay_credit'    => {}, -      'rate'             => {}, -      'cust_main_county' => {}, -    ], - -    'dialup' => [ -      '_desc' => 'Access to dialup configuraiton', -      'svc_acct_pop' => {}, -    ], - -    'broadband' => [ -      '_desc' => 'Access to broadband configuration', -      'router'     => {}, -      'addr_block' => {}, -    ], - -    'misc' => [ -      'part_referral'      => {}, -      'part_virtual_field' => {}, -      'msgcat'             => {}, -      'inventory_class'    => {}, -    ], - -  }, +  'New customer', +  'View customer', +  #'View Customer | View tickets', +  'Edit customer', +  'Cancel customer', +  'Delete customer', + +  'Order customer package', +  'Change customer package', +  'Edit customer package dates', +  'Customize customer package', +  'Suspend customer package', +  'Unsuspend customer package', +  'Cancel customer package immediately', +  'Cancel customer package later', + +  'Provision service', +  'Unprovision service', +  #legacy link stuff + +  'Post payment', +  'Process payment', +  'Post credit', +  #more financial stuff  ); -#turn it into a more hash-like structure, but ordered via IxHash +sub rights { +  @rights; +} diff --git a/FS/FS/access_group.pm b/FS/FS/access_group.pm index 9d870e57f..25190406f 100644 --- a/FS/FS/access_group.pm +++ b/FS/FS/access_group.pm @@ -3,8 +3,11 @@ package FS::access_group;  use strict;  use vars qw( @ISA );  use FS::Record qw( qsearch qsearchs ); +use FS::m2name_Common; +use FS::access_groupagent; +use FS::access_right; -@ISA = qw(FS::Record); +@ISA = qw(FS::m2m_Common FS::m2name_Common FS::Record);  =head1 NAME @@ -27,15 +30,14 @@ FS::access_group - Object methods for access_group records  =head1 DESCRIPTION -An FS::access_group object represents an example.  FS::access_group inherits from +An FS::access_group object represents an access group.  FS::access_group inherits from  FS::Record.  The following fields are currently supported:  =over 4  =item groupnum - primary key -=item groupname -  - +=item groupname - Access group name  =back @@ -45,7 +47,7 @@ FS::Record.  The following fields are currently supported:  =item new HASHREF -Creates a new example.  To add the example to the database, see L<"insert">. +Creates a new access group.  To add the access group to the database, see L<"insert">.  Note that this stores the hash reference, not a distinct copy of the hash it  points to.  You can ask the object for a copy with the I<hash> method. @@ -84,7 +86,7 @@ returns the error, otherwise returns false.  =item check -Checks all fields to make sure this is a valid example.  If there is +Checks all fields to make sure this is a valid access group.  If there is  an error, returns the error, otherwise returns false.  Called by the insert  and replace methods. @@ -105,12 +107,51 @@ sub check {    $self->SUPER::check;  } +=item access_groupagent + +Returns all associated FS::access_groupagent records. + +=cut + +sub access_groupagent { +  my $self = shift; +  qsearch('access_groupagent', { 'groupnum' => $self->groupnum } ); +} + +=item access_rights + +Returns all associated FS::access_right records. + +=cut + +sub access_rights { +  my $self = shift; +  qsearch('access_right', { 'righttype'   => 'FS::access_group', +                            'rightobjnum' => $self->groupnum  +                          } +         ); +} + +=item access_right RIGHTNAME + +Returns the specified FS::access_right record.  Can be used as a boolean, to +test if this group has the given RIGHTNAME. + +=cut + +sub access_right { +  my( $self, $name ) = shift; +  qsearchs('access_right', { 'righttype'   => 'FS::access_group', +                             'rightobjnum' => $self->groupnum, +                             'rightname'   => $name, +                           } +          ); +} +  =back  =head1 BUGS -The author forgot to customize this manpage. -  =head1 SEE ALSO  L<FS::Record>, schema.html from the base documentation. diff --git a/FS/FS/access_groupagent.pm b/FS/FS/access_groupagent.pm index 6b5def1a3..3de8feeed 100644 --- a/FS/FS/access_groupagent.pm +++ b/FS/FS/access_groupagent.pm @@ -3,6 +3,7 @@ package FS::access_groupagent;  use strict;  use vars qw( @ISA );  use FS::Record qw( qsearch qsearchs ); +use FS::agent;  @ISA = qw(FS::Record); @@ -27,7 +28,7 @@ FS::access_groupagent - Object methods for access_groupagent records  =head1 DESCRIPTION -An FS::access_groupagent object represents an example.  FS::access_groupagent inherits from +An FS::access_groupagent object represents an group reseller virtualization.  FS::access_groupagent inherits from  FS::Record.  The following fields are currently supported:  =over 4 @@ -47,7 +48,7 @@ FS::Record.  The following fields are currently supported:  =item new HASHREF -Creates a new example.  To add the example to the database, see L<"insert">. +Creates a new group reseller virtualization.  To add the record to the database, see L<"insert">.  Note that this stores the hash reference, not a distinct copy of the hash it  points to.  You can ask the object for a copy with the I<hash> method. @@ -86,7 +87,7 @@ returns the error, otherwise returns false.  =item check -Checks all fields to make sure this is a valid example.  If there is +Checks all fields to make sure this is a valid group reseller virtualization.  If there is  an error, returns the error, otherwise returns false.  Called by the insert  and replace methods. @@ -100,20 +101,29 @@ sub check {    my $error =       $self->ut_numbern('groupagentnum') -    || $self->ut_number('groupnum') -    || $self->ut_number('agentnum') +    || $self->ut_foreign_key('groupnum', 'access_group', 'groupnum') +    || $self->ut_foreign_key('agentnum', 'agent',        'agentnum')    ;    return $error if $error;    $self->SUPER::check;  } +=item agent + +Returns the associated FS::agent object. + +=cut + +sub agent { +  my $self = shift; +  qsearchs('agent', { 'agentnum' => $self->agentnum } ); +} +  =back  =head1 BUGS -The author forgot to customize this manpage. -  =head1 SEE ALSO  L<FS::Record>, schema.html from the base documentation. diff --git a/FS/FS/m2name_Common.pm b/FS/FS/m2name_Common.pm new file mode 100644 index 000000000..7c9637e27 --- /dev/null +++ b/FS/FS/m2name_Common.pm @@ -0,0 +1,95 @@ +package FS::m2name_Common; + +use strict; +use vars qw( @ISA $DEBUG ); +use FS::Schema qw( dbdef ); +use FS::Record qw( qsearch qsearchs ); #dbh ); + +@ISA = qw( FS::Record ); + +$DEBUG = 0; + +=head1 NAME + +FS::m2name_Common - Base class for tables with a related table listing names + +=head1 SYNOPSIS + +use FS::m2name_Common; + +@ISA = qw( FS::m2name_Common ); + +=head1 DESCRIPTION + +FS::m2name_Common is intended as a base class for classes which have a +related table that lists names. + +=head1 METHODS + +=over 4 + +=item process_m2name + +=cut + +sub process_m2name { +  my( $self, %opt ) = @_; + +  my $self_pkey = $self->dbdef_table->primary_key; +  my $link_sourcekey = $opt{'num_col'} || $self_pkey; + +  my $link_table = $self->_load_table($opt{'link_table'}); + +  my $link_static = $opt{'link_static'} || {}; + +  foreach my $name ( @{ $opt{'names_list'} } ) { + +    my $obj = qsearchs( $link_table, { +        $link_sourcekey  => $self->$self_pkey(), +        $opt{'name_col'} => $name, +        %$link_static, +    }); + +    if ( $obj && ! $opt{'params'}->{"$link_table.$name"} ) { + +      my $d_obj = $obj; #need to save $obj for below. +      my $error = $d_obj->delete; +      die "error deleting $d_obj for $link_table.$name: $error" if $error; + +    } elsif ( $opt{'params'}->{"$link_table.$name"} && ! $obj ) { + +      #ok to clobber it now (but bad form nonetheless?) +      #$obj = new "FS::$link_table" ( { +      $obj = "FS::$link_table"->new( { +        $link_sourcekey  => $self->$self_pkey(), +        $opt{'name_col'} => $name, +        %$link_static, +      }); +      my $error = $obj->insert; +      die "error inserting $obj for $link_table.$name: $error" if $error; +    } + +  } + +  ''; +} + +sub _load_table { +  my( $self, $table ) = @_; +  eval "use FS::$table"; +  die $@ if $@; +  $table; +} + +=back + +=head1 BUGS + +=head1 SEE ALSO + +L<FS::Record> + +=cut + +1; + diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm index 05dc59913..de4d047de 100644 --- a/FS/FS/part_pkg.pm +++ b/FS/FS/part_pkg.pm @@ -1,7 +1,7 @@  package FS::part_pkg;  use strict; -use vars qw( @ISA %freq %plans $DEBUG ); +use vars qw( @ISA %plans $DEBUG );  use Carp qw(carp cluck confess);  use Tie::IxHash;  use FS::Conf; @@ -571,6 +571,32 @@ sub is_free {    }  } + +sub freqs_href { +  #method, class method or sub? #my $self = shift; + +  tie my %freq, 'Tie::IxHash',  +    '0'  => '(no recurring fee)', +    '1h' => 'hourly', +    '1d' => 'daily', +    '1w' => 'weekly', +    '2w' => 'biweekly (every 2 weeks)', +    '1'  => 'monthly', +    '2'  => 'bimonthly (every 2 months)', +    '3'  => 'quarterly (every 3 months)', +    '6'  => 'semiannually (every 6 months)', +    '12' => 'annually', +    '24' => 'biannually (every 2 years)', +    '36' => 'triannually (every 3 years)', +    '48' => '(every 4 years)', +    '60' => '(every 5 years)', +    '120' => '(every 10 years)', +  ; + +  \%freq; + +} +  =item freq_pretty  Returns an english representation of the I<freq> field, such as "monthly", @@ -578,29 +604,14 @@ Returns an english representation of the I<freq> field, such as "monthly",  =cut -tie %freq, 'Tie::IxHash',  -  '0'  => '(no recurring fee)', -  '1h' => 'hourly', -  '1d' => 'daily', -  '1w' => 'weekly', -  '2w' => 'biweekly (every 2 weeks)', -  '1'  => 'monthly', -  '2'  => 'bimonthly (every 2 months)', -  '3'  => 'quarterly (every 3 months)', -  '6'  => 'semiannually (every 6 months)', -  '12' => 'annually', -  '24' => 'biannually (every 2 years)', -  '36' => 'triannually (every 3 years)', -  '48' => '(every 4 years)', -  '60' => '(every 5 years)', -  '120' => '(every 10 years)', -; -  sub freq_pretty {    my $self = shift;    my $freq = $self->freq; -  if ( exists($freq{$freq}) ) { -    $freq{$freq}; + +  my $freqs_href = $self->freqs_href; + +  if ( exists($freqs_href->{$freq}) ) { +    $freqs_href->{$freq};    } else {      my $interval = 'month';      if ( $freq =~ /^(\d+)([hdw])$/ ) { diff --git a/FS/MANIFEST b/FS/MANIFEST index 9e3285dbb..098fe4a64 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -342,3 +342,6 @@ t/access_right.t  FS/m2m_Common.pm  FS/pay_batch.pm  t/pay_batch.t +FS/ConfDefaults.pm +t/ConfDefaults.t +FS/m2name_Common.pm diff --git a/htetc/handler.pl b/htetc/handler.pl index d400a55ea..1dfa1376e 100644 --- a/htetc/handler.pl +++ b/htetc/handler.pl @@ -182,6 +182,10 @@ sub handler        use FS::pkg_class;        use FS::access_user;        use FS::access_group; +      use FS::access_usergroup; +      use FS::access_groupagent; +      use FS::access_right; +      use FS::AccessRight;        if ( %%%RT_ENABLED%%% ) {          eval ' diff --git a/httemplate/browse/access_group.html b/httemplate/browse/access_group.html index 6ba89ea81..9ebb2b882 100644 --- a/httemplate/browse/access_group.html +++ b/httemplate/browse/access_group.html @@ -4,6 +4,45 @@ my $html_init =    "Internal access groups control access to the back-office interface.<BR><BR>".    qq!<A HREF="${p}edit/access_group.html"><I>Add an internal access group</I></A><BR><BR>!; +#false laziness w/access_user.html & agent_type.cgi +my $agents_sub = sub { +  my $access_group = shift; + +  [ map { +          my $access_groupagent = $_; +          my $agent = $access_groupagent->agent; +          [ +            { +              'data'  => $agent->agent, +              'align' => 'left', +              'link'  => $p. 'edit/agent.cgi?'. $agent->agentnum, +            }, +          ]; +        } +    grep { $_->agent } #? +    $access_group->access_groupagent, + +  ]; +   +}; + +my $rights_sub = sub { +  my $access_group = shift; + +  [ map { my $access_right = $_; +          [ +            {  +              'data'  => $access_right->rightname, +              'align' => 'left', +            }, +          ]; +        } +    $access_group->access_rights, + +  ]; + +}; +  my $count_query = 'SELECT COUNT(*) FROM access_group';  my $link = [ $p.'edit/access_group.html?', 'groupnum' ]; @@ -22,12 +61,18 @@ my $link = [ $p.'edit/access_group.html?', 'groupnum' ];                   'count_query' => $count_query,                   'header'      => [ '#',                                      'Group name', +                                    'Agents', +                                    'Rights',                                    ],                   'fields'      => [ 'groupnum',                                      'groupname', +                                    $agents_sub, +                                    $rights_sub,                                    ],                   'links'       => [ $link,                                      $link, +                                    '', +                                    '',                                    ],               )  %> diff --git a/httemplate/browse/access_user.html b/httemplate/browse/access_user.html index 38d5430b1..be11bf82a 100644 --- a/httemplate/browse/access_user.html +++ b/httemplate/browse/access_user.html @@ -4,7 +4,7 @@ my $html_init =    "Internal users have access to the back-office interface.  Typically, this is your employees and contractors, but in a VISP setup, you can also add accounts for your reseller's employees.  It is <B>highly recommended</B> to add a <B>separate account for each person</B> rather than using role accounts.<BR><BR>".    qq!<A HREF="${p}edit/access_user.html"><I>Add an internal user</I></A><BR><BR>!; -#false laziness w/agent_type.cgi +#false laziness w/access_group.html & agent_type.cgi  my $groups_sub = sub {    my $access_user = shift; diff --git a/httemplate/edit/access_group.html b/httemplate/edit/access_group.html index 11b8df7bc..d7f7667f4 100644 --- a/httemplate/edit/access_group.html +++ b/httemplate/edit/access_group.html @@ -5,6 +5,42 @@                                 'groupnum'   => 'Group number',                                 'groupname'  => 'Group name',                               }, +                   'viewall_dir' => 'browse', + +                 'html_bottom' => +                   sub { +                     my $access_group = shift; + +                     "<BR>Group virtualized to customers of agents:<BR>". +                     ntable("#cccccc",2). +                     '<TR><TD>'. +                     include( '/elements/checkboxes-table.html', +                                'source_obj'   => $access_group, +                                'link_table'   => 'access_groupagent', +                                'target_table' => 'agent', +                                'name_col'     => 'agent', +                                'target_link'  => $p.'edit/agent.cgi?', +                                'disable-able' => 1, +                            ). +                     '</TR></TD></TABLE>'. + +                     "<BR>Group rights:<BR>". +                     ntable("#cccccc",2). +                     '<TR><TD>'. +                     include( '/elements/checkboxes-table-name.html', +                                'source_obj'   => $access_group, +                                'link_table'   => 'access_right', +                                'link_static'  => { 'righttype' => +                                                      'FS::access_group', +                                                  }, +                                'num_col'      => 'rightobjnum', +                                'name_col'     => 'rightname', +                                'names_list'   => [ FS::AccessRight->rights() ], +                            ). +                     '</TR></TD></TABLE>' + +                     ; +                   },             )  %> diff --git a/httemplate/edit/elements/edit.html b/httemplate/edit/elements/edit.html index 120c03a3c..94bf6eecd 100644 --- a/httemplate/edit/elements/edit.html +++ b/httemplate/edit/elements/edit.html @@ -16,6 +16,18 @@    #    # 'menubar'     => '', #menubar arrayref    # +  # #run when re-displaying with an error +  # 'error_callback' => sub { my $cgi, $object = @_; }, +  # +  # #run when editing +  # 'edit_callback' => sub { my $cgi, $object = @_; }, +  # +  # #run when adding +  # 'new_callback' => sub { my $cgi, $object = @_; }, +  # +  # #broken'html_table_bottom' => '', #string or listref of additinal HTML to +  #                            #add before </TABLE> +  #    # 'viewall_dir' => '', #'search' or 'browse', defaults to 'search'    #    # 'html_bottom' => '', #string @@ -43,16 +55,25 @@        map { $_ => scalar($cgi->param($_)) } fields($table)      }); +    &{$opt{'error_callback'}}($cgi, $object) +      if $opt{'error_callback'}; +    } elsif ( $cgi->keywords ) { #editing      my( $query ) = $cgi->keywords;      $query =~ /^(\d+)$/;      $object = qsearchs( $table, { $pkey => $1 } ); +    &{$opt{'edit_callback'}}($cgi, $object) +      if $opt{'edit_callback'}; +    } else { #adding      $object = $class->new( {} ); +    &{$opt{'new_callback'}}($cgi, $object) +      if $opt{'new_callback'}; +    }    my $action = $object->$pkey() ? 'Edit' : 'Add'; diff --git a/httemplate/edit/part_pkg.cgi b/httemplate/edit/part_pkg.cgi index 462d5161f..b085d2260 100755 --- a/httemplate/edit/part_pkg.cgi +++ b/httemplate/edit/part_pkg.cgi @@ -237,7 +237,7 @@ if ( dbdef->table('pkg_svc')->column('primary_svc') ) {    push @form_radio, 'pkg_svc_primary';  } -tie my %freq, 'Tie::IxHash', %FS::part_pkg::freq; +tie my %freq, 'Tie::IxHash', %{FS::part_pkg->freqs_href()};  if ( $part_pkg->dbdef_table->column('freq')->type =~ /(int)/i ) {    delete $freq{$_} foreach grep { ! /^\d+$/ } keys %freq;  } diff --git a/httemplate/edit/process/access_group.html b/httemplate/edit/process/access_group.html index e8c6d07b1..9bb9d1dda 100644 --- a/httemplate/edit/process/access_group.html +++ b/httemplate/edit/process/access_group.html @@ -1,5 +1,15 @@  <%= include( 'elements/process.html',                 'table'       => 'access_group',                 'viewall_dir' => 'browse', +               'process_m2m' => { 'link_table'   => 'access_groupagent', +                                  'target_table' => 'agent', +                                }, +               'process_m2name' => { +                     'link_table'   => 'access_right', +                     'link_static'  => { 'righttype' => 'FS::access_group', }, +                     'num_col'      => 'rightobjnum', +                     'name_col'     => 'rightname', +                     'names_list'   => [ FS::AccessRight->rights() ], +               },             )  %> diff --git a/httemplate/edit/process/elements/process.html b/httemplate/edit/process/elements/process.html index 59ad35ee4..a6e3b50e3 100644 --- a/httemplate/edit/process/elements/process.html +++ b/httemplate/edit/process/elements/process.html @@ -16,7 +16,14 @@    # 'viewall_dir' => '', #'search' or 'browse', defaults to 'search'    # 'process_m2m' => { 'link_table'   => 'link_table_name',    #                    'target_table' => 'target_table_name', -  #                  }. +  #                  }, +  # 'process_m2name' => { 'link_table'   => 'link_table_name', +  #                       'link_static' => { 'column' => 'value' }, +  #                       'num_col' => 'column', #if column name is different in +  #                                              #link_table than source_table  +  #                       'name_col' => 'name_column', +  #                       'names_list' => [ 'list', 'names' ], +  #                     },    my(%opt) = @_; @@ -52,6 +59,12 @@                                );    } +  if ( !$error && $opt{'process_m2name'} ) { +    $error = $new->process_m2name( %{ $opt{'process_m2name'} }, +                                   'params' => scalar($cgi->Vars), +                                 ); +  } +    if ( $error ) {      $cgi->param('error', $error);      print $cgi->redirect(popurl(2). "$table.html?". $cgi->query_string ); diff --git a/httemplate/elements/checkboxes-table-name.html b/httemplate/elements/checkboxes-table-name.html new file mode 100644 index 000000000..8e9dd29d2 --- /dev/null +++ b/httemplate/elements/checkboxes-table-name.html @@ -0,0 +1,85 @@ +<% + +  ## +  # required +  ## +  # 'link_table'      => 'table_name', +  # +  # 'name_col' => 'name_column', +  # #or +  # 'name_callback' => sub { }, +  # +  # 'names_list' => [ 'value', 'other value' ], +  # +  ## +  # recommended (required?) +  ## +  # 'source_obj'   => $obj, +  # #or? +  # #'source_table' => 'table_name', +  # #'sourcenum'    => '4', #current value of primary key in source_table +  # #                       # (none is okay, just pass it if you have it) +  ## +  # optional +  ## +  # 'num_col' => 'col_name' #if column name is different in link_table than +  #                         #source_table +  # 'link_static' => { 'column' => 'value' }, + +  my( %opt ) = @_; + +  my( $source_pkey, $sourcenum, $source_obj ); +  if ( $opt{'source_obj'} ) { + +    $source_obj = $opt{'source_obj'}; +    #$source_table = $source_obj->dbdef_table->table; +    $source_pkey = $source_obj->dbdef_table->primary_key; +    $sourcenum = $source_obj->$source_pkey(); + +  } else { + +    #$source_obj? +    $source_pkey = $opt{'source_table'} +                     ? dbdef->table($opt{'source_table'})->primary_key +                     : ''; +    $sourcenum = $opt{'sourcenum'}; +  } + +  $source_pkey = $opt{'num_col'} || $source_pkey; + +  my $link_static = $opt{'link_static'} || {}; + +%> + +<% foreach my $name ( @{ $opt{'names_list'} } ) { + +     my $checked; +     if ( $cgi->param('error') ) { + +       $checked = $cgi->param($opt{'link_table'}. ".$name" ) +                    ? 'CHECKED' +                    : ''; + +     } else { + +       $checked = +         qsearchs( $opt{'link_table'}, { +                                         $source_pkey     => $sourcenum, +                                         $opt{'name_col'} => $name, +                                         %$link_static, +                                       }                                 ) +                    ? 'CHECKED' +                    : '' + +     } + +%> + +  <INPUT TYPE="checkbox" NAME="<%= $opt{'link_table'}. ".$name" %>" <%= $checked %> VALUE="ON"> + +  <%= $name %> + +  <BR> + +<% } %> + diff --git a/httemplate/elements/checkboxes-table.html b/httemplate/elements/checkboxes-table.html index d26ebef35..16376fa3d 100644 --- a/httemplate/elements/checkboxes-table.html +++ b/httemplate/elements/checkboxes-table.html @@ -68,16 +68,28 @@     ) {       my $targetnum = $target_obj->$target_pkey(); + +     my $checked; +     if ( $cgi->param('error') ) { + +       $checked = $cgi->param($target_pkey.$targetnum) +                    ? 'CHECKED' +                    : ''; + +     } else { + +       $checked = qsearchs( $opt{'link_table'}, { +                                                  $source_pkey => $sourcenum, +                                                  $target_pkey => $targetnum, +                                                }                             ) +                    ? 'CHECKED' +                    : '' + +     } +  %> -  <INPUT TYPE="checkbox" NAME="<%= $target_pkey. $targetnum %>" <%= -        qsearchs( $opt{'link_table'}, { -          $source_pkey => $sourcenum, -          $target_pkey => $targetnum, -        }) -          ? 'CHECKED ' -          : '' -  %> VALUE="ON"> +  <INPUT TYPE="checkbox" NAME="<%= $target_pkey. $targetnum %>" <%= $checked %> VALUE="ON">    <% if ( $opt{'target_link'} ) { %>  | 
