Merge branch 'patch-19' of https://github.com/gjones2/Freeside
[freeside.git] / httemplate / edit / elements / part_svc_column.html
1 <%doc>
2 To be called from part_svc.cgi.
3 <& elements/part_svc_column.html, 
4     'svc_acct',
5     # options...
6     'part_svc'  => $part_svc, # the existing part_svc to edit
7     'clone'     => 0,         # or a svcpart to clone from
8 &>
9
10 </%doc>
11 <%once>
12 # the semantics of this could be better
13
14 # all of these conditions are when NOT to allow that flag choice
15 # don't allow the 'inventory' flags (M, A) to be chosen for 
16 # fields that aren't free-text
17 my $inv_sub = sub { $_[0]->{disable_inventory} || $_[0]->{type} ne 'text' };
18 tie my %flag, 'Tie::IxHash',
19   ''  => { 'desc' => 'No default', 'condition' => sub { 0 } },
20   'D' => { 'desc' => 'Default', 
21            'condition' =>
22              sub { $_[0]->{disable_default } }
23          },
24   'F' => { 'desc' => 'Fixed (unchangeable)',
25            'condition' =>
26              sub { $_[0]->{disable_fixed} },
27          },
28   'S' => { 'desc' => 'Selectable Choice',
29            'condition' =>
30              sub { $_[0]->{disable_select} },
31          },
32   'M' => { 'desc' => 'Manual selection from inventory',
33            'condition' => $inv_sub,
34          },
35   'A' => { 'desc' => 'Automatically fill in from inventory',
36            'condition' => $inv_sub,
37          },
38   'H' => { 'desc' => 'Select from hardware class',
39            'condition' => sub { $_[0]->{type} ne 'select-hardware' },
40          },
41   'X' => { 'desc' => 'Excluded',
42            'condition' => sub { 1 }, # obsolete
43          },
44 ;
45
46 # the semantics of this could be much better
47 sub flag_condition {
48   my $f = shift;
49   not &{ $flag{$f}->{'condition'} }(@_);
50 }
51
52 my %communigate_fields = (
53   'svc_acct'        => { map { $_=>1 }
54                             qw( file_quota file_maxnum file_maxsize
55                                 password_selfchange password_recover
56                               ),
57                             grep /^cgp_/, fields('svc_acct')
58   },
59   'svc_domain'      => { map { $_=>1 }
60                             qw( max_accounts trailer parent_svcnum ),
61                             grep /^(cgp|acct_def)_/, fields('svc_domain')
62   },
63 );
64 </%once>
65 <INPUT TYPE="hidden" NAME="svcdb" VALUE="<% $svcdb %>">
66 <BR><BR>
67 <& /elements/table.html &>
68   <TR><TH COLSPAN=<% $columns %>>Exports</TH></TR>
69   <TR>
70 % # exports
71 % foreach my $part_export (@part_export) {
72     <TD>
73       <INPUT TYPE="checkbox" \
74              NAME="exportnum<% $part_export->exportnum %>" \
75              VALUE=1 \
76              <% $has_export_svc{$part_export->exportnum} ? 'CHECKED' : '' %>>
77       <% $part_export->label_html %>
78     </TD>
79 %   $count++;
80 %   if ( $count % $columns == 0 ) {
81   </TR>
82   <TR>
83 %   }
84 % }
85   </TR>
86 </TABLE><BR><BR>
87 For the selected table, you can give fields default or fixed (unchangeable)
88 values, or select an inventory class to manually or automatically fill in 
89 that field.
90 <& /elements/table-grid.html, cellpadding => 4 &>
91   <TR>
92     <TH BGCOLOR="#cccccc">Field</TH>
93     <TH BGCOLOR="#cccccc">Label</TH>
94     <TH BGCOLOR="#cccccc" COLSPAN=2>Modifier</TH>
95   </TR>
96 % $part_svc->set('svcpart' => $opt{'clone'}) if $opt{'clone'}; # for now
97 % my $i = 0;
98 % foreach my $field (@fields) {
99 %   my $def = shift @defs;
100 %   my $part_svc_column = $part_svc->part_svc_column($field);
101 %   my $flag = $part_svc_column->columnflag;
102 %   my $formatter = $def->{'format'} || sub { shift };
103 %   my $value = &{$formatter}($part_svc_column->columnvalue);
104   <TR CLASS="row<%$i%>">
105     <TD ROWSPAN=2 CLASS="grid" ALIGN="right">
106       <% $def->{'label'} || $field %>
107     </TD>
108     <TD ROWSPAN=2 CLASS="grid">
109       <INPUT NAME="<% $svcdb %>__<% $field %>_label"
110              STYLE="text-align: right"
111              VALUE="<% $part_svc_column->columnlabel || $def->{'label'} |h %>">
112     </TD>
113
114     <TD ROWSPAN=1 CLASS="grid">
115 %   # flag selection
116 %   if ( $def->{'type'} eq 'disabled' ) {
117 %     $flag = '';
118       No default
119 %   } else {
120 %     my $name = $svcdb.'__'.$field.'_flag';
121       <SELECT NAME="<%$name%>"
122               ID="<%$name%>"
123               STYLE="width:100%"
124               onchange="flag_changed(this)">
125 %     foreach my $f (keys %flag) {
126 %       if ( flag_condition($f, $def, $svcdb, $field) ) {
127           <OPTION VALUE="<%$f%>"<% $flag eq $f ? ' SELECTED' : ''%>>
128             <% $flag{$f}->{desc} %>
129           </OPTION>
130 %       }
131 %     }
132       </SELECT>
133 %   } # if $def->{'type'} eq 'disabled'
134     </TD>
135     <TD CLASS="grid">
136 %   # value entry/selection
137 %   my $name = $svcdb.'__'.$field;
138 %   # These are all MANDATORY SELECT types.  Regardless of the flag value,
139 %   # there will never be a text input (either in svc_* or in part_svc) for
140 %   # these fields.
141 %   if ( $def->{'type'} eq 'checkbox' ) {
142       <& /elements/checkbox.html,
143           'field'       => $name,
144           'curr_value'  => $value,
145           'value'       => 'Y' &>
146 %
147 %   } elsif ( $def->{'type'} eq 'select' ) {
148 %
149 %     if ( $def->{'select_table'} ) {
150       <& /elements/select-table.html,
151           'field'       => $name,
152           'id'          => $name.'_select',
153           'table'       => $def->{'select_table'},
154           'name_col'    => $def->{'select_label'},
155           'value_col'   => $def->{'select_key'},
156           'order_by'    => dbdef->table($def->{'select_table'})->primary_key,
157           'multiple'    => $def->{'multiple'},
158           'disable_empty' => 1,
159           'curr_value'  => $value,
160       &>
161 %     } else {
162 %       my (@options, %labels);
163 %       if ( $def->{'select_list'} ) {
164 %         @options = @{ $def->{'select_list'} };
165 %         @labels{@options} = @options;
166 %       } elsif ( $def->{'select_hash'} ) {
167 %         if ( ref($def->{'select_hash'}) eq 'ARRAY' ) {
168 %           tie my %hash, 'Tie::IxHash', @{ $def->{'select_hash'} };
169 %           $def->{'select_hash'} = \%hash;
170 %         }
171 %         @options = keys( %{ $def->{'select_hash'} } );
172 %         %labels = %{ $def->{'select_hash'} };
173 %       }
174       <& /elements/select.html,
175           'field'       => $name,
176           'id'          => $name.'_select',
177           'options'     => \@options,
178           'labels'      => \%labels,
179           'multiple'    => $def->{'multiple'},
180           'curr_value'  => $value,
181       &>
182 %     }
183 %   } elsif ( $def->{'type'} =~ /select-(.*?).html/ ) {
184       <& '/elements/'.$def->{'type'},
185           'field'       => $name,
186           'id'          => $name.'_select',
187           'multiple'    => $def->{'multiple'},
188           'curr_value'  => $value,
189       &>
190 %   } elsif ( $def->{'type'} eq 'communigate_pro-accessmodes' ) {
191       <& /elements/communigate_pro-accessmodes.html,
192           'element_name_prefix' => $name.'_',
193           'curr_value'  => $value,
194       &>
195 %   } elsif ( $def->{'type'} eq 'textarea' ) {
196 %   # special cases
197       <TEXTAREA NAME="<%$name%>"><% $value |h %></TEXTAREA>
198 %   } elsif ( $def->{'type'} eq 'disabled' ) {
199       <INPUT TYPE="hidden" NAME="<%$name%>" VALUE="">
200 %   } else {
201 %     # the normal case: a text input, and a _select which is an inventory
202 %     # or hardware class
203       <INPUT TYPE="text"
204              NAME="<%$name%>"
205              ID="<%$name%>" 
206              VALUE="<%$value%>">
207 %     # inventory class selection
208       <& /elements/select-table.html,
209           'field'       => $name.'_classnum',
210           'id'          => $name.'_select',
211           'table'       => 'inventory_class',
212           'name_col'    => 'classname',
213           'curr_value'  => $value,
214           'empty_label' => 'Select inventory class',
215           'multiple'    => 1,
216       &>
217 %   }
218     </TD>
219   </TR>
220   <TR CLASS="row<%$i%>">
221     <TD COLSPAN=2 CLASS="def_info">
222 %   if ( $def->{def_info} ) {
223       (<% $def->{def_info} %>)
224     </TD>
225   </TR>
226 %   }
227 % $i = 1-$i;
228 % } # foreach my $field
229 %
230 % # special case: svc_acct password edit ACL
231 % if ( $svcdb eq 'svc_acct' ) {
232 %   push @fields, 'restrict_edit_password';
233   <TR>
234     <TD COLSPAN=3 ALIGN="right">
235       <% emt('Require "Provision" access right to edit password') %>
236     </TD>
237     <TD>
238       <INPUT TYPE="checkbox" NAME="restrict_edit_password" VALUE="Y" \
239       <% $part_svc->restrict_edit_password ? 'CHECKED' : '' %>>
240     </TD>
241   </TR>
242 % }
243 </TABLE>
244 <& /elements/progress-init.html,
245   $svcdb, #form name
246   [ # form fields to send
247     qw(svc svcpart classnum selfservice_access disabled preserve exportnum),
248     @fields
249   ],
250   'process/part_svc.cgi',   # target
251   $p.'browse/part_svc.cgi', # redirect landing
252   $svcdb, #key
253 &>
254 % $svcpart = '' if $opt{clone};
255 <BR>
256 <INPUT NAME="submit"
257        TYPE="button"
258        VALUE="<% emt($svcpart ? 'Apply changes' : 'Add service') %>"
259        onclick="fixup_submit('<%$svcdb%>')"
260 >
261 <%init>
262 my $svcdb = shift;
263 my %opt = @_;
264 my $columns = 3;
265 my $count = 0;
266 my $communigate = 0;
267 my $conf = FS::Conf->new;
268
269 my $part_svc = $opt{'part_svc'} || FS::part_svc->new;
270
271 my @part_export;
272 my $export_info = FS::part_export::export_info($svcdb);
273 foreach (keys %{ $export_info }) {
274   push @part_export, qsearch('part_export', { exporttype => $_ });
275 }
276 $communigate = scalar(grep {$_->exporttype =~ /^communigate/} @part_export);
277
278 my $svcpart = $opt{'clone'} || $part_svc->svcpart;
279 my %has_export_svc;
280 if ( $svcpart ) {
281   foreach (qsearch('export_svc', { svcpart => $svcpart })) {
282     $has_export_svc{$_->exportnum} = 1;
283   }
284 }
285
286 my @fields;
287 if ( defined( dbdef->table($svcdb) ) ) { # when is it ever not defined?
288   @fields = grep {
289     $_ ne 'svcnum'
290       and ( $communigate || ! $communigate_fields{$svcdb}->{$_} )
291       and ( !FS::part_svc->svc_table_fields($svcdb)->{$_}->{disable_part_svc_column}
292             || $part_svc->part_svc_column($_)->columnflag )
293   } fields($svcdb);
294 }
295 if ( $svcdb eq 'svc_acct'
296       or ( $svcdb eq 'svc_broadband' and $conf->exists('svc_broadband-radius') )
297    )
298 {
299   push @fields, 'usergroup';
300 }
301
302 my @defs = map { FS::part_svc->svc_table_fields($svcdb)->{$_} } @fields;
303 </%init>