3 #script to show display basket of orders
4 #written by chris@katipo.co.nz 24/2/2000
6 # Copyright 2000-2002 Katipo Communications
8 # This file is part of Koha.
10 # Koha is free software; you can redistribute it and/or modify it
11 # under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 3 of the License, or
13 # (at your option) any later version.
15 # Koha is distributed in the hope that it will be useful, but
16 # WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with Koha; if not, see <http://www.gnu.org/licenses>.
30 this script allows to create a new record to order it. This record shouldn't exist
38 the bookseller the librarian has to buy a new book.
41 the title of this new record.
44 the author of this new record.
46 =item publication year
47 the publication year of this new record.
50 the number of this order.
55 the basket number for this new order.
58 if this order comes from a suggestion.
61 the item's id in the breeding reservoir
78 use C4
::Suggestions
; # GetSuggestion
79 use C4
::Biblio
; # GetBiblioData GetMarcPrice
80 use C4
::Items
; #PrepareItemRecord
84 use C4
::Search qw
/FindDuplicate/;
86 #needed for z3950 import:
87 use C4
::ImportBatch qw
/GetImportRecordMarc SetImportRecordStatus/;
89 use Koha
::Acquisition
::Booksellers
;
90 use Koha
::Acquisition
::Currencies
;
91 use Koha
::BiblioFrameworks
;
92 use Koha
::DateUtils
qw( dt_from_string );
93 use Koha
::MarcSubfieldStructures
;
96 use Koha
::RecordProcessor
;
99 my $booksellerid = $input->param('booksellerid'); # FIXME: else ERROR!
100 my $budget_id = $input->param('budget_id') || 0;
101 my $title = $input->param('title');
102 my $author = $input->param('author');
103 my $publicationyear = $input->param('publicationyear');
104 my $ordernumber = $input->param('ordernumber') || '';
105 our $biblionumber = $input->param('biblionumber');
106 our $basketno = $input->param('basketno');
107 my $suggestionid = $input->param('suggestionid');
108 my $close = $input->param('close');
109 my $uncertainprice = $input->param('uncertainprice');
110 my $import_batch_id = $input->param('import_batch_id'); # if this is filled, we come from a staged file, and we will return here after saving the order !
111 my $subscriptionid = $input->param('subscriptionid');
117 our ( $template, $loggedinuser, $cookie, $userflags ) = get_template_and_user
(
119 template_name
=> "acqui/neworderempty.tt",
122 authnotrequired
=> 0,
123 flagsrequired
=> { acquisition
=> 'order_manage' },
128 our $marcflavour = C4
::Context
->preference('marcflavour');
131 my $order = GetOrder
($ordernumber);
132 $basketno = $order->{'basketno'};
135 our $basket = GetBasket
($basketno);
136 my $basketobj = Koha
::Acquisition
::Baskets
->find( $basketno );
137 $booksellerid = $basket->{booksellerid
} unless $booksellerid;
138 my $bookseller = Koha
::Acquisition
::Booksellers
->find( $booksellerid );
140 my $contract = GetContract
({
141 contractnumber
=> $basket->{contractnumber
}
144 #simple parameters reading (all in one :-)
145 our $params = $input->Vars;
146 my $listprice=0; # the price, that can be in MARC record if we have one
147 if ( $ordernumber eq '' and defined $params->{'breedingid'}){
148 #we want to import from the breeding reservoir (from a z3950 search)
149 my ($marcrecord, $encoding) = MARCfindbreeding
($params->{'breedingid'});
150 die("Could not find the selected record in the reservoir, bailing") unless $marcrecord;
152 # Remove all the items (952) from the imported record
153 foreach my $item ($marcrecord->field('952')) {
154 $marcrecord->delete_field($item);
159 ($biblionumber,$duplicatetitle) = FindDuplicate
($marcrecord);
160 if($biblionumber && !$input->param('use_external_source')) {
161 #if duplicate record found and user did not decide yet, first warn user
162 #and let them choose between using a new record or an existing record
163 Load_Duplicate
($duplicatetitle);
166 #from this point: add a new record
167 if (C4
::Context
->preference("BiblioAddsAuthorities")){
168 my $headings_linked=BiblioAutoLink
($marcrecord, $params->{'frameworkcode'});
171 $params->{'frameworkcode'} or $params->{'frameworkcode'} = "";
172 ( $biblionumber, $bibitemnum ) = AddBiblio
( $marcrecord, $params->{'frameworkcode'} );
173 # get the price if there is one.
174 $listprice = GetMarcPrice
($marcrecord, $marcflavour);
175 SetImportRecordStatus
($params->{'breedingid'}, 'imported');
180 my ( @order_user_ids, @order_users, @catalog_details );
181 our $tagslib = GetMarcStructure
(1, 'ACQ', { unsafe
=> 1 } );
182 my ( $itemnumber_tag, $itemnumber_subtag ) = GetMarcFromKohaField
( 'items.itemnumber', 'ACQ' );
183 if ( not $ordernumber ) { # create order
186 if ( $biblionumber ) {
187 $data = GetBiblioData
($biblionumber);
189 # get suggestion fields if applicable. If it's a subscription renewal, then the biblio already exists
190 # otherwise, retrieve suggestion information.
191 elsif ($suggestionid) {
192 $data = GetSuggestion
($suggestionid);
193 $budget_id ||= $data->{'budgetid'} // 0;
196 if ( not $biblionumber and Koha
::BiblioFrameworks
->find('ACQ') ) {
197 #my $acq_mss = Koha::MarcSubfieldStructures->search({ frameworkcode => 'ACQ', tagfield => { '!=' => $itemnumber_tag } });
198 foreach my $tag ( sort keys %{$tagslib} ) {
200 next if $tag eq $itemnumber_tag; # skip items fields
201 foreach my $subfield ( sort keys %{ $tagslib->{$tag} } ) {
202 my $mss = $tagslib->{$tag}{$subfield};
203 next if IsMarcStructureInternal
($mss);
204 next if $mss->{tab
} == -1;
205 my $value = $mss->{defaultvalue
};
207 if ($suggestionid and $mss->{kohafield
}) {
208 # Reading suggestion info if ordering from a suggestion
209 if ( $mss->{kohafield
} eq 'biblio.title' ) {
210 $value = $data->{title
};
212 elsif ( $mss->{kohafield
} eq 'biblio.author' ) {
213 $value = $data->{author
};
215 elsif ( $mss->{kohafield
} eq 'biblioitems.publishercode' ) {
216 $value = $data->{publishercode
};
218 elsif ( $mss->{kohafield
} eq 'biblioitems.editionstatement' ) {
219 $value = $data->{editionstatement
};
221 elsif ( $mss->{kohafield
} eq 'biblioitems.publicationyear' ) {
222 $value = $data->{publicationyear
};
224 elsif ( $mss->{kohafield
} eq 'biblioitems.isbn' ) {
225 $value = $data->{isbn
};
227 elsif ( $mss->{kohafield
} eq 'biblio.seriestitle' ) {
228 $value = $data->{seriestitle
};
232 if ( $value eq '' ) {
234 # get today date & replace <<YYYY>>, <<MM>>, <<DD>> if provided in the default value
235 my $today_dt = dt_from_string
;
236 my $year = $today_dt->strftime('%Y');
237 my $month = $today_dt->strftime('%m');
238 my $day = $today_dt->strftime('%d');
239 $value =~ s/<<YYYY>>/$year/g;
240 $value =~ s/<<MM>>/$month/g;
241 $value =~ s/<<DD>>/$day/g;
243 # And <<USER>> with surname (?)
245 ( C4
::Context
->userenv
246 ? C4
::Context
->userenv->{'surname'}
247 : "superlibrarian" );
248 $value =~ s/<<USER>>/$username/g;
250 push @catalog_details, {
252 subfield
=> $subfield,
253 %$mss, # Do we need plugins support (?)
261 $data = GetOrder
($ordernumber);
262 $biblionumber = $data->{'biblionumber'};
263 $budget_id = $data->{'budget_id'};
265 $basket = GetBasket
( $data->{'basketno'} );
266 $basketno = $basket->{'basketno'};
268 @order_user_ids = GetOrderUsers
($ordernumber);
269 foreach my $order_user_id (@order_user_ids) {
270 # FIXME Could be improved with search -in
271 my $order_patron = Koha
::Patrons
->find( $order_user_id );
272 push @order_users, $order_patron if $order_patron;
277 # - no ordernumber but a biblionumber: from a subscription, from an existing record
278 # - no ordernumber, no biblionumber: from a suggestion, from a new order
279 if ( not $ordernumber or $biblionumber ) {
280 if ( C4
::Context
->preference('UseACQFrameworkForBiblioRecords') ) {
281 my $record = $biblionumber ? GetMarcBiblio
({ biblionumber
=> $biblionumber }) : undef;
282 foreach my $tag ( sort keys %{$tagslib} ) {
284 next if $tag eq $itemnumber_tag; # skip items fields
285 my @fields = $biblionumber ?
$record->field($tag) : ();
286 foreach my $subfield ( sort keys %{ $tagslib->{$tag} } ) {
287 my $mss = $tagslib->{$tag}{$subfield};
288 next if IsMarcStructureInternal
($mss);
289 next if $mss->{tab
} == -1;
290 # We only need to display the values
291 my $value = join '; ', map { $_->subfield( $subfield ) } @fields;
293 push @catalog_details, {
295 subfield
=> $subfield,
305 $template->param( catalog_details
=> \
@catalog_details, );
308 $suggestion = GetSuggestionInfo
($suggestionid) if $suggestionid;
310 my @currencies = Koha
::Acquisition
::Currencies
->search;
311 my $active_currency = Koha
::Acquisition
::Currencies
->get_active;
313 # build bookfund list
314 my $patron = Koha
::Patrons
->find( $loggedinuser )->unblessed;
316 my $budget = GetBudget
($budget_id);
318 my $budget_loop = [];
319 my $budgets = GetBudgetHierarchy
;
320 foreach my $r (@
{$budgets}) {
321 next unless (CanUserUseBudget
($patron, $r, $userflags));
322 if (!defined $r->{budget_amount
} || $r->{budget_amount
} <0) {
325 push @
{$budget_loop}, {
326 b_id
=> $r->{budget_id
},
327 b_txt
=> $r->{budget_name
},
328 b_sort1_authcat
=> $r->{'sort1_authcat'},
329 b_sort2_authcat
=> $r->{'sort2_authcat'},
330 b_active
=> $r->{budget_period_active
},
331 b_sel
=> ( $r->{budget_id
} == $budget_id ) ?
1 : 0,
332 b_level
=> $r->{budget_level
},
337 $budget_id = $data->{'budget_id'};
338 $budget_name = $budget->{'budget_name'};
342 $template->param( sort1
=> $data->{'sort1'} );
343 $template->param( sort2
=> $data->{'sort2'} );
345 if ($basketobj->effective_create_items eq 'ordering' && !$ordernumber) {
346 # Check if ACQ framework exists
347 my $marc = GetMarcStructure
(1, 'ACQ', { unsafe
=> 1 } );
349 $template->param('NoACQframework' => 1);
352 AcqCreateItemOrdering
=> 1,
353 UniqueItemFields
=> C4
::Context
->preference('UniqueItemFields'),
357 # Get the item types list, but only if item_level_itype is YES. Otherwise, it will be in the item, no need to display it in the biblio
359 @itemtypes = Koha
::ItemTypes
->search unless C4
::Context
->preference('item-level_itypes');
361 if ( defined $subscriptionid ) {
362 my $lastOrderReceived = GetLastOrderReceivedFromSubscriptionid
$subscriptionid;
363 if ( defined $lastOrderReceived ) {
364 $budget_id = $lastOrderReceived->{budgetid
};
365 $data->{listprice
} = $lastOrderReceived->{listprice
};
366 $data->{uncertainprice
} = $lastOrderReceived->{uncertainprice
};
367 $data->{tax_rate
} = $lastOrderReceived->{tax_rate_on_ordering
};
368 $data->{discount
} = $lastOrderReceived->{discount
};
369 $data->{rrp
} = $lastOrderReceived->{rrp
};
370 $data->{ecost
} = $lastOrderReceived->{ecost
};
371 $data->{quantity
} = $lastOrderReceived->{quantity
};
372 $data->{unitprice
} = $lastOrderReceived->{unitprice
};
373 $data->{order_internalnote
} = $lastOrderReceived->{order_internalnote
};
374 $data->{order_vendornote
} = $lastOrderReceived->{order_vendornote
};
375 $data->{sort1
} = $lastOrderReceived->{sort1
};
376 $data->{sort2
} = $lastOrderReceived->{sort2
};
378 $basket = GetBasket
( $input->param('basketno') );
382 # Find the items.barcode subfield for barcode validations
383 my (undef, $barcode_subfield) = GetMarcFromKohaField
('items.barcode', '');
388 budget_id
=> $budget_id,
389 budget_name
=> $budget_name
392 # get option values for gist syspref
393 my @gst_values = map {
395 }, split( '\|', C4
::Context
->preference("gist") );
397 my $quantity = $input->param('rr_quantity_to_order') ?
398 $input->param('rr_quantity_to_order') :
403 existing
=> $biblionumber,
404 ordernumber
=> $ordernumber,
405 # basket informations
406 basketno
=> $basketno,
408 basketname
=> $basket->{'basketname'},
409 basketnote
=> $basket->{'note'},
410 booksellerid
=> $basket->{'booksellerid'},
411 basketbooksellernote
=> $basket->{booksellernote
},
412 basketcontractno
=> $basket->{contractnumber
},
413 basketcontractname
=> $contract->{contractname
},
414 creationdate
=> $basket->{creationdate
},
415 authorisedby
=> $basket->{'authorisedby'},
416 authorisedbyname
=> $basket->{'authorisedbyname'},
417 closedate
=> $basket->{'closedate'},
419 suggestionid
=> $suggestion->{suggestionid
},
420 surnamesuggestedby
=> $suggestion->{surnamesuggestedby
},
421 firstnamesuggestedby
=> $suggestion->{firstnamesuggestedby
},
422 biblionumber
=> $biblionumber,
423 uncertainprice
=> $data->{'uncertainprice'},
424 discount_2dp
=> sprintf( "%.2f", $bookseller->discount ) , # for display
425 discount
=> $bookseller->discount,
426 orderdiscount_2dp
=> sprintf( "%.2f", $data->{'discount'} || 0 ),
427 orderdiscount
=> $data->{'discount'},
428 order_internalnote
=> $data->{'order_internalnote'},
429 order_vendornote
=> $data->{'order_vendornote'},
430 listincgst
=> $bookseller->listincgst,
431 invoiceincgst
=> $bookseller->invoiceincgst,
432 name
=> $bookseller->name,
433 cur_active_sym
=> $active_currency->symbol,
434 cur_active
=> $active_currency->currency,
435 currencies
=> \
@currencies,
436 currency
=> $data->{currency
},
437 vendor_currency
=> $bookseller->listprice,
438 orderexists
=> ( $new eq 'yes' ) ?
0 : 1,
439 title
=> $data->{'title'},
440 author
=> $data->{'author'},
441 publicationyear
=> $data->{'publicationyear'} ?
$data->{'publicationyear'} : $data->{'copyrightdate'},
442 editionstatement
=> $data->{'editionstatement'},
443 budget_loop
=> $budget_loop,
444 isbn
=> $data->{'isbn'},
445 ean
=> $data->{'ean'},
446 seriestitle
=> $data->{'seriestitle'},
447 itemtypeloop
=> \
@itemtypes,
448 quantity
=> $quantity,
449 quantityrec
=> $quantity,
450 rrp
=> $data->{'rrp'},
451 gst_values
=> \
@gst_values,
452 tax_rate
=> $data->{tax_rate_on_ordering
} ?
$data->{tax_rate_on_ordering
}+0.0 : $bookseller->tax_rate ?
$bookseller->tax_rate+0.0 : 0,
453 listprice
=> sprintf( "%.2f", $data->{listprice
} || $data->{price
} || $listprice),
454 total
=> sprintf( "%.2f", ($data->{ecost
} || 0) * ($data->{'quantity'} || 0) ),
455 ecost
=> sprintf( "%.2f", $data->{ecost
} || 0),
456 unitprice
=> sprintf( "%.2f", $data->{unitprice
} || 0),
457 publishercode
=> $data->{'publishercode'},
458 barcode_subfield
=> $barcode_subfield,
459 import_batch_id
=> $import_batch_id,
460 subscriptionid
=> $subscriptionid,
461 acqcreate
=> $basketobj->effective_create_items eq "ordering" ?
1 : "",
462 users_ids
=> join(':', @order_user_ids),
463 users
=> \
@order_users,
464 (uc(C4
::Context
->preference("marcflavour"))) => 1
467 output_html_with_http_headers
$input, $cookie, $template->output;
470 =head2 MARCfindbreeding
472 $record = MARCfindbreeding($breedingid);
474 Look up the import record repository for the record with
475 record with id $breedingid. If found, returns the decoded
476 MARC::Record; otherwise, -1 is returned (FIXME).
477 Returns as second parameter the character encoding.
481 sub MARCfindbreeding
{
483 my ($marc, $encoding) = GetImportRecordMarc
($id);
484 # remove the - in isbn, koha store isbn without any -
486 my $record = MARC
::Record
->new_from_usmarc($marc);
487 my ($isbnfield,$isbnsubfield) = GetMarcFromKohaField
('biblioitems.isbn','');
488 if ( $record->field($isbnfield) ) {
489 foreach my $field ( $record->field($isbnfield) ) {
490 foreach my $subfield ( $field->subfield($isbnsubfield) ) {
491 my $newisbn = $field->subfield($isbnsubfield);
493 $field->update( $isbnsubfield => $newisbn );
497 # fix the unimarc 100 coded field (with unicode information)
498 if ($marcflavour eq 'UNIMARC' && $record->subfield(100,'a')) {
499 my $f100a=$record->subfield(100,'a');
500 my $f100 = $record->field(100);
501 my $f100temp = $f100->as_string;
502 $record->delete_field($f100);
503 if ( length($f100temp) > 28 ) {
504 substr( $f100temp, 26, 2, "50" );
505 $f100->update( 'a' => $f100temp );
506 my $f100 = MARC
::Field
->new( '100', '', '', 'a' => $f100temp );
507 $record->insert_fields_ordered($f100);
511 if ( !defined(ref($record)) ) {
515 # normalize author : probably UNIMARC specific...
516 if ( C4
::Context
->preference("z3950NormalizeAuthor")
517 and C4
::Context
->preference("z3950AuthorAuthFields") )
519 my ( $tag, $subfield ) = GetMarcFromKohaField
("biblio.author", '');
522 C4
::Context
->preference("z3950AuthorAuthFields");
523 my @auth_fields = split /,/, $auth_fields;
526 if ( $record->field($tag) ) {
527 foreach my $tmpfield ( $record->field($tag)->subfields ) {
529 my $subfieldcode = shift @
$tmpfield;
530 my $subfieldvalue = shift @
$tmpfield;
532 $field->add_subfields(
533 "$subfieldcode" => $subfieldvalue )
534 if ( $subfieldcode ne $subfield );
538 MARC
::Field
->new( $tag, "", "",
539 $subfieldcode => $subfieldvalue )
540 if ( $subfieldcode ne $subfield );
544 $record->delete_field( $record->field($tag) );
545 foreach my $fieldtag (@auth_fields) {
546 next unless ( $record->field($fieldtag) );
547 my $lastname = $record->field($fieldtag)->subfield('a');
548 my $firstname = $record->field($fieldtag)->subfield('b');
549 my $title = $record->field($fieldtag)->subfield('c');
550 my $number = $record->field($fieldtag)->subfield('d');
552 $field->add_subfields(
553 "$subfield" => ucfirst($title) . " "
554 . ucfirst($firstname) . " "
558 $field->add_subfields(
559 "$subfield" => ucfirst($firstname) . ", "
560 . ucfirst($lastname) );
563 $record->insert_fields_ordered($field);
565 return $record, $encoding;
572 my ($duplicatetitle)= @_;
573 ($template, $loggedinuser, $cookie) = get_template_and_user
(
575 template_name
=> "acqui/neworderempty_duplicate.tt",
578 authnotrequired
=> 0,
579 flagsrequired
=> { acquisition
=> 'order_manage' },
585 biblionumber
=> $biblionumber,
586 basketno
=> $basketno,
587 booksellerid
=> $basket->{'booksellerid'},
588 breedingid
=> $params->{'breedingid'},
589 duplicatetitle
=> $duplicatetitle,
590 (uc(C4
::Context
->preference("marcflavour"))) => 1
593 output_html_with_http_headers
$input, $cookie, $template->output;