#
# This file is part of Koha.
#
-# Koha is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 2 of the License, or (at your option) any later
-# version.
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
#
-# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
#
-# You should have received a copy of the GNU General Public License along
-# with Koha; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use Carp;
use C4::Context;
use C4::Debug;
-use C4::Dates qw(format_date format_date_in_iso);
-use MARC::Record;
use C4::Suggestions;
use C4::Biblio;
use C4::Contract;
use Koha::Acquisition::Bookseller;
use Koha::Number::Price;
+use C4::Koha qw( subfield_is_koha_internal_p );
+
+use MARC::Field;
+use MARC::Record;
+
use Time::localtime;
use HTML::Entities;
&GetLateOrders &GetOrderFromItemnumber
&SearchOrders &GetHistory &GetRecentAcqui
&ModReceiveOrder &CancelReceipt
- &GetCancelledOrders &TransferOrder
+ &TransferOrder
&GetLastOrderNotReceivedFromSubscriptionid &GetLastOrderReceivedFromSubscriptionid
&ModItemOrder
&AddClaim
&GetBiblioCountByBasketno
+
+ &GetOrderUsers
+ &ModOrderUsers
+ &NotifyOrderUsers
+
+ &FillWithDefaultValues
);
}
=head3 GetBasketGroupAsCSV
-=over
-
-&GetBasketGroupAsCSV($basketgroupid);
+ &GetBasketGroupAsCSV($basketgroupid);
Export a basket group as CSV
$cgi parameter is needed for column name translation
-=back
-
=cut
sub GetBasketGroupAsCSV {
=head3 GetOrders
- @orders = &GetOrders($basketnumber, $orderby);
+ @orders = &GetOrders( $basketno, { orderby => 'biblio.title', cancelled => 0|1 } );
Looks up the pending (non-cancelled) orders with the given basket
-number. If C<$booksellerID> is non-empty, only orders from that seller
-are returned.
+number.
-return :
-C<&basket> returns a two-element array. C<@orders> is an array of
-references-to-hash, whose keys are the fields from the aqorders,
-biblio, and biblioitems tables in the Koha database.
+If cancelled is set, only cancelled orders will be returned.
=cut
sub GetOrders {
- my ( $basketno, $orderby ) = @_;
+ my ( $basketno, $params ) = @_;
+
return () unless $basketno;
+
+ my $orderby = $params->{orderby};
+ my $cancelled = $params->{cancelled} || 0;
+
my $dbh = C4::Context->dbh;
- my $query ="
+ my $query = q|
SELECT biblio.*,biblioitems.*,
aqorders.*,
aqbudgets.*,
+ |;
+ $query .= $cancelled
+ ? q|
+ aqorders_transfers.ordernumber_to AS transferred_to,
+ aqorders_transfers.timestamp AS transferred_to_timestamp
+ |
+ : q|
aqorders_transfers.ordernumber_from AS transferred_from,
aqorders_transfers.timestamp AS transferred_from_timestamp
+ |;
+ $query .= q|
FROM aqorders
LEFT JOIN aqbudgets ON aqbudgets.budget_id = aqorders.budget_id
LEFT JOIN biblio ON biblio.biblionumber = aqorders.biblionumber
LEFT JOIN biblioitems ON biblioitems.biblionumber =biblio.biblionumber
+ |;
+ $query .= $cancelled
+ ? q|
+ LEFT JOIN aqorders_transfers ON aqorders_transfers.ordernumber_from = aqorders.ordernumber
+ |
+ : q|
LEFT JOIN aqorders_transfers ON aqorders_transfers.ordernumber_to = aqorders.ordernumber
+
+ |;
+ $query .= q|
WHERE basketno=?
+ |;
+
+ if ($cancelled) {
+ $orderby ||= q|biblioitems.publishercode, biblio.title|;
+ $query .= q|
+ AND (datecancellationprinted IS NOT NULL
+ AND datecancellationprinted <> '0000-00-00')
+ |;
+ }
+ else {
+ $orderby ||=
+ q|aqorders.datecancellationprinted desc, aqorders.timestamp desc|;
+ $query .= q|
AND (datecancellationprinted IS NULL OR datecancellationprinted='0000-00-00')
- ";
+ |;
+ }
- $orderby = "biblioitems.publishercode,biblio.title" unless $orderby;
$query .= " ORDER BY $orderby";
- my $result_set =
+ my $orders =
$dbh->selectall_arrayref( $query, { Slice => {} }, $basketno );
- return @{$result_set};
+ return @{$orders};
}
#------------------------------------------------------------#
+
=head3 GetOrdersByBiblionumber
@orders = &GetOrdersByBiblionumber($biblionumber);
#------------------------------------------------------------#
-=head3 GetCancelledOrders
-
- my @orders = GetCancelledOrders($basketno, $orderby);
-
-Returns cancelled orders for a basket
-
-=cut
-
-sub GetCancelledOrders {
- my ( $basketno, $orderby ) = @_;
-
- return () unless $basketno;
-
- my $dbh = C4::Context->dbh;
- my $query = "
- SELECT
- biblio.*,
- biblioitems.*,
- aqorders.*,
- aqbudgets.*,
- aqorders_transfers.ordernumber_to AS transferred_to,
- aqorders_transfers.timestamp AS transferred_to_timestamp
- FROM aqorders
- LEFT JOIN aqbudgets ON aqbudgets.budget_id = aqorders.budget_id
- LEFT JOIN biblio ON biblio.biblionumber = aqorders.biblionumber
- LEFT JOIN biblioitems ON biblioitems.biblionumber = biblio.biblionumber
- LEFT JOIN aqorders_transfers ON aqorders_transfers.ordernumber_from = aqorders.ordernumber
- WHERE basketno = ?
- AND (datecancellationprinted IS NOT NULL
- AND datecancellationprinted <> '0000-00-00')
- ";
-
- $orderby = "aqorders.datecancellationprinted desc, aqorders.timestamp desc"
- unless $orderby;
- $query .= " ORDER BY $orderby";
- my $sth = $dbh->prepare($query);
- $sth->execute($basketno);
- my $results = $sth->fetchall_arrayref( {} );
-
- return @$results;
-}
-
-
-#------------------------------------------------------------#
-
=head3 ModReceiveOrder
&ModReceiveOrder({
my $order_vendornote = $params->{order_vendornote};
my $dbh = C4::Context->dbh;
- $datereceived = C4::Dates->output('iso') unless $datereceived;
+ $datereceived = output_pref(
+ {
+ dt => ( $datereceived ? dt_from_string( $datereceived ) : dt_from_string ),
+ dateformat => 'iso',
+ dateonly => 1,
+ }
+ );
my $suggestionid = GetSuggestionFromBiblionumber( $biblionumber );
if ($suggestionid) {
ModSuggestion( {suggestionid=>$suggestionid,
$cost,
$rrp,
$ecost,
- $budget_id,
+ ( $budget_id ? $budget_id : $order->{budget_id} ),
( defined $order_internalnote ? $order_internalnote : () ),
( defined $order_vendornote ? $order_vendornote : () ),
$biblionumber,
$ordernumber
);
+
+ # All items have been received, sent a notification to users
+ NotifyOrderUsers( $ordernumber );
+
}
return ($datereceived, $new_ordernumber);
}
LEFT JOIN biblioitems ON biblioitems.biblionumber=biblio.biblionumber
};
- # If we search on ordernumber, we retrieve the transfered order if a transfer has been done.
+ # If we search on ordernumber, we retrieve the transferred order if a transfer has been done.
$query .= q{
LEFT JOIN aqorders_transfers ON aqorders_transfers.ordernumber_to = aqorders.ordernumber
} if $ordernumber;
my $newordernumber = TransferOrder($ordernumber, $basketno);
Transfer an order line to a basket.
-Mark $ordernumber as cancelled with an internal note 'Cancelled and transfered
+Mark $ordernumber as cancelled with an internal note 'Cancelled and transferred
to BOOKSELLER on DATE' and create new order with internal note
-'Transfered from BOOKSELLER on DATE'.
+'Transferred from BOOKSELLER on DATE'.
Move all attached items to the new order.
-Received orders cannot be transfered.
+Received orders cannot be transferred.
Return the ordernumber of created order.
=cut
$query = q{
UPDATE aqorders
- SET datecancellationprinted = CAST(NOW() AS date)
+ SET datecancellationprinted = CAST(NOW() AS date), orderstatus = ?
WHERE ordernumber = ?
};
$sth = $dbh->prepare($query);
- $rv = $sth->execute($ordernumber);
+ $rv = $sth->execute('cancelled', $ordernumber);
delete $order->{'ordernumber'};
delete $order->{parent_ordernumber};
my $get_canceled_order = $params{get_canceled_order} || 0;
my $ordernumber = $params{ordernumber};
my $search_children_too = $params{search_children_too} || 0;
+ my $created_by = $params{created_by} || [];
my @order_loop;
my $total_qty = 0;
aqorders.basketno,
aqbasket.basketname,
aqbasket.basketgroupid,
+ aqbasket.authorisedby,
+ concat( borrowers.firstname,' ',borrowers.surname) AS authorisedbyname,
aqbasketgroups.name as groupname,
aqbooksellers.name,
aqbasket.creationdate,
LEFT JOIN aqinvoices ON aqorders.invoiceid = aqinvoices.invoiceid
LEFT JOIN deletedbiblio ON deletedbiblio.biblionumber=aqorders.biblionumber
LEFT JOIN deletedbiblioitems ON deletedbiblioitems.biblionumber=aqorders.biblionumber
+ LEFT JOIN borrowers ON aqbasket.authorisedby=borrowers.borrowernumber
";
- if ( C4::Context->preference("IndependentBranches") ) {
- $query .= " LEFT JOIN borrowers ON aqbasket.authorisedby=borrowers.borrowernumber";
- }
-
$query .= " WHERE 1 ";
unless ($get_canceled_order or (defined $orderstatus and $orderstatus eq 'cancelled')) {
$query .= ") ";
}
+ if ( @$created_by ) {
+ $query .= ' AND aqbasket.authorisedby IN ( ' . join( ',', ('?') x @$created_by ) . ')';
+ push @query_params, @$created_by;
+ }
+
if ( C4::Context->preference("IndependentBranches") ) {
unless ( C4::Context->IsSuperLibrarian() ) {
=head3 AddClaim
-=over
-
-&AddClaim($ordernumber);
+ &AddClaim($ordernumber);
Add a claim for an order
-=back
-
=cut
sub AddClaim {
Reopen an invoice
-Equivalent to ModInvoice(invoiceid => $invoiceid, closedate => C4::Dates->new()->output('iso'))
+Equivalent to ModInvoice(invoiceid => $invoiceid, closedate => output_pref({ dt=>dt_from_string, dateonly=>1, otputpref=>'iso' }))
=cut
}
}
- # Not used yet
- #if ($receiving) {
- # if ( $bookseller->{invoiceincgst} ) {
- # $order->{unitpricegsti} = $order->{unitprice};
- # $order->{unitpricegste} =
- # $order->{unitpricegsti} / ( 1 + $order->{gstrate} );
- # }
- # else {
- # $order->{unitpricegste} = $order->{unitprice};
- # $order->{unitpricegsti} =
- # $order->{unitpricegste} * ( 1 + $order->{gstrate} );
- # }
- # $order->{gstvalue} =
- # $order->{quantityreceived} *
- # $order->{unitpricegste} *
- # $order->{gstrate};
- #}
+ if ($receiving) {
+ if ( $bookseller->{listincgst} ) {
+ $order->{unitpricegsti} = Koha::Number::Price->new( $order->{unitprice} )->round;
+ $order->{unitpricegste} = Koha::Number::Price->new(
+ $order->{unitpricegsti} / ( 1 + $order->{gstrate} ) )->round;
+ }
+ else {
+ $order->{unitpricegste} = Koha::Number::Price->new( $order->{unitprice} )->round;
+ $order->{unitpricegsti} = Koha::Number::Price->new(
+ $order->{unitpricegste} * ( 1 + $order->{gstrate} ) )->round;
+ }
+ $order->{gstvalue} = Koha::Number::Price->new(
+ ( $order->{unitpricegsti} - $order->{unitpricegste} )
+ * $order->{quantityreceived} )->round;
+
+ $order->{totalgste} = $order->{unitpricegste} * $order->{quantity};
+ $order->{totalgsti} = $order->{unitpricegsti} * $order->{quantity};
+ }
return $order;
}
+=head3 GetOrderUsers
+
+ $order_users_ids = &GetOrderUsers($ordernumber);
+
+Returns a list of all borrowernumbers that are in order users list
+
+=cut
+
+sub GetOrderUsers {
+ my ($ordernumber) = @_;
+
+ return unless $ordernumber;
+
+ my $query = q|
+ SELECT borrowernumber
+ FROM aqorder_users
+ WHERE ordernumber = ?
+ |;
+ my $dbh = C4::Context->dbh;
+ my $sth = $dbh->prepare($query);
+ $sth->execute($ordernumber);
+ my $results = $sth->fetchall_arrayref( {} );
+
+ my @borrowernumbers;
+ foreach (@$results) {
+ push @borrowernumbers, $_->{'borrowernumber'};
+ }
+
+ return @borrowernumbers;
+}
+
+=head3 ModOrderUsers
+
+ my @order_users_ids = (1, 2, 3);
+ &ModOrderUsers($ordernumber, @basketusers_ids);
+
+Delete all users from order users list, and add users in C<@order_users_ids>
+to this users list.
+
+=cut
+
+sub ModOrderUsers {
+ my ( $ordernumber, @order_users_ids ) = @_;
+
+ return unless $ordernumber;
+
+ my $dbh = C4::Context->dbh;
+ my $query = q|
+ DELETE FROM aqorder_users
+ WHERE ordernumber = ?
+ |;
+ my $sth = $dbh->prepare($query);
+ $sth->execute($ordernumber);
+
+ $query = q|
+ INSERT INTO aqorder_users (ordernumber, borrowernumber)
+ VALUES (?, ?)
+ |;
+ $sth = $dbh->prepare($query);
+ foreach my $order_user_id (@order_users_ids) {
+ $sth->execute( $ordernumber, $order_user_id );
+ }
+}
+
+sub NotifyOrderUsers {
+ my ($ordernumber) = @_;
+
+ my @borrowernumbers = GetOrderUsers($ordernumber);
+ return unless @borrowernumbers;
+
+ my $order = GetOrder( $ordernumber );
+ for my $borrowernumber (@borrowernumbers) {
+ my $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber );
+ my $branch = C4::Branch::GetBranchDetail( $borrower->{branchcode} );
+ my $biblio = C4::Biblio::GetBiblio( $order->{biblionumber} );
+ my $letter = C4::Letters::GetPreparedLetter(
+ module => 'acquisition',
+ letter_code => 'ACQ_NOTIF_ON_RECEIV',
+ branchcode => $branch->{branchcode},
+ tables => {
+ 'branches' => $branch,
+ 'borrowers' => $borrower,
+ 'biblio' => $biblio,
+ 'aqorders' => $order,
+ },
+ );
+ if ( $letter ) {
+ C4::Letters::EnqueueLetter(
+ {
+ letter => $letter,
+ borrowernumber => $borrowernumber,
+ LibraryName => C4::Context->preference("LibraryName"),
+ message_transport_type => 'email',
+ }
+ ) or warn "can't enqueue letter $letter";
+ }
+ }
+}
+
+=head3 FillWithDefaultValues
+
+FillWithDefaultValues( $marc_record );
+
+This will update the record with default value defined in the ACQ framework.
+For all existing fields, if a default value exists and there are no subfield, it will be created.
+If the field does not exist, it will be created too.
+
+=cut
+
+sub FillWithDefaultValues {
+ my ($record) = @_;
+ my $tagslib = C4::Biblio::GetMarcStructure( 1, 'ACQ' );
+ if ($tagslib) {
+ my ($itemfield) =
+ C4::Biblio::GetMarcFromKohaField( 'items.itemnumber', '' );
+ for my $tag ( sort keys %$tagslib ) {
+ next unless $tag;
+ next if $tag == $itemfield;
+ for my $subfield ( sort keys %{ $tagslib->{$tag} } ) {
+ next if ( subfield_is_koha_internal_p($subfield) );
+ my $defaultvalue = $tagslib->{$tag}{$subfield}{defaultvalue};
+ if ( defined $defaultvalue and $defaultvalue ne '' ) {
+ my @fields = $record->field($tag);
+ if (@fields) {
+ for my $field (@fields) {
+ unless ( defined $field->subfield($subfield) ) {
+ $field->add_subfields(
+ $subfield => $defaultvalue );
+ }
+ }
+ }
+ else {
+ $record->insert_fields_ordered(
+ MARC::Field->new(
+ $tag, '', '', $subfield => $defaultvalue
+ )
+ );
+ }
+ }
+ }
+ }
+ }
+}
+
1;
__END__