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 (-553 / +59 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 146-383 if ($op eq ""){ Link Here
146
    my @import_record_id_selected = $input->multi_param("import_record_id");
147
    my @import_record_id_selected = $input->multi_param("import_record_id");
147
    my $matcher_id = $input->param('matcher_id');
148
    my $matcher_id = $input->param('matcher_id');
148
    my $active_currency = Koha::Acquisition::Currencies->get_active;
149
    my $active_currency = Koha::Acquisition::Currencies->get_active;
149
    my $biblio_count = 0;
150
    while( my $import_record = $import_records->next ){
150
    while( my $import_record = $import_records->next ){
151
        $biblio_count++;
151
        my $marcrecord        = $import_record->get_marc_record || die "couldn't translate marc information";
152
        my $duplifound = 0;
152
        my @homebranches      = $input->multi_param( 'homebranch_' . $import_record->import_record_id );
153
        # Check if this import_record_id was selected
153
        my @holdingbranches   = $input->multi_param( 'holdingbranch_' . $import_record->import_record_id );
154
        next if not grep { $_ eq $import_record->import_record_id } @import_record_id_selected;
154
        my @itypes            = $input->multi_param( 'itype_' . $import_record->import_record_id );
155
        my $marcrecord = $import_record->get_marc_record || die "couldn't translate marc information";
155
        my @nonpublic_notes   = $input->multi_param( 'nonpublic_note_' . $import_record->import_record_id );
156
        my $matches = $import_record->get_import_record_matches({ chosen => 1 });
156
        my @public_notes      = $input->multi_param( 'public_note_' . $import_record->import_record_id );
157
        my $match = $matches->count ? $matches->next : undef;
157
        my @locs              = $input->multi_param( 'loc_' . $import_record->import_record_id );
158
        my $biblionumber = $match ? $match->candidate_match_id : 0;
158
        my @ccodes            = $input->multi_param( 'ccode_' . $import_record->import_record_id );
159
        my $c_quantity =
159
        my @notforloans       = $input->multi_param( 'notforloan_' . $import_record->import_record_id );
160
               $input->param( 'quantity_' . $import_record->import_record_id )
160
        my @uris              = $input->multi_param( 'uri_' . $import_record->import_record_id );
161
            || GetMarcQuantity( $marcrecord, C4::Context->preference('marcflavour') )
161
        my @copynos           = $input->multi_param( 'copyno_' . $import_record->import_record_id );
162
            || 1;
162
        my @budget_codes      = $input->multi_param( 'budget_code_' . $import_record->import_record_id );
163
        my $c_budget_id =
164
               $input->param( 'budget_id_' . $import_record->import_record_id )
165
            || $input->param('all_budget_id')
166
            || $budget_id;
167
        my $c_discount = $input->param( 'discount_' . $import_record->import_record_id );
168
        my $c_sort1 = $input->param( 'sort1_' . $import_record->import_record_id ) || $input->param('all_sort1') || '';
169
        my $c_sort2 = $input->param( 'sort2_' . $import_record->import_record_id ) || $input->param('all_sort2') || '';
170
        my $c_replacement_price = $input->param( 'replacementprice_' . $import_record->import_record_id );
171
        my $c_price             = $input->param( 'price_' . $import_record->import_record_id )
172
            || GetMarcPrice( $marcrecord, C4::Context->preference('marcflavour') );
173
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 );
163
        my @itemprices        = $input->multi_param( 'itemprice_' . $import_record->import_record_id );
230
        my @replacementprices = $input->multi_param( 'replacementprice_' . $import_record->import_record_id );
164
        my @replacementprices = $input->multi_param( 'replacementprice_' . $import_record->import_record_id );
231
        my @itemcallnumbers   = $input->multi_param( 'itemcallnumber_' . $import_record->import_record_id );
165
        my @itemcallnumbers   = $input->multi_param( 'itemcallnumber_' . $import_record->import_record_id );
232
        my @coded_location_qualifiers =
233
            $input->multi_param( 'coded_location_qualifier_' . $import_record->import_record_id );
234
        my @barcodes     = $input->multi_param( 'barcode_' . $import_record->import_record_id );
235
        my @enumchrons   = $input->multi_param( 'enumchron_' . $import_record->import_record_id );
236
        my $itemcreation = 0;
237
238
        my @itemnumbers;
239
        for (my $i = 0; $i < $count; $i++) {
240
            $itemcreation = 1;
241
            my $item = Koha::Item->new(
242
                {
243
                    biblionumber             => $biblionumber,
244
                    homebranch               => $homebranches[$i],
245
                    holdingbranch            => $holdingbranches[$i],
246
                    itemnotes_nonpublic      => $nonpublic_notes[$i],
247
                    itemnotes                => $public_notes[$i],
248
                    location                 => $locs[$i],
249
                    ccode                    => $ccodes[$i],
250
                    itype                    => $itypes[$i],
251
                    notforloan               => $notforloans[$i],
252
                    uri                      => $uris[$i],
253
                    copynumber               => $copynos[$i],
254
                    price                    => $itemprices[$i],
255
                    replacementprice         => $replacementprices[$i],
256
                    itemcallnumber           => $itemcallnumbers[$i],
257
                    coded_location_qualifier => $coded_location_qualifiers[$i],
258
                    barcode                  => $barcodes[$i],
259
                    enumchron                => $enumchrons[$i],
260
                }
261
            )->store;
262
            push( @itemnumbers, $item->itemnumber );
263
        }
264
        if ($itemcreation == 1) {
265
            # Group orderlines from MarcItemFieldsToOrder
266
            my $budget_hash;
267
            for (my $i = 0; $i < $count; $i++) {
268
                $budget_ids[$i] = $budget_id if !$budget_ids[$i];   # Use default budget if no budget selected in the UI
269
                $budget_hash->{ $budget_ids[$i] }->{quantity} += 1;
270
                $budget_hash->{ $budget_ids[$i] }->{price} = $itemprices[$i];
271
                $budget_hash->{ $budget_ids[$i] }->{replacementprice} =
272
                  $replacementprices[$i];
273
                $budget_hash->{ $budget_ids[$i] }->{itemnumbers} //= [];
274
                push @{ $budget_hash->{ $budget_ids[$i] }->{itemnumbers} },
275
                  $itemnumbers[$i];
276
            }
277
278
            # Create orderlines from MarcItemFieldsToOrder
279
            while(my ($budget_id, $infos) = each %$budget_hash) {
280
                if ($budget_id) {
281
                    my %orderinfo = (
282
                        biblionumber       => $biblionumber,
283
                        basketno           => $cgiparams->{'basketno'},
284
                        quantity           => $infos->{quantity},
285
                        budget_id          => $budget_id,
286
                        currency           => $cgiparams->{'all_currency'},
287
                    );
288
289
                    my $price = $infos->{price};
290
                    if ($price){
291
                        # in France, the cents separator is the , but sometimes, ppl use a .
292
                        # in this case, the price will be x100 when unformatted ! Replace the . by a , to get a proper price calculation
293
                        $price =~ s/\./,/ if C4::Context->preference("CurrencyFormat") eq "FR";
294
                        $price = Koha::Number::Price->new($price)->unformat;
295
                        $orderinfo{tax_rate_on_ordering} = $bookseller->tax_rate;
296
                        $orderinfo{tax_rate_on_receiving} = $bookseller->tax_rate;
297
                        my $order_discount = $c_discount ? $c_discount : $bookseller->discount;
298
                        $orderinfo{discount} = $order_discount;
299
                        $orderinfo{rrp} = $price;
300
                        $orderinfo{ecost} = $order_discount ? $price * ( 1 - $order_discount / 100 ) : $price;
301
                        $orderinfo{listprice} = $orderinfo{rrp} / $active_currency->rate;
302
                        $orderinfo{unitprice} = $orderinfo{ecost};
303
                        $orderinfo{sort1} = $c_sort1;
304
                        $orderinfo{sort2} = $c_sort2;
305
                    } else {
306
                        $orderinfo{listprice} = 0;
307
                    }
308
                    $orderinfo{replacementprice} = $infos->{replacementprice} || 0;
309
166
310
                    # remove uncertainprice flag if we have found a price in the MARC record
167
        my $client_item_fields = {
311
                    $orderinfo{uncertainprice} = 0 if $orderinfo{listprice};
168
            homebranches      => \@homebranches,
169
            holdingbranches   => \@holdingbranches,
170
            itypes            => \@itypes,
171
            nonpublic_notes   => \@nonpublic_notes,
172
            public_notes      => \@public_notes,
173
            locs              => \@locs,
174
            ccodes            => \@ccodes,
175
            notforloans       => \@notforloans,
176
            uris              => \@uris,
177
            copynos           => \@copynos,
178
            budget_codes      => \@budget_codes,
179
            itemprices        => \@itemprices,
180
            replacementprices => \@replacementprices,
181
            itemcallnumbers   => \@itemcallnumbers,
182
            c_quantity        => shift(@quantities)
183
                || GetMarcQuantity( $marcrecord, C4::Context->preference('marcflavour') )
184
                || 1,
185
            c_budget_id         => shift(@budgets_id) || $input->param('all_budget_id') || $budget_id,
186
            c_discount          => shift(@discount),
187
            c_sort1             => shift(@sort1) || $input->param('all_sort1') || '',
188
            c_sort2             => shift(@sort2) || $input->param('all_sort2') || '',
189
            c_replacement_price => shift(@orderreplacementprices),
190
            c_price => shift(@prices) || GetMarcPrice( $marcrecord, C4::Context->preference('marcflavour') ),
191
        };
192
193
        my $args = {
194
            import_batch_id           => $import_batch_id,
195
            import_record             => $import_record,
196
            matcher_id                => $matcher_id,
197
            overlay_action            => $overlay_action,
198
            agent                     => 'client',
199
            import_record_id_selected => \@import_record_id_selected,
200
            client_item_fields        => $client_item_fields,
201
            basket_id                 => $cgiparams->{'basketno'},
202
            vendor                    => $bookseller,
203
            budget_id                 => $budget_id,
204
        };
205
        my $result = Koha::MarcOrder->import_record_and_create_order_lines($args);
206
207
        $duplinbatch = $result->{duplicates_in_batch} if $result->{duplicates_in_batch};
208
        next if $result->{skip};    # If a duplicate is found, or the import record wasn't selected it will be skipped
312
209
313
                    my $order = Koha::Acquisition::Order->new( \%orderinfo );
314
                    $order->populate_with_prices_for_ordering();
315
                    $order->populate_with_prices_for_receiving();
316
                    $order->store;
317
                    $order->add_item( $_ ) for @{ $budget_hash->{$budget_id}->{itemnumbers} };
318
                }
319
            }
320
        } else {
321
            # 3rd add order
322
            my $patron = Koha::Patrons->find( $loggedinuser );
323
            # get quantity in the MARC record (1 if none)
324
            my $quantity = GetMarcQuantity($marcrecord, C4::Context->preference('marcflavour')) || 1;
325
            my %orderinfo = (
326
                biblionumber       => $biblionumber,
327
                basketno           => $cgiparams->{'basketno'},
328
                quantity           => $c_quantity,
329
                branchcode         => $patron->branchcode,
330
                budget_id          => $c_budget_id,
331
                uncertainprice     => 1,
332
                sort1              => $c_sort1,
333
                sort2              => $c_sort2,
334
                order_internalnote => $cgiparams->{'all_order_internalnote'},
335
                order_vendornote   => $cgiparams->{'all_order_vendornote'},
336
                currency           => $cgiparams->{'all_currency'},
337
                replacementprice   => $c_replacement_price,
338
            );
339
            # get the price if there is one.
340
            if ($c_price){
341
                # in France, the cents separator is the , but sometimes, ppl use a .
342
                # in this case, the price will be x100 when unformatted ! Replace the . by a , to get a proper price calculation
343
                $c_price =~ s/\./,/ if C4::Context->preference("CurrencyFormat") eq "FR";
344
                $c_price = Koha::Number::Price->new($c_price)->unformat;
345
                $orderinfo{tax_rate_on_ordering} = $bookseller->tax_rate;
346
                $orderinfo{tax_rate_on_receiving} = $bookseller->tax_rate;
347
                my $order_discount = $c_discount ? $c_discount : $bookseller->discount;
348
                $orderinfo{discount} = $order_discount;
349
                $orderinfo{rrp}   = $c_price;
350
                $orderinfo{ecost} = $order_discount ? $c_price * ( 1 - $order_discount / 100 ) : $c_price;
351
                $orderinfo{listprice} = $orderinfo{rrp} / $active_currency->rate;
352
                $orderinfo{unitprice} = $orderinfo{ecost};
353
            } else {
354
                $orderinfo{listprice} = 0;
355
            }
356
357
            # remove uncertainprice flag if we have found a price in the MARC record
358
            $orderinfo{uncertainprice} = 0 if $orderinfo{listprice};
359
360
            my $order = Koha::Acquisition::Order->new( \%orderinfo );
361
            $order->populate_with_prices_for_ordering();
362
            $order->populate_with_prices_for_receiving();
363
            $order->store;
364
365
            # 4th, add items if applicable
366
            # parse the item sent by the form, and create an item just for the import_record_id we are dealing with
367
            # this is not optimised, but it's working !
368
            if ( $basket->effective_create_items eq 'ordering' && !$basket->is_standing ) {
369
                my @tags         = $input->multi_param('tag');
370
                my @subfields    = $input->multi_param('subfield');
371
                my @field_values = $input->multi_param('field_value');
372
                my @serials      = $input->multi_param('serial');
373
                my $xml = TransformHtmlToXml( \@tags, \@subfields, \@field_values );
374
                my $record = MARC::Record::new_from_xml( $xml, 'UTF-8' );
375
                for (my $qtyloop=1;$qtyloop <= $c_quantity;$qtyloop++) {
376
                    my ( $biblionumber, undef, $itemnumber ) = AddItemFromMarc( $record, $biblionumber );
377
                    $order->add_item( $itemnumber );
378
                }
379
            }
380
        }
381
        $imported++;
210
        $imported++;
382
    }
211
    }
383
212
Lines 423-747 foreach my $r ( @{$budgets_hierarchy} ) { Link Here
423
$template->param( budget_loop    => $budget_loop,);
252
$template->param( budget_loop    => $budget_loop,);
424
253
425
output_html_with_http_headers $input, $cookie, $template->output;
254
output_html_with_http_headers $input, $cookie, $template->output;
426
427
428
sub import_batches_list {
429
    my ($template) = @_;
430
    my $batches = GetImportBatchRangeDesc();
431
432
    my @list = ();
433
    foreach my $batch (@$batches) {
434
        if ( $batch->{'import_status'} =~ /^staged$|^reverted$/ && $batch->{'record_type'} eq 'biblio') {
435
            # check if there is at least 1 line still staged
436
            my $import_records_count = Koha::Import::Records->search({
437
                import_batch_id => $batch->{'import_batch_id'},
438
                status          => $batch->{import_status}
439
            })->count;
440
            if ( $import_records_count ) {
441
                push @list, {
442
                        import_batch_id => $batch->{'import_batch_id'},
443
                        num_records => $batch->{'num_records'},
444
                        num_items => $batch->{'num_items'},
445
                        staged_date => $batch->{'upload_timestamp'},
446
                        import_status => $batch->{'import_status'},
447
                        file_name => $batch->{'file_name'},
448
                        comments => $batch->{'comments'},
449
                };
450
            } else {
451
                # if there are no more line to includes, set the status to imported
452
                # FIXME This should be removed in the future.
453
                SetImportBatchStatus( $batch->{'import_batch_id'}, 'imported' );
454
            }
455
        }
456
    }
457
    $template->param(batch_list => \@list); 
458
    my $num_batches = GetNumberOfNonZ3950ImportBatches();
459
    $template->param(num_results => $num_batches);
460
}
461
462
sub import_biblios_list {
463
    my ($template, $import_batch_id) = @_;
464
    my $batch = GetImportBatch($import_batch_id,'staged');
465
    return () unless $batch and $batch->{import_status} =~ /^staged$|^reverted$/;
466
    my $import_records = Koha::Import::Records->search({
467
        import_batch_id => $import_batch_id,
468
        status => $batch->{import_status}
469
    });
470
    my @list = ();
471
    my $item_error = 0;
472
473
    my $ccodes = { map { $_->{authorised_value} => $_->{opac_description} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => '', kohafield => 'items.ccode' } ) };
474
    my $locations = { map { $_->{authorised_value} => $_->{opac_description} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => '', kohafield => 'items.location' } ) };
475
    my $notforloans = { map { $_->{authorised_value} => $_->{lib} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => '', kohafield => 'items.notforloan' } ) };
