3 #script to add an order into the system
4 #written 29/2/00 by chris@katipo.co.nz
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 add an order.
35 =item neworderempty.pl to add an order from an existing record or from nothing.
37 =item newordersuggestion.pl to add an order from an existing suggestion.
43 All of the cgi parameters below are related to the new order.
48 the number of this new order.
51 the number of this new basket
54 the bookseller the librarian has to pay.
59 the title of the record ordered.
62 the author of the record ordered.
64 =item C<copyrightdate>
65 the copyrightdate of the record ordered.
68 the ISBN of the record ordered.
73 the quantity to order.
76 the price of this order.
78 =item C<uncertainprice>
79 uncertain price, can't close basket until prices of all orders are known.
82 the branch where this order will be received.
90 budget_id used to pay this order.
92 =item C<sort1> & C<sort2>
107 the number of the invoice for this order.
109 =item C<publishercode>
111 =item C<suggestionid>
112 if it is an order from an existing suggestion : the id of this suggestion.
121 use CGI qw ( -utf8 );
122 use JSON qw ( to_json encode_json );
123 use C4::Auth qw( get_template_and_user );
124 use C4::Acquisition qw( FillWithDefaultValues ModOrderUsers );
125 use C4::Suggestions qw( ModSuggestion );
132 use C4::Budgets qw( GetBudget GetBudgetSpent GetBudgetOrdered FieldsForCalculatingFundValues );
133 use C4::Items qw( AddItemFromMarc );
134 use C4::Output qw( output_html_with_http_headers );
135 use C4::Log qw( logaction );
136 use Koha::Acquisition::Currencies qw( get_active );
137 use Koha::Acquisition::Orders;
138 use Koha::Acquisition::Baskets;
140 use Koha::DateUtils qw( dt_from_string );
142 use Koha::AdditionalFields;
144 ### "-------------------- addorder.pl ----------"
146 # FIXME: This needs to do actual error checking and possibly return user to the same form,
147 # not just blindly call C4 functions and print a redirect.
149 my $input = CGI->new;
150 my $use_ACQ_framework = $input->param('use_ACQ_framework');
152 # Check if order total amount exceed allowed budget
153 my $confirm_budget_exceeding = $input->param('confirm_budget_exceeding');
154 unless($confirm_budget_exceeding) {
155 my $budget_id = $input->param('budget_id');
156 my $total = $input->param('total');
157 my $budget = GetBudget($budget_id);
158 my $budget_spent = GetBudgetSpent($budget_id);
159 my $budget_ordered = GetBudgetOrdered($budget_id);
161 my $ordernumber = $input->param('ordernumber');
162 if ( $ordernumber ) {
163 # modifying an existing order so remove order price from $budget_ordered
164 my $order = Koha::Acquisition::Orders->find($ordernumber);
166 # get correct unitprice and ecost fields
167 my ( $unitprice_field, $ecost_field ) = FieldsForCalculatingFundValues();
168 $budget_ordered = $budget_ordered - ( $order->$ecost_field * $order->quantity );
171 my $budget_used = $budget_spent + $budget_ordered;
172 my $budget_remaining = $budget->{budget_amount} - $budget_used;
173 my $budget_encumbrance = $budget->{budget_amount} * $budget->{budget_encumb} / 100;
174 my $budget_expenditure = $budget->{budget_expend};
176 if ( $total > $budget_remaining
177 || ( ($budget_encumbrance+0) && ($budget_used + $total) > $budget_encumbrance)
178 || ( ($budget_expenditure+0) && ($budget_used + $total) > $budget_expenditure) )
180 my ($template, $loggedinuser, $cookie) = get_template_and_user({
181 template_name => "acqui/addorder.tt",
184 flagsrequired => {acquisition => 'order_manage'},
187 my $url = $input->referer();
188 unless ( defined $url ) {
189 my $basketno = $input->param('basketno');
190 $url = "/cgi-bin/koha/acqui/basket.pl?basketno=$basketno";
193 my $vars = $input->Vars;
195 foreach (keys %$vars) {
198 values => [ $input->multi_param($_) ],
202 if( ($budget_encumbrance+0) && ($budget_used + $total) > $budget_encumbrance
203 && $total <= $budget_remaining)
206 encumbrance_exceeded => 1,
207 encumbrance => sprintf("%.2f", $budget->{'budget_encumb'}),
210 if( ($budget_expenditure+0) && ($budget_used + $total) > $budget_expenditure
211 && $total <= $budget_remaining )
213 my $currency = Koha::Acquisition::Currencies->get_active;
215 expenditure_exceeded => 1,
216 expenditure => sprintf("%.2f", $budget_expenditure),
217 currency => ($currency) ? $currency->symbol : '',
220 if($total > $budget_remaining){
221 $template->param(budget_exceeded => 1);
225 not_enough_budget => 1,
227 vars_loop => \@vars_loop,
229 output_html_with_http_headers $input, $cookie, $template->output;
234 # get_template_and_user used only to check auth & get user id
235 my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
237 template_name => "acqui/booksellers.tt",
240 flagsrequired => { acquisition => 'order_manage' },
246 ordernumber => scalar $input->param('ordernumber'),
247 basketno => scalar $input->param('basketno'),
248 biblionumber => scalar $input->param('biblionumber'),
249 invoiceid => scalar $input->param('invoiceid'),
250 quantity => scalar $input->param('quantity'),
251 budget_id => scalar $input->param('budget_id'),
252 currency => scalar $input->param('currency'),
253 listprice => scalar $input->param('listprice'),
254 uncertainprice => scalar $input->param('uncertainprice'),
255 tax_rate_on_ordering => scalar $input->param('tax_rate'),
256 discount => scalar $input->param('discount'),
257 rrp => scalar $input->param('rrp'),
258 replacementprice => scalar $input->param('replacementprice'),
259 ecost => scalar $input->param('ecost'),
260 unitprice => scalar $input->param('unitprice'),
261 order_internalnote => scalar $input->param('order_internalnote'),
262 order_vendornote => scalar $input->param('order_vendornote'),
263 sort1 => scalar $input->param('sort1'),
264 sort2 => scalar $input->param('sort2'),
265 subscriptionid => scalar $input->param('subscriptionid'),
266 estimated_delivery_date => scalar $input->param('estimated_delivery_date'),
269 $orderinfo->{uncertainprice} ||= 0;
270 $orderinfo->{subscriptionid} ||= undef;
272 my $user = $input->remote_user;
273 my $basketno = $$orderinfo{basketno};
274 my $basket = Koha::Acquisition::Baskets->find($basketno);
276 # Order related fields we're going to log
277 my @log_order_fields = (
281 'unitprice_tax_excluded',
282 'unitprice_tax_included',
288 'ecost_tax_excluded',
289 'ecost_tax_included',
290 'tax_rate_on_ordering'
293 # create, modify or delete biblio
294 # create if $quantity>0 and $existing='no'
295 # modify if $quantity>0 and $existing='yes'
296 if ( $basket->{is_standing} || $orderinfo->{quantity} ne '0' ) {
297 #TODO:check to see if biblio exists
298 unless ( $$orderinfo{biblionumber} ) {
301 if ( $use_ACQ_framework ) {
302 my @tags = $input->multi_param('bib_tag');
303 my @subfields = $input->multi_param('bib_subfield');
304 my @field_values = $input->multi_param('bib_field_value');
305 my $xml = TransformHtmlToXml( \@tags, \@subfields, \@field_values );
306 $record=MARC::Record::new_from_xml($xml, 'UTF-8');
308 #if it doesn't create it
309 $record = TransformKohaToMarc(
311 "biblio.title" => $input->param('title') || '',
312 "biblio.author" => $input->param('author') || '',
313 "biblio.seriestitle" => $input->param('series') || '',
314 "biblioitems.isbn" => $input->param('isbn') || '',
315 "biblioitems.ean" => $input->param('ean') || '',
316 "biblioitems.publishercode" => $input->param('publishercode') || '',
317 "biblioitems.publicationyear" => $input->param('publicationyear') || '',
318 "biblio.copyrightdate" => $input->param('publicationyear') || '',
319 "biblioitems.itemtype" => $input->param('itemtype') || '',
320 "biblioitems.editionstatement"=> $input->param('editionstatement') || '',
324 C4::Acquisition::FillWithDefaultValues( $record );
326 # create the record in catalogue, with framework ''
327 my ($biblionumber,$bibitemnum) = AddBiblio($record,'');
329 $orderinfo->{biblionumber}=$biblionumber;
332 # change suggestion status if applicable
333 if ( my $suggestionid = $input->param('suggestionid') ) {
336 suggestionid => $suggestionid,
337 biblionumber => $orderinfo->{biblionumber},
343 $orderinfo->{unitprice} = $orderinfo->{ecost} if not defined $orderinfo->{unitprice} or $orderinfo->{unitprice} eq '';
348 if ( $orderinfo->{ordernumber} ) {
349 $order = Koha::Acquisition::Orders->find($orderinfo->{ordernumber});
350 $order->set($orderinfo);
351 $log_action_name = 'MODIFY_ORDER';
353 $order = Koha::Acquisition::Order->new($orderinfo);
354 $log_action_name = 'CREATE_ORDER';
356 $order->populate_with_prices_for_ordering();
359 # Log the order creation
360 if (C4::Context->preference("AcquisitionLog")) {
362 foreach my $field(@log_order_fields) {
363 $infos->{$field} = $order->$field;
372 my $order_users_ids = $input->param('users_ids');
373 my @order_users = split( /:/, $order_users_ids );
374 ModOrderUsers( $order->ordernumber, @order_users );
376 # Retrieve and save additional fields values
377 my @additional_fields = Koha::AdditionalFields->search({ tablename => 'aqorders' })->as_list;
378 my @additional_field_values;
379 foreach my $af (@additional_fields) {
381 my $value = $input->param("additional_field_$id");
382 push @additional_field_values, {
387 $order->set_additional_fields(\@additional_field_values);
389 # now, add items if applicable
390 if ($basket->effective_create_items eq 'ordering') {
392 my @tags = $input->multi_param('tag');
393 my @subfields = $input->multi_param('subfield');
394 my @field_values = $input->multi_param('field_value');
395 my @serials = $input->multi_param('serial');
396 my @itemid = $input->multi_param('itemid');
397 #Rebuilding ALL the data for items into a hash
398 # parting them on $itemid.
402 my $range=scalar(@itemid);
403 for (my $i=0; $i<$range; $i++){
404 unless ($itemhash{$itemid[$i]}){
407 push @{$itemhash{$itemid[$i]}->{'tags'}},$tags[$i];
408 push @{$itemhash{$itemid[$i]}->{'subfields'}},$subfields[$i];
409 push @{$itemhash{$itemid[$i]}->{'field_values'}},$field_values[$i];
411 foreach my $item (keys %itemhash){
412 my $xml = TransformHtmlToXml( $itemhash{$item}->{'tags'},
413 $itemhash{$item}->{'subfields'},
414 $itemhash{$item}->{'field_values'},
418 my $record=MARC::Record::new_from_xml($xml, 'UTF-8');
419 my ($barcodefield,$barcodesubfield) = GetMarcFromKohaField('items.barcode');
420 next unless ( defined $barcodefield && defined $barcodesubfield );
421 my $barcode = $record->subfield($barcodefield,$barcodesubfield) || '';
422 my $aBpref = C4::Context->preference('autoBarcode');
423 if( $barcode eq '' && $aBpref ne 'OFF'){
425 if ( $aBpref eq 'hbyymmincr'){
426 my ($homebranchfield,$homebranchsubfield) = GetMarcFromKohaField('items.homebranch');
427 my $homebranch = $record->subfield($homebranchfield,$homebranchsubfield);
428 $barcodeobj = C4::Barcodes->new($aBpref, $homebranch);
430 $barcodeobj = C4::Barcodes->new($aBpref);
432 $barcode = $barcodeobj->value();
433 $record->field($barcodefield)->delete_subfield( code => $barcodesubfield);
434 $record->field($barcodefield)->add_subfields($barcodesubfield => $barcode);
436 my ($biblionumber,$bibitemnum,$itemnumber) = AddItemFromMarc($record,$$orderinfo{biblionumber});
437 $order->add_item($itemnumber);
443 if (C4::Context->preference("AcquisitionLog") && $basketno) {
444 my $modified = Koha::Acquisition::Baskets->find( $basketno );
449 to_json($modified->unblessed)
453 my $booksellerid=$$orderinfo{booksellerid};
454 if (my $import_batch_id = $input->param('import_batch_id')) {
455 print $input->redirect("/cgi-bin/koha/acqui/addorderiso2709.pl?import_batch_id=$import_batch_id&basketno=$basketno&booksellerid=$booksellerid");
456 } elsif ( defined $orderinfo->{invoiceid} ) {
457 print $input->redirect("/cgi-bin/koha/acqui/parcel.pl?invoiceid=" . $orderinfo->{invoiceid});
459 print $input->redirect("/cgi-bin/koha/acqui/basket.pl?basketno=$basketno");