Bug 33653: Use filter_by_active instead
[koha.git] / Koha / Acquisition / Orders.pm
1 package Koha::Acquisition::Orders;
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18 use Modern::Perl;
19
20
21 use Koha::Database;
22
23 use Koha::DateUtils qw( dt_from_string );
24 use Koha::Acquisition::Order;
25 use Koha::Exception;
26
27 use base qw(Koha::Objects);
28
29 =head1 NAME
30
31 Koha::Acquisition::Orders object set class
32
33 =head1 API
34
35 =head2 Class methods
36
37 =head3 filter_by_lates
38
39 my $late_orders = $orders->filter_by_lates($params);
40
41 Filter an order set given different parameters.
42
43 This is the equivalent method of the former GetLateOrders C4 subroutine
44
45 $params can be:
46
47 =over
48
49 =item C<delay> the number of days the basket has been closed
50
51 =item C<bookseller_id> the bookseller id
52
53 =item C<estimated_from> Beginning of the estimated delivery date
54
55 =item C<estimated_to> End of the estimated delivery date
56
57 =back
58
59 =cut
60
61 sub filter_by_lates {
62     my ( $self, $params ) = @_;
63     my $delay = $params->{delay};
64     my $bookseller_id = $params->{bookseller_id};
65     # my $branchcode = $params->{branchcode}; # FIXME do we really need this
66     my $estimated_from = $params->{estimated_from};
67     my $estimated_to = $params->{estimated_to};
68     my $dtf = Koha::Database->new->schema->storage->datetime_parser;
69
70     my @delivery_time_conditions;
71     my $date_add = "DATE_ADD(basketno.closedate, INTERVAL COALESCE(booksellerid.deliverytime, booksellerid.deliverytime, 0) day)";
72     my @estimated_delivery_time_conditions;
73     if ( defined $estimated_from or defined $estimated_to ) {
74         push @delivery_time_conditions, \[ "$date_add IS NOT NULL" ];
75         push @delivery_time_conditions, \[ "estimated_delivery_date IS NULL" ];
76         push @estimated_delivery_time_conditions, \[ "estimated_delivery_date IS NOT NULL" ];
77     }
78     if ( defined $estimated_from ) {
79         push @delivery_time_conditions, \[ "$date_add >= ?", $dtf->format_date($estimated_from) ];
80         push @estimated_delivery_time_conditions, \[ "estimated_delivery_date >= ?", $dtf->format_date($estimated_from) ];
81     }
82     if ( defined $estimated_to ) {
83         push @delivery_time_conditions, \[ "$date_add <= ?", $dtf->format_date($estimated_to) ];
84         push @estimated_delivery_time_conditions, \[ "estimated_delivery_date <= ?", $dtf->format_date($estimated_to) ];
85     }
86     if ( defined $estimated_from and not defined $estimated_to ) {
87         push @delivery_time_conditions, \[ "$date_add <= ?", $dtf->format_date(dt_from_string) ];
88         push @estimated_delivery_time_conditions, \[ "estimated_delivery_date <= ?", $dtf->format_date(dt_from_string) ];
89     }
90
91     $self->search(
92         {
93             -or => [
94                 { datereceived => undef },
95                 quantityreceived => { '<' => \'quantity' }
96             ],
97             'basketno.closedate' => [
98                 -and =>
99                 { '!=' => undef },
100                 {
101                     defined $delay
102                     ? (
103                         '<=' => $dtf->format_date(
104                             dt_from_string->subtract( days => $delay )
105                         )
106                       )
107                     : ()
108                 }
109               ],
110             'datecancellationprinted' => undef,
111             (
112                 $bookseller_id
113                 ? ( 'basketno.booksellerid' => $bookseller_id )
114                 : ()
115             ),
116
117             # ( $branchcode ? ('borrower.branchcode')) # FIXME branch is not a filter we may not need to implement this
118
119             ( ( @delivery_time_conditions and @estimated_delivery_time_conditions ) ?
120                 ( -or =>
121                     [
122                         -and => \@estimated_delivery_time_conditions,
123                         -and => \@delivery_time_conditions
124                     ]
125                 )
126                 : ()
127             ),
128             (
129                 C4::Context->preference('IndependentBranches')
130                   && !C4::Context->IsSuperLibrarian
131                 ? ( 'borrower.branchcode' => C4::Context->userenv->{branch} )
132                 : ()
133             )
134         },
135         {
136             '+select' => [
137                 \"DATE_ADD(basketno.closedate, INTERVAL COALESCE(booksellerid.deliverytime, booksellerid.deliverytime, 0) day)",
138             ],
139             '+as' => [qw/
140                 calculated_estimated_delivery_date
141             /],
142             join => { 'basketno' => 'booksellerid' },
143             prefetch => {'basketno' => 'booksellerid'},
144         }
145     )->filter_by_active;
146 }
147
148 =head3 filter_by_active
149
150     my $new_rs = $orders->filter_by_active;
151
152 Returns a new resultset filtering orders that are not active.
153
154 =cut
155
156 sub filter_by_active {
157     my ($self) = @_;
158     return $self->search(
159         {
160             '-or' => [
161                 { 'basket.is_standing' => 1,
162                   'orderstatus' => [ 'new', 'ordered', 'partial' ] },
163                 { 'orderstatus' => [ 'ordered', 'partial' ] }
164             ]
165         },
166         { join => 'basket' }
167     );
168 }
169
170 =head3 filter_by_current
171
172     $orders->filter_by_current
173
174 Return the orders of the set that have not been cancelled.
175
176 =cut
177
178 sub filter_by_current {
179     my ($self) = @_;
180     return $self->search(
181         {
182             datecancellationprinted => undef,
183         }
184     );
185 }
186
187 =head3 filter_by_cancelled
188
189     $orders->filter_by_cancelled
190
191 Return the orders of the set that have been cancelled.
192
193 =cut
194
195 sub filter_by_cancelled {
196     my ($self) = @_;
197     return $self->search(
198         {
199             datecancellationprinted => { '!=' => undef }
200         }
201     );
202 }
203
204 =head3 filter_by_id_including_transfers
205
206     my $orders = $orders->filter_by_id_including_transfers(
207         {
208             ordernumber => $ordernumber
209         }
210     );
211
212 When searching for orders by I<ordernumber>, include the aqorders_transfers table
213 so we can find orders that have changed their ordernumber as the result of a transfer
214
215 =cut
216
217 sub filter_by_id_including_transfers {
218     my ( $self, $params ) = @_;
219
220     Koha::Exceptions::MissingParameter->throw( "The ordernumber param is mandatory" )
221         unless $params->{ordernumber};
222
223     return $self->search(
224         {
225             -or => [
226                 { 'me.ordernumber' => $params->{ordernumber} },
227                 { 'aqorders_transfers_ordernumber_to.ordernumber_from' => $params->{ordernumber} }
228             ]
229         },
230         { join => 'aqorders_transfers_ordernumber_to' }
231     );
232 }
233
234 =head2 Internal methods
235
236 =head3 _type
237
238 =cut
239
240 sub _type {
241     return 'Aqorder';
242 }
243
244 =head3 object_class
245
246 =cut
247
248 sub object_class {
249     return 'Koha::Acquisition::Order';
250 }
251
252 1;