476
    # location list
477
    my @locations;
478
    foreach (sort keys %$locations) {
479
        push @locations, { code => $_, description => "$_ - " . $locations->{$_} };
480
    }
481
    my @ccodes;
482
    foreach (sort {$ccodes->{$a} cmp $ccodes->{$b}} keys %$ccodes) {
483
        push @ccodes, { code => $_, description => $ccodes->{$_} };
484
    }
485
    my @notforloans;
486
    foreach (sort {$notforloans->{$a} cmp $notforloans->{$b}} keys %$notforloans) {
487
        push @notforloans, { code => $_, description => $notforloans->{$_} };
488
    }
489
490
    my $biblio_count = 0;
491
    while ( my $import_record = $import_records->next ) {
492
        my $item_id = 1;
493
        $biblio_count++;
494
        my $matches = $import_record->get_import_record_matches({ chosen => 1 });
495
        my $match = $matches->count ? $matches->next : undef;
496
        my $match_biblio = $match ? Koha::Biblios->find({ biblionumber => $match->candidate_match_id }) : undef;
497
        my %cellrecord = (
498
            import_record_id => $import_record->import_record_id,
499
            import_biblio => $import_record->import_biblio,
500
            import  => 1,
501
            status => $import_record->status,
502
            record_sequence => $import_record->record_sequence,
503
            overlay_status => $import_record->overlay_status,
504
            match_biblionumber => $match ? $match->candidate_match_id : 0,
505
            match_citation     => $match_biblio ? ($match_biblio->title || '') . ' ' .( $match_biblio->author || ''): '',
506
            match_score => $match ? $match->score : 0,
507
        );
508
        my $marcrecord = $import_record->get_marc_record || die "couldn't translate marc information";
509
510
        my $infos = get_infos_syspref('MarcFieldsToOrder', $marcrecord, ['price', 'quantity', 'budget_code', 'discount', 'sort1', 'sort2','replacementprice']);
511
        my $price = $infos->{price};
512
        my $replacementprice = $infos->{replacementprice};
513
        my $quantity = $infos->{quantity};
514
        my $budget_code = $infos->{budget_code};
515
        my $discount = $infos->{discount};
516
        my $sort1 = $infos->{sort1};
517
        my $sort2 = $infos->{sort2};
518
        my $budget_id;
519
520
        if ($budget_code) {
521
            my $biblio_budget = GetBudgetByCode($budget_code);
522
            if ($biblio_budget) {
523
                $budget_id = $biblio_budget->{budget_id};
524
            }
525
        }
526
527
        # Items
528
        my @itemlist = ();
529
        my $all_items_quantity = 0;
530
        my $alliteminfos = get_marc_item_fields_to_order($marcrecord);
531
        if ($alliteminfos != -1) {
532
            foreach my $iteminfos (@$alliteminfos) {
533
                # Quantity is required, default to one if not supplied
534
                my $quantity = delete $iteminfos->{quantity} || 1;
535
536
                # Handle incorrectly named original parameters for MarcItemFieldsToOrder
537
                $iteminfos->{location}   = delete $iteminfos->{loc}    if $iteminfos->{loc};
538
                $iteminfos->{copynumber} = delete $iteminfos->{copyno} if $iteminfos->{copyno};
539
                # Price is handled as "itemprice" in the UI form to distinguish from MarcFieldsToOrder
540
                $iteminfos->{itemprice}  = delete $iteminfos->{price}  if $iteminfos->{price};
541
542
                # Convert budge code to a budget id
543
                my $item_budget_code = delete $iteminfos->{budget_code};
544
                if ( $item_budget_code ) {
545
                    my $item_budget = GetBudgetByCode( $item_budget_code );
546
                    $iteminfos->{budget_id} = $item_budget->{budget_id} || $budget_id;
547
                }
548
549
                # Clone the item data for the needed quantity
550
                # Add the incremented item id for each item in that quantity
551
                for (my $i = 0; $i < $quantity; $i++) {
552
                    my $itemrecord = { %$iteminfos };
553
                    $itemrecord->{item_id} = $item_id++;
554
                    $all_items_quantity++;
555
                    push @itemlist, $itemrecord;
556
                }
557
            }
558
559
            $cellrecord{'iteminfos'} = \@itemlist;
560
        } else {
561
            $cellrecord{'item_error'} = 1;
562
        }
563
        push @list, \%cellrecord;
564
565
        # If MarcItemFieldsToOrder is not set, we use MarcFieldsToOrder to populate the order form.
566
        if ($alliteminfos == -1 || scalar(@$alliteminfos) == 0) {
567
            $cellrecord{price} = $price || '';
568
            $cellrecord{replacementprice} = $replacementprice || '';
569
            $cellrecord{quantity} = $quantity || '';
570
            $cellrecord{budget_id} = $budget_id || '';
571
        } else {
572
            # When using MarcItemFields to order we want the order to have the same quantity as total items
573
            $cellrecord{quantity} = $all_items_quantity;
574
        }
575
        # The fields discount, sort1, and sort2 only exist at the order level, so always use MarcItemFieldsToOrder
576
        $cellrecord{discount} = $discount || '';
577
        $cellrecord{sort1} = $sort1 || '';
578
        $cellrecord{sort2} = $sort2 || '';
579
580
    }
