3 #script to group (closed) baskets into basket groups for easier order management
4 #written by john.soros@biblibre.com 01/10/2008
6 # Copyright 2008 - 2009 BibLibre SARL
7 # Parts Copyright Catalyst 2010
9 # This file is part of Koha.
11 # Koha is free software; you can redistribute it and/or modify it under the
12 # terms of the GNU General Public License as published by the Free Software
13 # Foundation; either version 2 of the License, or (at your option) any later
16 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
17 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License along
21 # with Koha; if not, write to the Free Software Foundation, Inc.,
22 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 This script lets the user group (closed) baskets into basket groups for easier order management. Note that the grouped baskets have to be from the same bookseller and
32 have to be closed to be printed or exported.
40 The bookseller who we want to display the baskets (and basketgroups) of.
55 use C4
::Bookseller qw
/GetBookSellerFromId/;
56 use C4
::Budgets qw
/ConvertCurrency/;
57 use C4
::Acquisition qw
/CloseBasketgroup ReOpenBasketgroup GetOrders GetBasketsByBasketgroup GetBasketsByBookseller ModBasketgroup NewBasketgroup DelBasketgroup GetBasketgroups ModBasket GetBasketgroup GetBasket GetBasketGroupAsCSV/;
58 use C4
::Bookseller qw
/GetBookSellerFromId/;
59 use C4
::Branch qw
/GetBranches/;
60 use C4
::Members qw
/GetMember/;
64 our ($template, $loggedinuser, $cookie)
65 = get_template_and_user
({template_name
=> "acqui/basketgroup.tmpl",
69 flagsrequired
=> {acquisition
=> 'group_manage'},
75 my $bookseller = shift;
77 my @orders = GetOrders
($basketno);
78 for my $order (@orders){
79 $total = $total + ( $order->{ecost
} * $order->{quantity
} );
80 if ($bookseller->{invoiceincgst
} && ! $bookseller->{listincgst
} && ( $bookseller->{gstrate
} // C4
::Context
->preference("gist") )) {
81 my $gst = $bookseller->{gstrate
} // C4
::Context
->preference("gist");
82 $total = $total * ( $gst / 100 +1);
85 $total .= " " . ($bookseller->{invoiceprice
} // 0);
89 #displays all basketgroups and all closed baskets (in their respective groups)
90 sub displaybasketgroups
{
91 my $basketgroups = shift;
92 my $bookseller = shift;
94 if (scalar @
$basketgroups != 0) {
95 foreach my $basketgroup (@
$basketgroups){
98 while($i < scalar(@
$baskets)){
99 my $basket = @
$baskets[$i];
100 if($basket->{'basketgroupid'} && $basket->{'basketgroupid'} == $basketgroup->{'id'}){
101 $basket->{total
} = BasketTotal
($basket->{basketno
}, $bookseller);
102 push(@
{$basketgroup->{'baskets'}}, $basket);
103 splice(@
$baskets, $i, 1);
109 $basketgroup -> {'basketsqty'} = $basketsqty;
111 $template->param(basketgroups
=> $basketgroups);
113 for(my $i=0; $i < scalar @
$baskets; ++$i) {
114 if( ! @
$baskets[$i]->{'closedate'} ) {
115 splice(@
$baskets, $i, 1);
118 @
$baskets[$i]->{total
} = BasketTotal
(@
$baskets[$i]->{basketno
}, $bookseller);
121 $template->param(baskets
=> $baskets);
122 $template->param( booksellername
=> $bookseller ->{'name'});
125 sub printbasketgrouppdf
{
126 my ($basketgroupid) = @_;
128 my $pdfformat = C4
::Context
->preference("OrderPdfFormat");
129 if ($pdfformat eq 'pdfformat::layout3pages' || $pdfformat eq 'pdfformat::layout2pages' || $pdfformat eq 'pdfformat::layout3pagesfr'
130 || $pdfformat eq 'pdfformat::layout2pagesde'){
132 eval "require $pdfformat";
139 print $input->header;
140 print $input->start_html; # FIXME Should do a nicer page
141 print "<h1>Invalid PDF Format set</h1>";
142 print "Please go to the systempreferences and set a valid pdfformat";
146 my $basketgroup = GetBasketgroup
($basketgroupid);
147 my $bookseller = GetBookSellerFromId
($basketgroup->{'booksellerid'});
148 my $baskets = GetBasketsByBasketgroup
($basketgroupid);
151 for my $basket (@
$baskets) {
153 my @ords = &GetOrders
($basket->{basketno
});
154 for my $ord (@ords) {
156 next unless ( $ord->{biblionumber
} or $ord->{quantity
}> 0 );
172 $ord->{rrp
} = ConvertCurrency
( $ord->{'currency'}, $ord->{rrp
} );
173 if ( $bookseller->{'listincgst'} ) {
174 $ord->{rrpgsti
} = sprintf( "%.2f", $ord->{rrp
} );
175 $ord->{gstgsti
} = sprintf( "%.2f", $ord->{gstrate
} * 100 );
176 $ord->{rrpgste
} = sprintf( "%.2f", $ord->{rrp
} / ( 1 + ( $ord->{gstgsti} / 100 ) ) );
177 $ord->{gstgste
} = sprintf( "%.2f", $ord->{gstgsti
} / ( 1 + ( $ord->{gstgsti} / 100 ) ) );
178 $ord->{ecostgsti
} = sprintf( "%.2f", $ord->{ecost
} );
179 $ord->{ecostgste
} = sprintf( "%.2f", $ord->{ecost
} / ( 1 + ( $ord->{gstgsti} / 100 ) ) );
180 $ord->{gstvalue
} = sprintf( "%.2f", ( $ord->{ecostgsti
} - $ord->{ecostgste
} ) * $ord->{quantity
});
181 $ord->{totalgste
} = sprintf( "%.2f", $ord->{quantity
} * $ord->{ecostgste
} );
182 $ord->{totalgsti
} = sprintf( "%.2f", $ord->{quantity
} * $ord->{ecostgsti
} );
184 $ord->{rrpgsti
} = sprintf( "%.2f", $ord->{rrp
} * ( 1 + ( $ord->{gstrate
} ) ) );
185 $ord->{rrpgste
} = sprintf( "%.2f", $ord->{rrp
} );
186 $ord->{gstgsti
} = sprintf( "%.2f", $ord->{gstrate
} * 100 );
187 $ord->{gstgste
} = sprintf( "%.2f", $ord->{gstrate
} * 100 );
188 $ord->{ecostgsti
} = sprintf( "%.2f", $ord->{ecost
} * ( 1 + ( $ord->{gstrate
} ) ) );
189 $ord->{ecostgste
} = sprintf( "%.2f", $ord->{ecost
} );
190 $ord->{gstvalue
} = sprintf( "%.2f", ( $ord->{ecostgsti
} - $ord->{ecostgste
} ) * $ord->{quantity
});
191 $ord->{totalgste
} = sprintf( "%.2f", $ord->{quantity
} * $ord->{ecostgste
} );
192 $ord->{totalgsti
} = sprintf( "%.2f", $ord->{quantity
} * $ord->{ecostgsti
} );
194 my $bib = GetBiblioData
($ord->{biblionumber
});
195 my $itemtypes = GetItemTypes
();
198 # 0 1 2 3 4 5 6 7 8 9
199 #isbn, itemtype, author, title, publishercode, quantity, listprice ecost discount gstrate
203 my $marcrecord=eval{MARC
::Record
::new_from_xml
( $ord->{marcxml
},'UTF-8' )};
205 if ( C4
::Context
->preference("marcflavour") eq 'UNIMARC' ) {
206 $en = $marcrecord->subfield( '345', "b" );
207 } elsif ( C4
::Context
->preference("marcflavour") eq 'MARC21' ) {
208 $en = $marcrecord->subfield( '037', "a" );
213 isbn
=> ($ord->{isbn
} ?
$ord->{isbn
} : undef),
214 itemtype
=> ( $ord->{itemtype
} and $bib->{itemtype
} ?
$itemtypes->{$bib->{itemtype
}}->{description
} : undef ),
215 en
=> ( $en ?
$en : undef ),
217 for my $key ( qw
/ gstrate author title itemtype publishercode discount quantity rrpgsti rrpgste gstgsti gstgste ecostgsti ecostgste gstvalue totalgste totalgsti / ) {
218 $ba_order->{$key} = $ord->{$key};
221 push(@ba_orders, $ba_order);
223 $orders{$basket->{basketno
}} = \
@ba_orders;
225 print $input->header(
226 -type
=> 'application/pdf',
227 -attachment
=> ( $basketgroup->{name
} || $basketgroupid ) . '.pdf'
229 my $pdf = printpdf
($basketgroup, $bookseller, $baskets, \
%orders, $bookseller->{gstrate
} // C4
::Context
->preference("gist")) || die "pdf generation failed";
234 my $op = $input->param('op') || 'display';
235 # possible values of $op :
236 # - add : adds a new basketgroup, or edit an open basketgroup, or display a closed basketgroup
237 # - mod_basket : modify an individual basket of the basketgroup
238 # - closeandprint : close and print an closed basketgroup in pdf. called by clicking on "Close and print" button in closed basketgroups list
239 # - print : print a closed basketgroup. called by clicking on "Print" button in closed basketgroups list
240 # - export : export in CSV a closed basketgroup. called by clicking on "Export" button in closed basketgroups list
241 # - delete : delete an open basketgroup. called by clicking on "Delete" button in open basketgroups list
242 # - reopen : reopen a closed basketgroup. called by clicking on "Reopen" button in closed basketgroup list
243 # - attachbasket : save a modified basketgroup, or creates a new basketgroup when a basket is closed. called from basket page
244 # - display : display the list of all basketgroups for a vendor
245 my $booksellerid = $input->param('booksellerid');
246 $template->param(booksellerid
=> $booksellerid);
248 if ( $op eq "add" ) {
250 # if no param('basketgroupid') is not defined, adds a new basketgroup
251 # else, edit (if it is open) or display (if it is close) the basketgroup basketgroupid
252 # the template will know if basketgroup must be displayed or edited, depending on the value of closed key
254 my $bookseller = &GetBookSellerFromId
($booksellerid);
255 my $basketgroupid = $input->param('basketgroupid');
258 my $freedeliveryplace;
259 if ( $basketgroupid ) {
260 # Get the selected baskets in the basketgroup to display them
261 my $selecteds = GetBasketsByBasketgroup
($basketgroupid);
262 foreach my $basket(@
{$selecteds}){
263 $basket->{total
} = BasketTotal
($basket->{basketno
}, $bookseller);
265 $template->param(basketgroupid
=> $basketgroupid,
266 selectedbaskets
=> $selecteds);
268 # Get general informations about the basket group to prefill the form
269 my $basketgroup = GetBasketgroup
($basketgroupid);
271 name
=> $basketgroup->{name
},
272 deliverycomment
=> $basketgroup->{deliverycomment
},
273 freedeliveryplace
=> $basketgroup->{freedeliveryplace
},
275 $billingplace = $basketgroup->{billingplace
};
276 $deliveryplace = $basketgroup->{deliveryplace
};
277 $freedeliveryplace = $basketgroup->{freedeliveryplace
};
278 $template->param( closedbg
=> ($basketgroup ->{'closed'}) ?
1 : 0);
280 $template->param( closedbg
=> 0);
282 # determine default billing and delivery places depending on librarian homebranch and existing basketgroup data
283 my $borrower = GetMember
( ( 'borrowernumber' => $loggedinuser ) );
284 $billingplace = $billingplace || $borrower->{'branchcode'};
285 $deliveryplace = $deliveryplace || $borrower->{'branchcode'};
287 my $branches = C4
::Branch
::GetBranchesLoop
( $billingplace );
288 $template->param( billingplaceloop
=> $branches );
289 $branches = C4
::Branch
::GetBranchesLoop
( $deliveryplace );
290 $template->param( deliveryplaceloop
=> $branches );
291 $template->param( booksellerid
=> $booksellerid );
293 # the template will display a unique basketgroup
294 $template->param(grouping
=> 1);
295 my $basketgroups = &GetBasketgroups
($booksellerid);
296 my $baskets = &GetBasketsByBookseller
($booksellerid);
297 displaybasketgroups
($basketgroups, $bookseller, $baskets);
298 } elsif ($op eq 'mod_basket') {
300 # edit an individual basket contained in this basketgroup
302 my $basketno=$input->param('basketno');
303 my $basketgroupid=$input->param('basketgroupid');
304 ModBasket
( { basketno
=> $basketno,
305 basketgroupid
=> $basketgroupid } );
306 print $input->redirect("basket.pl?basketno=" . $basketno);
307 } elsif ( $op eq 'closeandprint') {
309 # close an open basketgroup and generates a pdf
311 my $basketgroupid = $input->param('basketgroupid');
312 CloseBasketgroup
($basketgroupid);
313 printbasketgrouppdf
($basketgroupid);
315 }elsif ($op eq 'print'){
317 # print a closed basketgroup
319 my $basketgroupid = $input->param('basketgroupid');
320 printbasketgrouppdf
($basketgroupid);
322 }elsif ( $op eq "export" ) {
324 # export a closed basketgroup in csv
326 my $basketgroupid = $input->param('basketgroupid');
327 print $input->header(
329 -attachment
=> 'basketgroup' . $basketgroupid . '.csv',
331 print GetBasketGroupAsCSV
( $basketgroupid, $input );
333 }elsif( $op eq "delete"){
335 # delete an closed basketgroup
337 my $basketgroupid = $input->param('basketgroupid');
338 DelBasketgroup
($basketgroupid);
339 print $input->redirect('/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid.'&listclosed=1');
340 }elsif ( $op eq 'reopen'){
342 # reopen a closed basketgroup
344 my $basketgroupid = $input->param('basketgroupid');
345 my $booksellerid = $input->param('booksellerid');
346 ReOpenBasketgroup
($basketgroupid);
347 my $redirectpath = ((defined $input->param('mode'))&& ($input->param('mode') eq 'singlebg')) ?
'/cgi-bin/koha/acqui/basketgroup.pl?op=add&basketgroupid='.$basketgroupid.'&booksellerid='.$booksellerid : '/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' .$booksellerid.'&listclosed=1';
348 print $input->redirect($redirectpath);
349 } elsif ( $op eq 'attachbasket') {
351 # save a modified basketgroup, or creates a new basketgroup when a basket is closed. called from basket page
354 my $basketgroup = {};
355 my @baskets = $input->param('basket');
356 my $basketgroupid = $input->param('basketgroupid');
357 my $basketgroupname = $input->param('basketgroupname');
358 my $booksellerid = $input->param('booksellerid');
359 my $billingplace = $input->param('billingplace');
360 my $deliveryplace = $input->param('deliveryplace');
361 my $freedeliveryplace = $input->param('freedeliveryplace');
362 my $deliverycomment = $input->param('deliverycomment');
363 my $closedbg = $input->param('closedbg') ?
1 : 0;
364 if ($basketgroupid) {
365 # If we have a basketgroupid we edit the basketgroup
367 name
=> $basketgroupname,
368 id
=> $basketgroupid,
369 basketlist
=> \
@baskets,
370 billingplace
=> $billingplace,
371 deliveryplace
=> $deliveryplace,
372 freedeliveryplace
=> $freedeliveryplace,
373 deliverycomment
=> $deliverycomment,
376 ModBasketgroup
($basketgroup);
381 # we create a new basketgroup (whith a closed basket)
383 name
=> $basketgroupname,
384 booksellerid
=> $booksellerid,
385 basketlist
=> \
@baskets,
386 billingplace
=> $billingplace,
387 deliveryplace
=> $deliveryplace,
388 freedeliveryplace
=> $freedeliveryplace,
389 deliverycomment
=> $deliverycomment,
392 $basketgroupid = NewBasketgroup
($basketgroup);
394 my $redirectpath = ((defined $input->param('mode')) && ($input->param('mode') eq 'singlebg')) ?
'/cgi-bin/koha/acqui/basketgroup.pl?op=add&basketgroupid='.$basketgroupid.'&booksellerid='.$booksellerid : '/cgi-bin/koha/acqui/basketgroup.pl?booksellerid=' . $booksellerid;
395 $redirectpath .= "&listclosed=1" if $closedbg ;
396 print $input->redirect($redirectpath );
399 # no param : display the list of all basketgroups for a given vendor
400 my $basketgroups = &GetBasketgroups
($booksellerid);
401 my $bookseller = &GetBookSellerFromId
($booksellerid);
402 my $baskets = &GetBasketsByBookseller
($booksellerid);
404 displaybasketgroups
($basketgroups, $bookseller, $baskets);
406 $template->param(listclosed
=> ((defined $input->param('listclosed')) && ($input->param('listclosed') eq '1'))?
1:0 );
407 #prolly won't use all these, maybe just use print, the rest can be done inside validate
408 output_html_with_http_headers
$input, $cookie, $template->output;