Revision da364d0f
Von Kivitendo Admin vor fast 10 Jahren hinzugefügt
SL/Controller/Helper/ParseFilter.pm | ||
---|---|---|
257 | 257 |
|
258 | 258 |
A search filter will usually search for things in relations of the actual |
259 | 259 |
search target. A search for sales orders may be filtered by the name of the |
260 |
customer. L<Rose::DB::Object> alloes you to search for these by filtering them prefixed with their table:
|
|
260 |
customer. L<Rose::DB::Object> allows you to search for these by filtering them prefixed with their table:
|
|
261 | 261 |
|
262 | 262 |
query => [ |
263 | 263 |
'customer.name' => 'John Doe', |
... | ... | |
265 | 265 |
'orddate' => [ lt => DateTime->today ], |
266 | 266 |
] |
267 | 267 |
|
268 |
Unfortunately, if you specify them in you form as these strings, the form |
|
268 |
Unfortunately, if you specify them in your form as these strings, the form
|
|
269 | 269 |
parser will convert them into nested structures like this: |
270 | 270 |
|
271 | 271 |
$::form = bless { |
... | ... | |
297 | 297 |
|
298 | 298 |
[% L.select_tag('filter.salesman.id', ...) %] |
299 | 299 |
|
300 |
Additionally you can add modifier to the name to set a certain method: |
|
300 |
Additionally you can add a modifier to the name to set a certain method:
|
|
301 | 301 |
|
302 | 302 |
[% L.input_tag('filter.department.description:substr::ilike', ...) %] |
303 | 303 |
|
... | ... | |
313 | 313 |
=head1 LAUNDERING |
314 | 314 |
|
315 | 315 |
Unfortunately Template cannot parse the postfixes if you want to |
316 |
rerender the filter. For this reason all colons filter keys are by
|
|
316 |
rerender the filter. For this reason all colon filter keys are by |
|
317 | 317 |
default laundered into underscores, so you can use them like this: |
318 | 318 |
|
319 | 319 |
[% L.input_tag('filter.price:number::lt', filter.price_number__lt) %] |
... | ... | |
326 | 326 |
All of your original entries will stay intact. If you don't want this to |
327 | 327 |
happen pass C<< no_launder => 1 >> as a parameter. Additionally you can pass a |
328 | 328 |
different target for the laundered values with the C<launder_to> parameter. It |
329 |
takes an hashref and will deep copy all values in your filter to the target. So
|
|
329 |
takes a hashref and will deep copy all values in your filter to the target. So |
|
330 | 330 |
if you have a filter that looks like this: |
331 | 331 |
|
332 | 332 |
$filter = { |
... | ... | |
382 | 382 |
] |
383 | 383 |
] |
384 | 384 |
|
385 |
For more abuot custom filters, see L<SL::DB::Helper::Filtered>.
|
|
385 |
For more about custom filters, see L<SL::DB::Helper::Filtered>.
|
|
386 | 386 |
|
387 | 387 |
=head1 FILTERS (leading with :) |
388 | 388 |
|
... | ... | |
450 | 450 |
L.input_tag('customer.name:substr::ilike', ...) |
451 | 451 |
L.input_tag('invoice.customer.name:substr::ilike', ...) |
452 | 452 |
|
453 |
This will sarch for orders whose invoice has the _same_ customer, which matches |
|
453 |
This will search for orders whose invoice has the _same_ customer, which matches
|
|
454 | 454 |
both inputs. This is because tables are aliased by their name and not by their |
455 | 455 |
position in with_objects. |
456 | 456 |
|
... | ... | |
460 | 460 |
|
461 | 461 |
=item * |
462 | 462 |
|
463 |
Additional filters shoud be pluggable. |
|
463 |
Additional filters should be pluggable.
|
|
464 | 464 |
|
465 | 465 |
=back |
466 | 466 |
|
SL/DBUtils.pm | ||
---|---|---|
389 | 389 |
|
390 | 390 |
=head1 NAME |
391 | 391 |
|
392 |
SL::DBUTils.pm: All about Databaseconections in Lx
|
|
392 |
SL::DBUTils.pm: All about database connections in kivitendo
|
|
393 | 393 |
|
394 | 394 |
=head1 SYNOPSIS |
395 | 395 |
|
... | ... | |
422 | 422 |
|
423 | 423 |
DBUtils relies heavily on two parameters which have to be passed to almost every function: $form and $dbh. |
424 | 424 |
- $form is used for error handling only. It can be omitted in theory, but should not. |
425 |
- $dbh is a handle to the databe, as returned by the DBI::connect routine. If you don't have an active connectiong, you can query $form->get_standard_dbh() to get a generic no_auto connection. Don't forget to commit in this case!
|
|
425 |
- $dbh is a handle to the database, as returned by the DBI::connect routine. If you don't have an active connection, you can query $form->get_standard_dbh() to get a generic no_auto connection. Don't forget to commit in this case!
|
|
426 | 426 |
|
427 | 427 |
|
428 | 428 |
Every function here should accomplish the follwing things: |
SL/Helper/Csv.pm | ||
---|---|---|
119 | 119 |
0, |
120 | 120 |
0]) unless $info_ok; |
121 | 121 |
|
122 |
# If header is given, there need to be a header for each profile |
|
122 |
# If header is given, there needs to be a header for each profile
|
|
123 | 123 |
# and no empty headers. |
124 | 124 |
if ($info_ok && $self->header) { |
125 | 125 |
my @header = @{ $self->header }; |
... | ... | |
195 | 195 |
# people insist that case sensitivity doesn't exist and try to enter all |
196 | 196 |
# sorts of stuff. at this point we've got a profile (with keys that represent |
197 | 197 |
# valid methods), and a header full of strings. if two of them match, the user |
198 |
# mopst likely meant that field, so rewrite the header
|
|
198 |
# most likely meant that field, so rewrite the header |
|
199 | 199 |
if ($self->case_insensitive_header) { |
200 | 200 |
die 'case_insensitive_header is only possible with profile' unless $self->profile; |
201 | 201 |
if ($header) { |
... | ... | |
221 | 221 |
sub _check_multiplex_datatype_position { |
222 | 222 |
my ($self) = @_; |
223 | 223 |
|
224 |
return 1 if !$self->is_multiplexed; # ok if if not multiplexed
|
|
224 |
return 1 if !$self->is_multiplexed; # ok if not multiplexed |
|
225 | 225 |
|
226 | 226 |
my @positions = map { firstidx { 'datatype' eq lc($_) } @{ $_ } } @{ $self->header }; |
227 | 227 |
my $first_pos = $positions[0]; |
... | ... | |
368 | 368 |
|
369 | 369 |
See Synopsis. |
370 | 370 |
|
371 |
Text::CSV offeres already good functions to get lines out of a csv file, but in
|
|
372 |
most cases you will want those line to be parsed into hashes or even objects, |
|
371 |
Text::CSV already offers good functions to get lines out of a csv file, but in
|
|
372 |
most cases you will want those lines to be parsed into hashes or even objects,
|
|
373 | 373 |
so this model just skips ahead and gives you objects. |
374 | 374 |
|
375 | 375 |
Its basic assumptions are: |
... | ... | |
378 | 378 |
|
379 | 379 |
=item You do know what you expect to be in that csv file. |
380 | 380 |
|
381 |
This means first and foremost you have knowledge about encoding, number and |
|
381 |
This means first and foremost that you have knowledge about encoding, number and
|
|
382 | 382 |
date format, csv parameters such as quoting and separation characters. You also |
383 | 383 |
know what content will be in that csv and what L<Rose::DB> is responsible for |
384 | 384 |
it. You provide valid header columns and their mapping to the objects. |
... | ... | |
493 | 493 |
In this case C<listprice_as_number> will be used to read in values from the |
494 | 494 |
C<listprice> column. |
495 | 495 |
|
496 |
In case of a One-To-One relationsship these can also be set over
|
|
497 |
relationsships by sparating the steps with a dot (C<.>). This will work:
|
|
496 |
In case of a One-To-One relationship these can also be set over |
|
497 |
relationships by separating the steps with a dot (C<.>). This will work:
|
|
498 | 498 |
|
499 | 499 |
[ {profile => { customer => 'customer.name' }} ] |
500 | 500 |
|
Auch abrufbar als: Unified diff
Typos in Doku