581
    my $num_records = $batch->{'num_records'};
582
    my $overlay_action = GetImportBatchOverlayAction($import_batch_id);
583
    my $nomatch_action = GetImportBatchNoMatchAction($import_batch_id);
584
    my $item_action = GetImportBatchItemAction($import_batch_id);
585
    $template->param(import_biblio_list => \@list,
586
                        num_results => $num_records,
587
                        import_batch_id => $import_batch_id,
588
                        "overlay_action_${overlay_action}" => 1,
589
                        overlay_action => $overlay_action,
590
                        "nomatch_action_${nomatch_action}" => 1,
591
                        nomatch_action => $nomatch_action,
592
                        "item_action_${item_action}" => 1,
593
                        item_action => $item_action,
594
                        item_error => $item_error,
595
                        libraries => Koha::Libraries->search,
596
                        locationloop => \@locations,
597
                        itemtypes => Koha::ItemTypes->search,
598
                        ccodeloop => \@ccodes,
599
                        notforloanloop => \@notforloans,
600
                    );
601
    batch_info($template, $batch);
602
}
603
604
sub batch_info {
605
    my ($template, $batch) = @_;
606
    $template->param(batch_info => 1,
607
                                      file_name => $batch->{'file_name'},
608
                                          comments => $batch->{'comments'},
609
                                          import_status => $batch->{'import_status'},
610
                                          upload_timestamp => $batch->{'upload_timestamp'},
611
                                          num_records => $batch->{'num_records'},
612
                                          num_items => $batch->{'num_items'});
613
    if ($batch->{'num_records'} > 0) {
614
        if ($batch->{'import_status'} eq 'staged' or $batch->{'import_status'} eq 'reverted') {
615
            $template->param(can_commit => 1);
616
        }
617
        if ($batch->{'import_status'} eq 'imported') {
618
            $template->param(can_revert => 1);
619
        }
620
    }
621
    if (defined $batch->{'matcher_id'}) {
622
        my $matcher = C4::Matcher->fetch($batch->{'matcher_id'});
623
        if (defined $matcher) {
624
            $template->param('current_matcher_id' => $batch->{'matcher_id'},
625
                                              'current_matcher_code' => $matcher->code(),
626
                                              'current_matcher_description' => $matcher->description());
627
        }
628
    }
629
    add_matcher_list($batch->{'matcher_id'}, $template);
630
}
631
632
sub add_matcher_list {
633
    my ($current_matcher_id, $template) = @_;
634
    my @matchers = C4::Matcher::GetMatcherList();
635
    if (defined $current_matcher_id) {
636
        for (my $i = 0; $i <= $#matchers; $i++) {
637
            if ($matchers[$i]->{'matcher_id'} == $current_matcher_id) {
638
                $matchers[$i]->{'selected'} = 1;
639
            }
640
        }
641
    }
642
    $template->param(available_matchers => \@matchers);
643
}
644
645
sub get_infos_syspref {
646
    my ($syspref_name, $record, $field_list) = @_;
647
    my $syspref = C4::Context->preference($syspref_name);
648
    $syspref = "$syspref\n\n"; # YAML is anal on ending \n. Surplus does not hurt
649
    my $yaml = eval {
650
        YAML::XS::Load(Encode::encode_utf8($syspref));
651
    };
652
    if ( $@ ) {
653
        warn "Unable to parse $syspref syspref : $@";
654
        return ();
655
    }
656
    my $r;
657
    for my $field_name ( @$field_list ) {
658
        next unless exists $yaml->{$field_name};
659
        my @fields = split /\|/, $yaml->{$field_name};
660
        for my $field ( @fields ) {
661
            my ( $f, $sf ) = split /\$/, $field;
662
            next unless $f and $sf;
663
            if ( my $v = $record->subfield( $f, $sf ) ) {
664
                $r->{$field_name} = $v;
665
            }
666
            last if $yaml->{$field};
667
        }
668
    }
669
    return $r;
670
}
671
672
sub equal_number_of_fields {
673
    my ($tags_list, $record) = @_;
674
    my $tag_fields_count;
675
    for my $tag (@$tags_list) {
676
        my @fields = $record->field($tag);
677
        $tag_fields_count->{$tag} = scalar @fields;
678
    }
679
680
    my $tags_count;
681
    foreach my $key ( keys %$tag_fields_count ) {
682
        if ( $tag_fields_count->{$key} > 0 ) { # Having 0 of a field is ok
683
            $tags_count //= $tag_fields_count->{$key}; # Start with the count from the first occurrence
684
            return -1 if $tag_fields_count->{$key} != $tags_count; # All counts of various fields should be equal if they exist
685
        }
686
    }
687
688
    return $tags_count;
689
}
690
691
sub get_marc_item_fields_to_order {
692
    my ($record) = @_;
693
694
    my $syspref = C4::Context->preference('MarcItemFieldsToOrder');
695
    $syspref = "$syspref\n\n"; # YAML is anal on ending \n. Surplus does not hurt
696
    my $yaml = eval {
697
        YAML::XS::Load(Encode::encode_utf8($syspref));
698
    };
699
    if ( $@ ) {
700
        warn "Unable to parse $syspref syspref : $@";
701
        return ();
702
    }
703
704
    my @result;
705
    my @tags_list;
706
707
    # Check tags in syspref definition
708
    for my $field_name ( keys %$yaml ) {
709
        my @fields = split /\|/, $yaml->{$field_name};
710
        for my $field ( @fields ) {
711
            my ( $f, $sf ) = split /\$/, $field;
712
            next unless $f and $sf;
713
            push @tags_list, $f;
714
        }
715
    }
716
    @tags_list = List::MoreUtils::uniq(@tags_list);
717
718
    my $tags_count = equal_number_of_fields(\@tags_list, $record);
719
    # Return if the number of these fields in the record is not the same.
720
    return -1 if $tags_count == -1;
721
722
    # Gather the fields
723
    my $fields_hash;
724
    foreach my $tag (@tags_list) {
725
        my @tmp_fields;
726
        foreach my $field ($record->field($tag)) {
727
            push @tmp_fields, $field;
728
        }
729
        $fields_hash->{$tag} = \@tmp_fields;
730
    }
731
732
    for (my $i = 0; $i < $tags_count; $i++) {
733
        my $r;
734
        for my $field_name ( keys %$yaml ) {
735
            my @fields = split /\|/, $yaml->{$field_name};
736
            for my $field ( @fields ) {
737
                my ( $f, $sf ) = split /\$/, $field;
738
                next unless $f and $sf;
739
                my $v = $fields_hash->{$f}[$i] ? $fields_hash->{$f}[$i]->subfield( $sf ) : undef;
740
                $r->{$field_name} = $v if (defined $v);
741
                last if $yaml->{$field};
742
            }
743
        }
744
        push @result, $r;
745
    }
746
    return \@result;
747
}
748
- 

Return to bug 35026