View | Details | Raw Unified | Return to bug 35026
Collapse All | Expand All

(-)a/Koha/MarcOrder.pm (-2 / +31 lines)
Lines 661-666 sub create_order_lines { Link Here
661
    return;
661
    return;
662
}
662
}
663
663
664
=head3 import_batches_list
665
666
Fetches import batches matching the batch to be added to the basket and adds these to the $template
667
668
Koha::MarcOrder->import_batches_list($template);
669
670
=cut
671
664
sub import_batches_list {
672
sub import_batches_list {
665
    my ( $self, $template ) = @_;
673
    my ( $self, $template ) = @_;
666
    my $batches = GetImportBatchRangeDesc();
674
    my $batches = GetImportBatchRangeDesc();
Lines 699-704 sub import_batches_list { Link Here
699
    $template->param( num_results => $num_batches );
707
    $template->param( num_results => $num_batches );
700
}
708
}
701
709
710
=head3
711
712
For an import batch, this function reads the files and creates all the relevant data pertaining to that file
713
It then passes this to the $template variable to be shown in the UI
714
715
Koha::MarcOrder->import_biblios_list( $template, $cgiparams->{'import_batch_id'} );
716
717
=cut
718
702
sub import_biblios_list {
719
sub import_biblios_list {
703
    my ( $self, $template, $import_batch_id ) = @_;
720
    my ( $self, $template, $import_batch_id ) = @_;
704
    my $batch = GetImportBatch( $import_batch_id, 'staged' );
721
    my $batch = GetImportBatch( $import_batch_id, 'staged' );
Lines 797-803 sub import_biblios_list { Link Here
797
                'uri',        'copyno',        'price', 'replacementprice', 'itemcallnumber', 'quantity', 'budget_code'
814
                'uri',        'copyno',        'price', 'replacementprice', 'itemcallnumber', 'quantity', 'budget_code'
798
            ]
815
            ]
799
        );
816
        );
