1 package SL::Presenter::ReclamationFilter;
5 use SL::Presenter::EscapedText qw(escape is_escaped);
6 use SL::Presenter::Tag qw(html_tag input_tag select_tag date_tag checkbox_tag);
7 use SL::Locale::String qw(t8);
9 use Exporter qw(import);
17 my ($filter, $reclamation_type, %params) = @_;
19 $filter ||= undef; #filter should not be '' (empty string);
20 my %default_filter_elements = ( # {{{
23 'text' => t8("Reclamation Reason"),
24 'input_type' => 'input_tag',
25 'input_name' => 'filter.reclamation_items.reason.name:substr::ilike',
26 'input_default' => $filter->{reclamation_items}->{reason}->{'name:substr::ilike'},
31 'text' => t8("Reclamation ID"),
32 'input_type' => 'input_tag',
33 'input_name' => 'filter.id:number',
34 'input_default' =>$filter->{'id:number'},
40 'text' => t8("Reclamation Number"),
41 'input_type' => 'input_tag',
42 'input_name' => 'filter.record_number:substr::ilike',
43 'input_default' =>$filter->{'record_number:substr::ilike'},
44 'report_id' => 'record_number',
49 'text' => t8("Employee Name"),
50 'input_type' => 'input_tag',
51 'input_name' => 'filter.employee.name:substr::ilike',
52 'input_default' =>$filter->{employee}->{'name:substr::ilike'},
53 'report_id' => 'employee',
58 'text' => t8("Salesman Name"),
59 'input_type' => 'input_tag',
60 'input_name' => 'filter.salesman.name:substr::ilike',
61 'input_default' =>$filter->{salesman}->{'name:substr::ilike'},
62 'report_id' => 'salesman',
65 # 6,7 for Customer/Vendor
68 'text' => t8("Customer Name"),
69 'input_type' => 'input_tag',
70 'input_name' => 'filter.customer.name:substr::ilike',
71 'input_default' => $filter->{customer}->{'name:substr::ilike'},
72 'report_id' => 'customer',
73 'active' => ($reclamation_type eq 'sales_reclamation' ? 1 : 0),
77 'text' => t8("Vendor Name"),
78 'input_type' => 'input_tag',
79 'input_name' => 'filter.vendor.name:substr::ilike',
80 'input_default' => $filter->{vendor}->{'name:substr::ilike'},
81 'report_id' => 'vendor',
82 'active' => ($reclamation_type eq 'purchase_reclamation' ? 1 : 0),
84 'customer_number' => {
86 'text' => t8("Customer Number"),
87 'input_type' => 'input_tag',
88 'input_name' => 'filter.customer.customernumber:substr::ilike',
89 'input_default' => $filter->{customer}->{'customernumber:substr::ilike'},
90 'active' => ($reclamation_type eq 'sales_reclamation' ? 1 : 0),
94 'text' => t8("Vendor Number"),
95 'input_type' => 'input_tag',
96 'input_name' => 'filter.vendor.vendornumber:substr::ilike',
97 'input_default' => $filter->{vendor}->{'vendornumber:substr::ilike'},
98 'active' => ($reclamation_type eq 'purchase_reclamation' ? 1 : 0),
102 'text' => t8("Contact Name"),
103 'input_type' => 'input_tag',
104 'input_name' => 'filter.contact.cp_name:substr::ilike',
105 'input_default' =>$filter->{contact}->{'cp_name:substr::ilike'},
106 'report_id' => 'contact',
111 'text' => t8("Language Code"),
112 'input_type' => 'input_tag',
113 'input_name' => 'filter.language.article_code:substr::ilike',
114 'input_default' =>$filter->{language}->{'article_code:substr::ilike'},
115 'report_id' => 'language',
118 'department_description' => {
120 'text' => t8("Department Description"),
121 'input_type' => 'input_tag',
122 'input_name' => 'filter.department.description:substr::ilike',
123 'input_default' =>$filter->{department}->{'description:substr::ilike'},
124 'report_id' => 'department',
127 'globalproject_projectnumber' => {
129 'text' => t8("Project Number"),
130 'input_type' => 'input_tag',
131 'input_name' => 'filter.globalproject.projectnumber:substr::ilike',
132 'input_default' =>$filter->{globalproject}->{'projectnumber:substr::ilike'},
133 'report_id' => 'globalproject',
136 'globalproject_description' => {
138 'text' => t8("Project Description"),
139 'input_type' => 'input_tag',
140 'input_name' => 'filter.globalproject.description:substr::ilike',
141 'input_default' =>$filter->{globalproject}->{'description:substr::ilike'},
144 'cv_record_number' => {
146 'text' => ($reclamation_type eq 'sales_reclamation'
147 ? t8("Customer Record Number")
148 : t8("Vendor Record Number")
150 'input_type' => 'input_tag',
151 'input_name' => 'filter.cv_record_number:substr::ilike',
152 'input_default' => $filter->{'cv_record_number:substr::ilike'},
153 'report_id' => 'cv_record_number',
156 'transaction_description' => {
158 'text' => t8("Description"),
159 'input_type' => 'input_tag',
160 'input_name' => 'filter.transaction_description:substr::ilike',
161 'input_default' =>$filter->{'transaction_description:substr::ilike'},
162 'report_id' => 'transaction_description',
167 'text' => t8("Notes"),
168 'input_type' => 'input_tag',
169 'input_name' => 'filter.notes:substr::ilike',
170 'input_default' =>$filter->{'notes:substr::ilike'},
171 'report_id' => 'notes',
176 'text' => t8("Internal Notes"),
177 'input_type' => 'input_tag',
178 'input_name' => 'filter.intnotes:substr::ilike',
179 'input_default' =>$filter->{'intnotes:substr::ilike'},
180 'report_id' => 'intnotes',
185 'text' => t8("Shipping Point"),
186 'input_type' => 'input_tag',
187 'input_name' => 'filter.shippingpoint:substr::ilike',
188 'input_default' =>$filter->{'shippingpoint:substr::ilike'},
189 'report_id' => 'shippingpoint',
194 'text' => t8("Ship via"),
195 'input_type' => 'input_tag',
196 'input_name' => 'filter.shipvia:substr::ilike',
197 'input_default' =>$filter->{'shipvia:substr::ilike'},
198 'report_id' => 'shipvia',
203 'text' => t8("Total"),
204 'input_type' => 'input_tag',
205 'input_name' => 'filter.amount:number',
206 'input_default' =>$filter->{'amount:number'},
207 'report_id' => 'amount',
212 'text' => t8("Subtotal"),
213 'input_type' => 'input_tag',
214 'input_name' => 'filter.netamount:number',
215 'input_default' =>$filter->{'netamount:number'},
216 'report_id' => 'netamount',
219 'delivery_term_description' => {
221 'text' => t8("Delivery Terms"),
222 'input_type' => 'input_tag',
223 'input_name' => 'filter.delivery_term.description:substr::ilike',
224 'input_default' =>$filter->{delivery_term}->{'description:substr::ilike'},
225 'report_id' => 'delivery_term',
228 'payment_description' => {
230 'text' => t8("Payment Terms"),
231 'input_type' => 'input_tag',
232 'input_name' => 'filter.payment.description:substr::ilike',
233 'input_default' =>$filter->{payment}->{'description:substr::ilike'},
234 'report_id' => 'payment',
239 'text' => t8("Currency"),
240 'input_type' => 'input_tag',
241 'input_name' => 'filter.currency.name:substr::ilike',
242 'input_default' =>$filter->{currency}->{'name:substr::ilike'},
243 'report_id' => 'currency',
248 'text' => t8("Exchangerate"),
249 'input_type' => 'input_tag',
250 'input_name' => 'filter.exchangerate:number',
251 'input_default' =>$filter->{'exchangerate:number'},
252 'report_id' => 'exchangerate',
257 'text' => t8("Tax Included"),
258 'input_type' => 'yes_no_tag',
259 'input_name' => 'filter.taxincluded',
260 'input_default' =>$filter->{taxincluded},
261 'report_id' => 'taxincluded',
264 'taxzone_description' => {
266 'text' => t8("Tax zone"),
267 'input_type' => 'input_tag',
268 'input_name' => 'filter.taxzone.description:substr::ilike',
269 'input_default' =>$filter->{taxzone}->{'description:substr::ilike'},
270 'report_id' => 'taxzone',
275 'text' => t8("Tax point"),
276 'input_type' => 'date_tag',
277 'input_name' => 'tax_point',
278 'input_default_ge' => $filter->{'tax_pont' . ':date::ge'},
279 'input_default_le' => $filter->{'tax_pont' . ':date::le'},
280 'report_id' => 'tax_point',
285 'text' => t8("Deadline"),
286 'input_type' => 'date_tag',
287 'input_name' => 'reqdate',
288 'input_default_ge' => $filter->{'reqdate' . ':date::ge'},
289 'input_default_le' => $filter->{'reqdate' . ':date::le'},
290 'report_id' => 'reqdate',
295 'text' => t8("Booking Date"),
296 'input_type' => 'date_tag',
297 'input_name' => 'transdate',
298 'input_default_ge' => $filter->{'transdate' . ':date::ge'},
299 'input_default_le' => $filter->{'transdate' . ':date::le'},
300 'report_id' => 'transdate',
305 'text' => t8("Creation Time"),
306 'input_type' => 'date_tag',
307 'input_name' => 'itime',
308 'input_default_ge' => $filter->{'itime' . ':date::ge'},
309 'input_default_le' => $filter->{'itime' . ':date::le'},
310 'report_id' => 'itime',
315 'text' => t8("Last modification Time"),
316 'input_type' => 'date_tag',
317 'input_name' => 'mtime',
318 'input_default_ge' => $filter->{'mtime' . ':date::ge'},
319 'input_default_le' => $filter->{'mtime' . ':date::le'},
320 'report_id' => 'mtime',
325 'text' => t8("Delivered"),
326 'input_type' => 'yes_no_tag',
327 'input_name' => 'filter.delivered',
328 'input_default' =>$filter->{delivered},
329 'report_id' => 'delivered',
334 'text' => t8("Closed"),
335 'input_type' => 'yes_no_tag',
336 'input_name' => 'filter.closed',
337 'input_default' =>$filter->{closed},
338 'report_id' => 'closed',
343 # combine default and param values for filter_element,
344 # only replace the lowest occurrence
345 my %filter_elements = %default_filter_elements;
346 while(my ($key, $value) = each (%{$params{filter_elements}})) {
347 if(exists $filter_elements{$key}) {
348 $filter_elements{$key} = ({
349 %{$filter_elements{$key}},
353 $filter_elements{$key} = $value;
357 my @filter_element_params =
358 sort { $a->{position} <=> $b->{position} }
359 grep { $_->{active} }
360 values %filter_elements;
363 for my $filter_element_param (@filter_element_params) {
364 unless($filter_element_param->{active}) {
368 my $filter_element = _create_input_element($filter_element_param, %params);
370 push @filter_elements, $filter_element;
373 my $filter_form_div = _create_filter_form(\@filter_elements, %params);
375 is_escaped($filter_form_div);
378 sub _create_input_element {
379 my ($element_param, %params) = @_;
381 my $element_th = html_tag('th', $element_param->{text}, align => 'right');
383 my $element_input = '';
385 if($element_param->{input_type} eq 'input_tag') {
387 $element_input = input_tag($element_param->{input_name}, $element_param->{input_default});
389 } elsif ($element_param->{input_type} eq 'yes_no_tag') {
391 $element_input = select_tag($element_param->{input_name}, [ [ 1 => t8('Yes') ], [ 0 => t8('No') ] ], default => $element_param->{input_default}, with_empty => 1)
393 } elsif($element_param->{input_type} eq 'date_tag') {
396 html_tag('th', t8("After"), align => 'right') .
398 date_tag("filter." . $element_param->{input_name} . ":date::ge", $element_param->{input_default_ge})
402 html_tag('th', t8("Before"), align => 'right') .
404 date_tag("filter." . $element_param->{input_name} . ":date::le", $element_param->{input_default_le})
410 html_tag('tr', $after_input)
412 html_tag('tr', $before_input)
417 my $element_input_td = html_tag('td',
422 my $element_checkbox_td = '';
423 unless($params{no_show} || $element_param->{report_id} eq '') {
424 my $checkbox = checkbox_tag('active_in_report.' . $element_param->{report_id}, checked => $params{active_in_report}->{$element_param->{report_id}}, for_submit => 1);
425 $element_checkbox_td = html_tag('td', $checkbox);
428 return $element_th . $element_input_td . $element_checkbox_td;
431 sub _create_filter_form {
432 my ($ref_elements, %params) = @_;
434 my $filter_table = _create_input_div($ref_elements, %params);
436 my $filter_form = html_tag('form', $filter_table, method => 'post', action => 'controller.pl', id => 'search_form');
441 sub _create_input_div {
442 my ($ref_elements, %params) = @_;
443 my @elements = @{$ref_elements};
445 my $div_columns = "";
447 $params{count_columns} ||= 4;
448 my $elements_per_column = (int((scalar(@{$ref_elements}) - 1) / $params{count_columns}) + 1);
449 for my $i (0 .. ($params{count_columns} - 1)) {
452 for my $j (0 .. ($elements_per_column - 1) ) {
453 my $idx = $elements_per_column * $i + $j;
454 my $element = $elements[$idx];
455 $rows .= html_tag('tr', $element);
458 $div_columns .= html_tag('div',
462 . html_tag('th', t8('Filter'))
463 . ( $params{no_show} ? '' : html_tag('th', t8('Show')) )
470 my $input_div = html_tag('div', $div_columns, style => "display:flex;flex-wrap:wrap");
485 SL::Presenter::ReclamationFilter - Presenter module for a generic Filter on
490 # in Reclamation Controller
491 my $filter_html = SL::Presenter::ReclamationFilter::filter(
492 $::form->{filter}, $self->type, active_in_report => $::form->{active_in_report}
500 =item C<filter $filter, $reclamation_type, %params>
502 Returns a rendered version (actually an instance of
503 L<SL::Presenter::EscapedText>) of a filter form for reclamations of type
504 C<$reclamation_type>.
506 C<$filter> should be the C<filter> value of the last C<$::form>. This is used to
507 get the previous values of the input fields.
509 C<%params> can include:
515 If falsish (the default) then a check box is added after the input field. Which
516 specifies whether the corresponding column appears in the report. The value of
517 the check box can be changed by the user.
519 =item * active_in_report
521 If C<$params{no_show}> is falsish, this is used to set the values of the check
522 boxes, after the input fields. This can be set to the C<active_in_report> value
523 of the last C<$::form>.
525 =item * filter_elements
527 Is combined with the default filter elements. This can be used to override
528 default values of the filter elements or to add a new ones.
530 #deactivate the id and record_number fields
531 $params{filter_elements} = ({
533 record_number => {active => 0}
540 =head1 FILTER ELEMENTS
542 A filter element is stored in and as a hash map. Each filter has a unique key
543 and should have entries for:
549 Is a number after which the elements are ordered. This can be a float.
553 Is shown before the input field.
557 This must be C<input_tag>, C<yes_no_tag> or C<date_tag>. It sets the input type
564 Creates a text input field. The default value of this field is set to the
565 C<input_default> entry of the filter element. C<input_name> is used to set the
566 name of the field, which should match the filter syntax.
570 Creates a yes/no input field. The default value of this field is set to the
571 C<input_default> entry of the filter element. C<input_name> is used to set the
572 name of the field, which should match the filter syntax.
576 Creates two date input fields. One filters for after the date and the other
577 filters for before the date. The default values of these fields are set to the
578 C<input_default_ge> and C<input_default_le> entries of the filter element.
579 C<input_name> is used to set the names of these fields, which should match the
580 filter syntax. For the first field ":date::ge" and for the second ":date::le" is
581 added to the end of C<input_name>.
587 Is used to generate the id of the check box after the input field. The value of
588 the check box can be found in the form under
589 C<$::form-E<gt>{'active_in_report'}-E<gt>{report_id}>.
593 If falsish the element is ignored.
595 =item * input_name, input_default, input_default_ge, input_default_le
597 Look at I<input_tag> to see how they are used.
607 Tamino Steinert E<lt>tamino.steinert@tamino.stE<gt>