800
        if ( %$alliteminfos != -1 ) {
817
        if ( !$alliteminfos || %$alliteminfos != -1 ) {
801
            my $item_homebranch     = $alliteminfos->{homebranch};
818
            my $item_homebranch     = $alliteminfos->{homebranch};
802
            my $item_holdingbranch  = $alliteminfos->{holdingbranch};
819
            my $item_holdingbranch  = $alliteminfos->{holdingbranch};
803
            my $item_itype          = $alliteminfos->{itype};
820
            my $item_itype          = $alliteminfos->{itype};
Lines 855-861 sub import_biblios_list { Link Here
855
        push @list, \%cellrecord;
872
        push @list, \%cellrecord;
856
873
857
        # If MarcItemFieldsToOrder is not set, we use MarcFieldsToOrder to populate the order form.
874
        # If MarcItemFieldsToOrder is not set, we use MarcFieldsToOrder to populate the order form.
858
        if ( %$alliteminfos == -1 ) {
875
        if ( $alliteminfos || %$alliteminfos == -1 ) {
859
            $cellrecord{price}            = $price            || '';
876
            $cellrecord{price}            = $price            || '';
860
            $cellrecord{replacementprice} = $replacementprice || '';
877
            $cellrecord{replacementprice} = $replacementprice || '';
861
            $cellrecord{quantity}         = $quantity         || '';
878
            $cellrecord{quantity}         = $quantity         || '';
Lines 896-901 sub import_biblios_list { Link Here
896
    _batch_info( $template, $batch );
913
    _batch_info( $template, $batch );
897
}
914
}
898
915
916
=head3
917
918
Creates a hash of information to be used about an import batch in the template
919
920
=cut
921
899
sub _batch_info {
922
sub _batch_info {
900
    my ( $template, $batch ) = @_;
923
    my ( $template, $batch ) = @_;
901
    $template->param(
924
    $template->param(
Lines 928-933 sub _batch_info { Link Here
928
    _add_matcher_list( $batch->{'matcher_id'}, $template );
951
    _add_matcher_list( $batch->{'matcher_id'}, $template );
929
}
952
}
930
953
954
=head3
955
956
Adds a list of available matchers based on an import batch
957
958
=cut
959
931
sub _add_matcher_list {
960
sub _add_matcher_list {
932
    my ( $current_matcher_id, $template ) = @_;
961
    my ( $current_matcher_id, $template ) = @_;
933
    my @matchers = C4::Matcher::GetMatcherList();
962
    my @matchers = C4::Matcher::GetMatcherList();
(-)a/acqui/addorderiso2709.pl (-541 / +63 lines)
Lines 30-36 use Encode; Link Here
30
use C4::Context;
30
use C4::Context;
31
use C4::Auth qw( get_template_and_user );
31
use C4::Auth qw( get_template_and_user );
32
use C4::Output qw( output_html_with_http_headers );
32
use C4::Output qw( output_html_with_http_headers );
33
use C4::ImportBatch qw( SetImportBatchStatus GetImportBatch GetImportBatchRangeDesc GetNumberOfNonZ3950ImportBatches GetImportBatchOverlayAction GetImportBatchNoMatchAction GetImportBatchItemAction );
33
use C4::ImportBatch qw( SetImportBatchStatus );
34
use C4::Matcher;
34
use C4::Matcher;
35
use C4::Search qw( FindDuplicate );
35
use C4::Search qw( FindDuplicate );
36
use C4::Biblio qw(
36
use C4::Biblio qw(
Lines 41-47 use C4::Biblio qw( Link Here
41
    TransformHtmlToXml
41
    TransformHtmlToXml
42
);
42
);
43
use C4::Items qw( PrepareItemrecordDisplay AddItemFromMarc );
43
use C4::Items qw( PrepareItemrecordDisplay AddItemFromMarc );
44
use C4::Budgets qw( GetBudget GetBudgets GetBudgetHierarchy CanUserUseBudget GetBudgetByCode );
44
use C4::Budgets qw( GetBudget GetBudgets GetBudgetHierarchy CanUserUseBudget );
45
use C4::Suggestions;    # GetSuggestion
45
use C4::Suggestions;    # GetSuggestion
46
use C4::Members;
46
use C4::Members;
47
47
Lines 54-59 use Koha::Acquisition::Booksellers; Link Here
54
use Koha::ImportBatches;
54
use Koha::ImportBatches;
55
use Koha::Import::Records;
55
use Koha::Import::Records;
56
use Koha::Patrons;
56
use Koha::Patrons;
57
use Koha::MarcOrder;
57
58
58
my $input = CGI->new;
59
my $input = CGI->new;
59
my ($template, $loggedinuser, $cookie, $userflags) = get_template_and_user({
60
my ($template, $loggedinuser, $cookie, $userflags) = get_template_and_user({
Lines 90-96 my $basket = Koha::Acquisition::Baskets->find( $cgiparams->{basketno} ); Link Here
90
if ($op eq ""){
91
if ($op eq ""){
91
    $template->param("basketno" => $cgiparams->{'basketno'});
92
    $template->param("basketno" => $cgiparams->{'basketno'});
92
#display batches
93
#display batches
93
    import_batches_list($template);
94
    Koha::MarcOrder->import_batches_list($template);
94
#
95
#
95
# 2nd step = display the content of the chosen file
96
# 2nd step = display the content of the chosen file
96
#
97
#
Lines 104-110 if ($op eq ""){ Link Here
104
                     bookseller => $bookseller,
105
                     bookseller => $bookseller,
105
                     "allmatch" => $allmatch,
106
                     "allmatch" => $allmatch,
106
                     );
107
                     );
107
    import_biblios_list($template, $cgiparams->{'import_batch_id'});
108
    Koha::MarcOrder->import_biblios_list($template, $cgiparams->{'import_batch_id'});
108
    if ( $basket->effective_create_items eq 'ordering' && !$basket->is_standing ) {
109
    if ( $basket->effective_create_items eq 'ordering' && !$basket->is_standing ) {
109
        # prepare empty item form
110
        # prepare empty item form
110
        my $cell = PrepareItemrecordDisplay( '', '', undef, 'ACQ' );
111
        my $cell = PrepareItemrecordDisplay( '', '', undef, 'ACQ' );
Lines 153-376 if ($op eq ""){ Link Here
153
    my @sort2 = $input->multi_param('sort2');
154
    my @sort2 = $input->multi_param('sort2');
154
    my $matcher_id = $input->param('matcher_id');
155
    my $matcher_id = $input->param('matcher_id');
155
    my $active_currency = Koha::Acquisition::Currencies->get_active;
156
    my $active_currency = Koha::Acquisition::Currencies->get_active;
156
    my $biblio_count = 0;
157
    while( my $import_record = $import_records->next ){
157
    while( my $import_record = $import_records->next ){
158
        $biblio_count++;
158
        my $marcrecord        = $import_record->get_marc_record || die "couldn't translate marc information";
159
        my $duplifound = 0;
159
        my @homebranches      = $input->multi_param( 'homebranch_' . $import_record->import_record_id );
160
        # Check if this import_record_id was selected
160
        my @holdingbranches   = $input->multi_param( 'holdingbranch_' . $import_record->import_record_id );
161
        next if not grep { $_ eq $import_record->import_record_id } @import_record_id_selected;
161
        my @itypes            = $input->multi_param( 'itype_' . $import_record->import_record_id );
162
        my $marcrecord = $import_record->get_marc_record || die "couldn't translate marc information";
162
        my @nonpublic_notes   = $input->multi_param( 'nonpublic_note_' . $import_record->import_record_id );
163
        my $matches = $import_record->get_import_record_matches({ chosen => 1 });
163
        my @public_notes      = $input->multi_param( 'public_note_' . $import_record->import_record_id );
164
        my $match = $matches->count ? $matches->next : undef;
164
        my @locs              = $input->multi_param( 'loc_' . $import_record->import_record_id );
165
        my $biblionumber = $match ? $match->candidate_match_id : 0;
165
        my @ccodes            = $input->multi_param( 'ccode_' . $import_record->import_record_id );
166
        my $c_quantity = shift( @quantities ) || GetMarcQuantity($marcrecord, C4::Context->preference('marcflavour') ) || 1;
166
        my @notforloans       = $input->multi_param( 'notforloan_' . $import_record->import_record_id );
167
        my $c_budget_id = shift( @budgets_id ) || $input->param('all_budget_id') || $budget_id;
167
        my @uris              = $input->multi_param( 'uri_' . $import_record->import_record_id );
168
        my $c_discount = shift ( @discount);
168
        my @copynos           = $input->multi_param( 'copyno_' . $import_record->import_record_id );
169
        my $c_sort1 = shift( @sort1 ) || $input->param('all_sort1') || '';
169
        my @budget_codes      = $input->multi_param( 'budget_code_' . $import_record->import_record_id );
170
        my $c_sort2 = shift( @sort2 ) || $input->param('all_sort2') || '';
170
        my @itemprices        = $input->multi_param( 'itemprice_' . $import_record->import_record_id );
171
        my $c_replacement_price = shift( @orderreplacementprices );
171
        my @replacementprices = $input->multi_param( 'replacementprice_' . $import_record->import_record_id );
172
        my $c_price = shift( @prices ) || GetMarcPrice($marcrecord, C4::Context->preference('marcflavour'));
172
        my @itemcallnumbers   = $input->multi_param( 'itemcallnumber_' . $import_record->import_record_id );
173
174
        my $client_item_fields = {
175
            homebranches      => \@homebranches,
176
            holdingbranches   => \@holdingbranches,
177
            itypes            => \@itypes,
178
            nonpublic_notes   => \@nonpublic_notes,
179
            public_notes      => \@public_notes,
180
            locs              => \@locs,
181
            ccodes            => \@ccodes,
182
            notforloans       => \@notforloans,
183
            uris              => \@uris,
184
            copynos           => \@copynos,
185
            budget_codes      => \@budget_codes,
186
            itemprices        => \@itemprices,
187
            replacementprices => \@replacementprices,
188
            itemcallnumbers   => \@itemcallnumbers,
189
            c_quantity        => shift(@quantities)
190
                || GetMarcQuantity( $marcrecord, C4::Context->preference('marcflavour') )
191
                || 1,
192
            c_budget_id         => shift(@budgets_id) || $input->param('all_budget_id') || $budget_id,
193
            c_discount          => shift(@discount),
194
            c_sort1             => shift(@sort1) || $input->param('all_sort1') || '',
195
            c_sort2             => shift(@sort2) || $input->param('all_sort2') || '',
196
            c_replacement_price => shift(@orderreplacementprices),
197
            c_price => shift(@prices) || GetMarcPrice( $marcrecord, C4::Context->preference('marcflavour') ),
198
        };
199
200
        my $args = {
201
            import_batch_id           => $import_batch_id,
202
            import_record             => $import_record,
203
            matcher_id                => $matcher_id,
204
            overlay_action            => $overlay_action,
205
            agent                     => 'client',
206
            import_record_id_selected => \@import_record_id_selected,
207
            client_item_fields        => $client_item_fields,
208
            basket_id                 => $cgiparams->{'basketno'},
209
            vendor                    => $bookseller,
210
            budget_id                 => $budget_id,
211
        };
212
        my $result = Koha::MarcOrder->import_record_and_create_order_lines($args);
213
214
        $duplinbatch = $result->{duplicates_in_batch} if $result->{duplicates_in_batch};
215
        next if $result->{skip};    # If a duplicate is found, or the import record wasn't selected it will be skipped
173
216
174
        # Insert the biblio, or find it through matcher
175
        if ( $biblionumber ) { # If matched during staging we can continue
176
            $import_record->status('imported')->store;
177
            if( $overlay_action eq 'replace' ){
178
                my $biblio = Koha::Biblios->find( $biblionumber );
179
                $import_record->replace({ biblio => $biblio });
180
            }
181
        } else { # Otherwise we check for duplicates, and skip if they exist
182
            if ($matcher_id) {
183
                if ( $matcher_id eq '_TITLE_AUTHOR_' ) {
184
                    $duplifound = 1 if FindDuplicate($marcrecord);
185
                }
186
                else {
187
                    my $matcher = C4::Matcher->fetch($matcher_id);
188
                    my @matches = $matcher->get_matches( $marcrecord, my $max_matches = 1 );
189
                    $duplifound = 1 if @matches;
190
                }
191
192
                $duplinbatch = $import_batch_id and next if $duplifound;
193
            }
194
195
            # remove hyphens (-) from ISBN
196
            # FIXME: This should probably be optional
197
            my ( $isbnfield, $isbnsubfield ) = GetMarcFromKohaField( 'biblioitems.isbn' );
198
            if ( $marcrecord->field($isbnfield) ) {
199
                foreach my $field ( $marcrecord->field($isbnfield) ) {
200
                    foreach my $subfield ( $field->subfield($isbnsubfield) ) {
201
                        my $newisbn = $field->subfield($isbnsubfield);
202
                        $newisbn =~ s/-//g;
203
                        $field->update( $isbnsubfield => $newisbn );
204
                    }
205
                }
206
            }
207
208
            # add the biblio
209
            ( $biblionumber, undef ) = AddBiblio( $marcrecord, $cgiparams->{'frameworkcode'} || '' );
210
            $import_record->status('imported')->store;
211
        }
212
213
        $import_record->import_biblio->matched_biblionumber($biblionumber)->store;
214
215
        # Add items from MarcItemFieldsToOrder
216
        my @homebranches = $input->multi_param('homebranch_' . $import_record->import_record_id);
217
        my $count = scalar @homebranches;
218
        my @holdingbranches = $input->multi_param('holdingbranch_' . $import_record->import_record_id);
219
        my @itypes = $input->multi_param('itype_' . $import_record->import_record_id);
220
        my @nonpublic_notes = $input->multi_param('nonpublic_note_' . $import_record->import_record_id);
221
        my @public_notes = $input->multi_param('public_note_' . $import_record->import_record_id);
222
        my @locs = $input->multi_param('loc_' . $import_record->import_record_id);
223
        my @ccodes = $input->multi_param('ccode_' . $import_record->import_record_id);
224
        my @notforloans = $input->multi_param('notforloan_' . $import_record->import_record_id);
225
        my @uris = $input->multi_param('uri_' . $import_record->import_record_id);
226
        my @copynos = $input->multi_param('copyno_' . $import_record->import_record_id);
227
        my @budget_ids =
228
            $input->multi_param( 'budget_code_' . $import_record->import_record_id ); # bad field name used in template!
229
        my @itemprices = $input->multi_param('itemprice_' . $import_record->import_record_id);
230
        my @replacementprices = $input->multi_param('replacementprice_' . $import_record->import_record_id);
231
        my @itemcallnumbers = $input->multi_param('itemcallnumber_' . $import_record->import_record_id);
232
        my $itemcreation = 0;
233
234
        my @itemnumbers;
235
        for (my $i = 0; $i < $count; $i++) {
236
            $itemcreation = 1;
237
            my $item = Koha::Item->new(
238
                {
239
                    biblionumber        => $biblionumber,
240
                    homebranch          => $homebranches[$i],
241
                    holdingbranch       => $holdingbranches[$i],
242
                    itemnotes_nonpublic => $nonpublic_notes[$i],
243
                    itemnotes           => $public_notes[$i],
244
                    location            => $locs[$i],
245
                    ccode               => $ccodes[$i],
246
                    itype               => $itypes[$i],
247
                    notforloan          => $notforloans[$i],
248
                    uri                 => $uris[$i],
249
                    copynumber          => $copynos[$i],
250
                    price               => $itemprices[$i],
251
                    replacementprice    => $replacementprices[$i],
252
                    itemcallnumber      => $itemcallnumbers[$i],
253
                }
254
            )->store;
255
            push( @itemnumbers, $item->itemnumber );
256
        }
257
        if ($itemcreation == 1) {
258
            # Group orderlines from MarcItemFieldsToOrder
259
            my $budget_hash;
260
            for (my $i = 0; $i < $count; $i++) {
261
                $budget_ids[$i] = $budget_id if !$budget_ids[$i];   # Use default budget if no budget selected in the UI
262
                $budget_hash->{ $budget_ids[$i] }->{quantity} += 1;
263
                $budget_hash->{ $budget_ids[$i] }->{price} = $itemprices[$i];
264
                $budget_hash->{ $budget_ids[$i] }->{replacementprice} =
265
                  $replacementprices[$i];
266
                $budget_hash->{ $budget_ids[$i] }->{itemnumbers} //= [];
267
                push @{ $budget_hash->{ $budget_ids[$i] }->{itemnumbers} },
268
                  $itemnumbers[$i];
269
            }
270
271
            # Create orderlines from MarcItemFieldsToOrder
272
            while(my ($budget_id, $infos) = each %$budget_hash) {
273
                if ($budget_id) {
274
                    my %orderinfo = (
275
                        biblionumber       => $biblionumber,
276
                        basketno           => $cgiparams->{'basketno'},
277
                        quantity           => $infos->{quantity},
278
                        budget_id          => $budget_id,
279
                        currency           => $cgiparams->{'all_currency'},
280
                    );
281
282
                    my $price = $infos->{price};
283
                    if ($price){
284
                        # in France, the cents separator is the , but sometimes, ppl use a .
285
                        # in this case, the price will be x100 when unformatted ! Replace the . by a , to get a proper price calculation
286
                        $price =~ s/\./,/ if C4::Context->preference("CurrencyFormat") eq "FR";
287
                        $price = Koha::Number::Price->new($price)->unformat;
288
                        $orderinfo{tax_rate_on_ordering} = $bookseller->tax_rate;
289
                        $orderinfo{tax_rate_on_receiving} = $bookseller->tax_rate;
290
                        my $order_discount = $c_discount ? $c_discount : $bookseller->discount;
291
                        $orderinfo{discount} = $order_discount;
292
                        $orderinfo{rrp} = $price;
293
                        $orderinfo{ecost} = $order_discount ? $price * ( 1 - $order_discount / 100 ) : $price;
294
                        $orderinfo{listprice} = $orderinfo{rrp} / $active_currency->rate;
295
                        $orderinfo{unitprice} = $orderinfo{ecost};
296
                        $orderinfo{sort1} = $c_sort1;
297
                        $orderinfo{sort2} = $c_sort2;
298
                    } else {
299
                        $orderinfo{listprice} = 0;
300
                    }
301
                    $orderinfo{replacementprice} = $infos->{replacementprice} || 0;
302
303
                    # remove uncertainprice flag if we have found a price in the MARC record
304
                    $orderinfo{uncertainprice} = 0 if $orderinfo{listprice};
305
306
                    my $order = Koha::Acquisition::Order->new( \%orderinfo );
307
                    $order->populate_with_prices_for_ordering();
308
                    $order->populate_with_prices_for_receiving();
309
                    $order->store;
310
                    $order->add_item( $_ ) for @{ $budget_hash->{$budget_id}->{itemnumbers} };
311
                }
312
            }
313
        } else {
314
            # 3rd add order
315
            my $patron = Koha::Patrons->find( $loggedinuser );
316
            # get quantity in the MARC record (1 if none)
317
            my $quantity = GetMarcQuantity($marcrecord, C4::Context->preference('marcflavour')) || 1;
318
            my %orderinfo = (
319
                biblionumber       => $biblionumber,
320
                basketno           => $cgiparams->{'basketno'},
321
                quantity           => $c_quantity,
322
                branchcode         => $patron->branchcode,
323
                budget_id          => $c_budget_id,
324
                uncertainprice     => 1,
325
                sort1              => $c_sort1,
326
                sort2              => $c_sort2,
327
                order_internalnote => $cgiparams->{'all_order_internalnote'},
328
                order_vendornote   => $cgiparams->{'all_order_vendornote'},
329
                currency           => $cgiparams->{'all_currency'},
330
                replacementprice   => $c_replacement_price,
331
            );
332
            # get the price if there is one.
333
            if ($c_price){
334
                # in France, the cents separator is the , but sometimes, ppl use a .
335
                # in this case, the price will be x100 when unformatted ! Replace the . by a , to get a proper price calculation
336
                $c_price =~ s/\./,/ if C4::Context->preference("CurrencyFormat") eq "FR";
337
                $c_price = Koha::Number::Price->new($c_price)->unformat;
338
                $orderinfo{tax_rate_on_ordering} = $bookseller->tax_rate;
339
                $orderinfo{tax_rate_on_receiving} = $bookseller->tax_rate;
340
                my $order_discount = $c_discount ? $c_discount : $bookseller->discount;
341
                $orderinfo{discount} = $order_discount;
342
                $orderinfo{rrp}   = $c_price;
343
                $orderinfo{ecost} = $order_discount ? $c_price * ( 1 - $order_discount / 100 ) : $c_price;
344
                $orderinfo{listprice} = $orderinfo{rrp} / $active_currency->rate;
345
                $orderinfo{unitprice} = $orderinfo{ecost};
346
            } else {
347
                $orderinfo{listprice} = 0;
348
            }
349
350
            # remove uncertainprice flag if we have found a price in the MARC record
351
            $orderinfo{uncertainprice} = 0 if $orderinfo{listprice};
352
353
            my $order = Koha::Acquisition::Order->new( \%orderinfo );
354
            $order->populate_with_prices_for_ordering();
355
            $order->populate_with_prices_for_receiving();
356
            $order->store;
357
358
            # 4th, add items if applicable
359
            # parse the item sent by the form, and create an item just for the import_record_id we are dealing with
360
            # this is not optimised, but it's working !
361
            if ( $basket->effective_create_items eq 'ordering' && !$basket->is_standing ) {
362
                my @tags         = $input->multi_param('tag');
363
                my @subfields    = $input->multi_param('subfield');
364
                my @field_values = $input->multi_param('field_value');
365
                my @serials      = $input->multi_param('serial');
366
                my $xml = TransformHtmlToXml( \@tags, \@subfields, \@field_values );
367
                my $record = MARC::Record::new_from_xml( $xml, 'UTF-8' );
368
                for (my $qtyloop=1;$qtyloop <= $c_quantity;$qtyloop++) {
369
                    my ( $biblionumber, undef, $itemnumber ) = AddItemFromMarc( $record, $biblionumber );
370
                    $order->add_item( $itemnumber );
371
                }
372
            }
373
        }
374
        $imported++;
217
        $imported++;
375
    }
218
    }
376
219
Lines 416-738 foreach my $r ( @{$budgets_hierarchy} ) { Link Here
416
$template->param( budget_loop    => $budget_loop,);
259
$template->param( budget_loop    => $budget_loop,);
417
260
418
output_html_with_http_headers $input, $cookie, $template->output;
261
output_html_with_http_headers $input, $cookie, $template->output;
419
420
421
sub import_batches_list {
422
    my ($template) = @_;
423
    my $batches = GetImportBatchRangeDesc();
424
425
    my @list = ();
426
    foreach my $batch (@$batches) {
427
        if ( $batch->{'import_status'} =~ /^staged$|^reverted$/ && $batch->{'record_type'} eq 'biblio') {
428
            # check if there is at least 1 line still staged
429
            my $import_records_count = Koha::Import::Records->search({
430
                import_batch_id => $batch->{'import_batch_id'},
431
                status          => $batch->{import_status}
432
            })->count;
433
            if ( $import_records_count ) {
434
                push @list, {
435
                        import_batch_id => $batch->{'import_batch_id'},
436
                        num_records => $batch->{'num_records'},
437
                        num_items => $batch->{'num_items'},
438
                        staged_date => $batch->{'upload_timestamp'},
439
                        import_status => $batch->{'import_status'},
440
                        file_name => $batch->{'file_name'},
441
                        comments => $batch->{'comments'},
442
                };
443
            } else {
444
                # if there are no more line to includes, set the status to imported
445
                # FIXME This should be removed in the future.
446
                SetImportBatchStatus( $batch->{'import_batch_id'}, 'imported' );
447
            }
448
        }
449
    }
450
    $template->param(batch_list => \@list); 
451
    my $num_batches = GetNumberOfNonZ3950ImportBatches();
452
    $template->param(num_results => $num_batches);
453
}
454
455
sub import_biblios_list {
456
    my ($template, $import_batch_id) = @_;
457
    my $batch = GetImportBatch($import_batch_id,'staged');
458
    return () unless $batch and $batch->{import_status} =~ /^staged$|^reverted$/;
459
    my $import_records = Koha::Import::Records->search({
460
        import_batch_id => $import_batch_id,
461
        status => $batch->{import_status}
462
    });
463
    my @list = ();
464
    my $item_error = 0;
465
466
    my $ccodes = { map { $_->{authorised_value} => $_->{opac_description} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => '', kohafield => 'items.ccode' } ) };
467
    my $locations = { map { $_->{authorised_value} => $_->{opac_description} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => '', kohafield => 'items.location' } ) };
468
    my $notforloans = { map { $_->{authorised_value} => $_->{lib} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => '', kohafield => 'items.notforloan' } ) };
469
    # location list
470
    my @locations;
471
    foreach (sort keys %$locations) {
472
        push @locations, { code => $_, description => "$_ - " . $locations->{$_} };
473
    }
474
    my @ccodes;
475
    foreach (sort {$ccodes->{$a} cmp $ccodes->{$b}} keys %$ccodes) {
476
        push @ccodes, { code => $_, description => $ccodes->{$_} };
477
    }
478
    my @notforloans;
479
    foreach (sort {$notforloans->{$a} cmp $notforloans->{$b}} keys %$notforloans) {
480
        push @notforloans, { code => $_, description => $notforloans->{$_} };
481
    }
482
483
    my $biblio_count = 0;
484
    while ( my $import_record = $import_records->next ) {
485
        my $item_id = 1;
486
        $biblio_count++;
487
        my $matches = $import_record->get_import_record_matches({ chosen => 1 });
488
        my $match = $matches->count ? $matches->next : undef;
489
        my $match_biblio = $match ? Koha::Biblios->find({ biblionumber => $match->candidate_match_id }) : undef;
490
        my %cellrecord = (
491
            import_record_id => $import_record->import_record_id,
492
            import_biblio => $import_record->import_biblio,
493
            import  => 1,
494
            status => $import_record->status,
495
            record_sequence => $import_record->record_sequence,
496
            overlay_status => $import_record->overlay_status,
497
            match_biblionumber => $match ? $match->candidate_match_id : 0,
498
            match_citation     => $match_biblio ? ($match_biblio->title || '') . ' ' .( $match_biblio->author || ''): '',
499
            match_score => $match ? $match->score : 0,
500
        );
501
        my $marcrecord = $import_record->get_marc_record || die "couldn't translate marc information";
502
503
        my $infos = get_infos_syspref('MarcFieldsToOrder', $marcrecord, ['price', 'quantity', 'budget_code', 'discount', 'sort1', 'sort2','replacementprice']);
504
        my $price = $infos->{price};
505
        my $replacementprice = $infos->{replacementprice};
506
        my $quantity = $infos->{quantity};
507
        my $budget_code = $infos->{budget_code};
508
        my $discount = $infos->{discount};
509
        my $sort1 = $infos->{sort1};
510
        my $sort2 = $infos->{sort2};
511
        my $budget_id;
512
513
        if ($budget_code) {
514
            my $biblio_budget = GetBudgetByCode($budget_code);
515
            if ($biblio_budget) {
516
                $budget_id = $biblio_budget->{budget_id};
517
            }
518
        }
519
520
        # Items
521
        my @itemlist = ();
522
        my $all_items_quantity = 0;
523
        my $alliteminfos = get_marc_item_fields_to_order($marcrecord);
524
        if ($alliteminfos != -1) {
525
            foreach my $iteminfos (@$alliteminfos) {
526
                # Quantity is required, default to one if not supplied
527
                my $quantity = delete $iteminfos->{quantity} || 1;
528
529
                # Handle incorrectly named original parameters for MarcItemFieldsToOrder
530
                $iteminfos->{location}   = delete $iteminfos->{loc}    if $iteminfos->{loc};
531
                $iteminfos->{copynumber} = delete $iteminfos->{copyno} if $iteminfos->{copyno};
532
533
                # Convert budge code to a budget id
534
                my $item_budget_code = delete $iteminfos->{budget_code};
535
                if ( $item_budget_code ) {
536
                    my $item_budget = GetBudgetByCode( $item_budget_code );
537
                    $iteminfos->{budget_id} = $item_budget->{budget_id} || $budget_id;
538
                }
539
540
                # Clone the item data for the needed quantity
541
                # Add the incremented item id for each item in that quantity
542
                for (my $i = 0; $i < $quantity; $i++) {
543
                    my $itemrecord = { %$iteminfos };
544
                    $itemrecord->{item_id} = $item_id++;
545
                    $all_items_quantity++;
546
                    push @itemlist, $itemrecord;
547
                }
548
            }
549
550
            $cellrecord{'iteminfos'} = \@itemlist;
551
        } else {
552
            $cellrecord{'item_error'} = 1;
553
        }
554
        push @list, \%cellrecord;
555
556
        # If MarcItemFieldsToOrder is not set, we use MarcFieldsToOrder to populate the order form.
557
        if ($alliteminfos == -1 || scalar(@$alliteminfos) == 0) {
558
            $cellrecord{price} = $price || '';
559
            $cellrecord{replacementprice} = $replacementprice || '';
560
            $cellrecord{quantity} = $quantity || '';
561
            $cellrecord{budget_id} = $budget_id || '';
562
        } else {
563
            # When using MarcItemFields to order we want the order to have the same quantity as total items
564
            $cellrecord{quantity} = $all_items_quantity;
565
        }
566
        # The fields discount, sort1, and sort2 only exist at the order level, so always use MarcItemFieldsToOrder
567
        $cellrecord{discount} = $discount || '';
568
        $cellrecord{sort1} = $sort1 || '';
569
        $cellrecord{sort2} = $sort2 || '';
570
571
    }
572
    my $num_records = $batch->{'num_records'};
573
    my $overlay_action = GetImportBatchOverlayAction($import_batch_id);
574
    my $nomatch_action = GetImportBatchNoMatchAction($import_batch_id);
575
    my $item_action = GetImportBatchItemAction($import_batch_id);
576
    $template->param(import_biblio_list => \@list,
577
                        num_results => $num_records,
578
                        import_batch_id => $import_batch_id,
579
                        "overlay_action_${overlay_action}" => 1,
580
                        overlay_action => $overlay_action,
581
                        "nomatch_action_${nomatch_action}" => 1,
582
                        nomatch_action => $nomatch_action,
583
                        "item_action_${item_action}" => 1,
584
                        item_action => $item_action,
585
                        item_error => $item_error,
586
                        libraries => Koha::Libraries->search,
587
                        locationloop => \@locations,
588
                        itemtypes => Koha::ItemTypes->search,
589
                        ccodeloop => \@ccodes,
590
                        notforloanloop => \@notforloans,
591
                    );
592
    batch_info($template, $batch);
593
}
594
595
sub batch_info {
596
    my ($template, $batch) = @_;
597
    $template->param(batch_info => 1,
598
                                      file_name => $batch->{'file_name'},
599
                                          comments => $batch->{'comments'},
600
                                          import_status => $batch->{'import_status'},
601
                                          upload_timestamp => $batch->{'upload_timestamp'},
602
                                          num_records => $batch->{'num_records'},
603
                                          num_items => $batch->{'num_items'});
604
    if ($batch->{'num_records'} > 0) {
605
        if ($batch->{'import_status'} eq 'staged' or $batch->{'import_status'} eq 'reverted') {
606
            $template->param(can_commit => 1);
607
        }
608
        if ($batch->{'import_status'} eq 'imported') {
609
            $template->param(can_revert => 1);
610
        }
611
    }
612
    if (defined $batch->{'matcher_id'}) {
613
        my $matcher = C4::Matcher->fetch($batch->{'matcher_id'});
614
        if (defined $matcher) {
615
            $template->param('current_matcher_id' => $batch->{'matcher_id'},
616
                                              'current_matcher_code' => $matcher->code(),
617
                                              'current_matcher_description' => $matcher->description());
618
        }
619
    }
620
    add_matcher_list($batch->{'matcher_id'}, $template);
621
}
622
623
sub add_matcher_list {
624
    my ($current_matcher_id, $template) = @_;
625
    my @matchers = C4::Matcher::GetMatcherList();
626
    if (defined $current_matcher_id) {
627
        for (my $i = 0; $i <= $#matchers; $i++) {
628
            if ($matchers[$i]->{'matcher_id'} == $current_matcher_id) {
629
                $matchers[$i]->{'selected'} = 1;
630
            }
631
        }
632
    }
633
    $template->param(available_matchers => \@matchers);
634
}
635
636
sub get_infos_syspref {
637
    my ($syspref_name, $record, $field_list) = @_;
638
    my $syspref = C4::Context->preference($syspref_name);
639
    $syspref = "$syspref\n\n"; # YAML is anal on ending \n. Surplus does not hurt
640
    my $yaml = eval {
641
        YAML::XS::Load(Encode::encode_utf8($syspref));
642
    };
643
    if ( $@ ) {
644
        warn "Unable to parse $syspref syspref : $@";
645
        return ();
646
    }
647
    my $r;
648
    for my $field_name ( @$field_list ) {
649
        next unless exists $yaml->{$field_name};
650
        my @fields = split /\|/, $yaml->{$field_name};
651
        for my $field ( @fields ) {
652
            my ( $f, $sf ) = split /\$/, $field;
653
            next unless $f and $sf;
654
            if ( my $v = $record->subfield( $f, $sf ) ) {
655
                $r->{$field_name} = $v;
656
            }
657
            last if $yaml->{$field};
658
        }
659
    }
660
    return $r;
661
}
662
663
sub equal_number_of_fields {
664
    my ($tags_list, $record) = @_;
665
    my $tag_fields_count;
666
    for my $tag (@$tags_list) {
667
        my @fields = $record->field($tag);
668
        $tag_fields_count->{$tag} = scalar @fields;
669
    }
670
671
    my $tags_count;
672
    foreach my $key ( keys %$tag_fields_count ) {
673
        if ( $tag_fields_count->{$key} > 0 ) { # Having 0 of a field is ok
674
            $tags_count //= $tag_fields_count->{$key}; # Start with the count from the first occurrence
675
            return -1 if $tag_fields_count->{$key} != $tags_count; # All counts of various fields should be equal if they exist
676
        }
677
    }
678
679
    return $tags_count;
680
}
681
682
sub get_marc_item_fields_to_order {
683
    my ($record) = @_;
684
685
    my $syspref = C4::Context->preference('MarcItemFieldsToOrder');
686
    $syspref = "$syspref\n\n"; # YAML is anal on ending \n. Surplus does not hurt
687
    my $yaml = eval {
688
        YAML::XS::Load(Encode::encode_utf8($syspref));
689
    };
690
    if ( $@ ) {
691
        warn "Unable to parse $syspref syspref : $@";
692
        return ();
693
    }
694
695
    my @result;
696
    my @tags_list;
697
698
    # Check tags in syspref definition
699
    for my $field_name ( keys %$yaml ) {
700
        my @fields = split /\|/, $yaml->{$field_name};
701
        for my $field ( @fields ) {
702
            my ( $f, $sf ) = split /\$/, $field;
703
            next unless $f and $sf;
704
            push @tags_list, $f;
705
        }
706
    }
707
    @tags_list = List::MoreUtils::uniq(@tags_list);
708
709
    my $tags_count = equal_number_of_fields(\@tags_list, $record);
710
    # Return if the number of these fields in the record is not the same.
711
    return -1 if $tags_count == -1;
712
713
    # Gather the fields
714
    my $fields_hash;
715
    foreach my $tag (@tags_list) {
716
        my @tmp_fields;
717
        foreach my $field ($record->field($tag)) {
718
            push @tmp_fields, $field;
719
        }
720
        $fields_hash->{$tag} = \@tmp_fields;
721
    }
722
723
    for (my $i = 0; $i < $tags_count; $i++) {
724
        my $r;
725
        for my $field_name ( keys %$yaml ) {
726
            my @fields = split /\|/, $yaml->{$field_name};
727
            for my $field ( @fields ) {
728
                my ( $f, $sf ) = split /\$/, $field;
729
                next unless $f and $sf;
730
                my $v = $fields_hash->{$f}[$i] ? $fields_hash->{$f}[$i]->subfield( $sf ) : undef;
731
                $r->{$field_name} = $v if (defined $v);
732
                last if $yaml->{$field};
733
            }
734
        }
735
        push @result, $r;
736
    }
737
    return \@result;
738
}
739
- 

Return to bug 35026