Bug 15184: Add the ability to duplicate existing order lines
[koha.git] / Koha / Acquisition / Order.pm
1 package Koha::Acquisition::Order;
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it under the
6 # terms of the GNU General Public License as published by the Free Software
7 # Foundation; either version 3 of the License, or (at your option) any later
8 # version.
9 #
10 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along
15 # with Koha; if not, write to the Free Software Foundation, Inc.,
16 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18 use Modern::Perl;
19
20 use Carp qw( croak );
21
22 use Koha::Acquisition::Baskets;
23 use Koha::Acquisition::Funds;
24 use Koha::Acquisition::Invoices;
25 use Koha::Database;
26 use Koha::DateUtils qw( dt_from_string output_pref );
27 use Koha::Items;
28 use Koha::Subscriptions;
29
30 use base qw(Koha::Object);
31
32 =head1 NAME
33
34 Koha::Acquisition::Order Object class
35
36 =head1 API
37
38 =head2 Class methods
39
40 =head3 new
41
42 Overloaded I<new> method for backwards compatibility.
43
44 =cut
45
46 sub new {
47     my ( $self, $params ) = @_;
48
49     my $schema  = Koha::Database->new->schema;
50     my @columns = $schema->source('Aqorder')->columns;
51
52     my $values =
53       { map { exists $params->{$_} ? ( $_ => $params->{$_} ) : () } @columns };
54     return $self->SUPER::new($values);
55 }
56
57 =head3 store
58
59 Overloaded I<store> method for backwards compatibility.
60
61 =cut
62
63 sub store {
64     my ($self) = @_;
65
66     my $schema  = Koha::Database->new->schema;
67     # Override quantity for standing orders
68     $self->quantity(1) if ( $self->basketno && $schema->resultset('Aqbasket')->find( $self->basketno )->is_standing );
69
70     # if these parameters are missing, we can't continue
71     for my $key (qw( basketno quantity biblionumber budget_id )) {
72         croak "Cannot insert order: Mandatory parameter $key is missing"
73           unless $self->$key;
74     }
75
76     if (not defined $self->{created_by}) {
77         my $userenv = C4::Context->userenv;
78         if ($userenv) {
79             $self->created_by($userenv->{number});
80         }
81     }
82
83     $self->quantityreceived(0) unless $self->quantityreceived;
84     $self->entrydate(dt_from_string) unless $self->entrydate;
85
86     $self->ordernumber(undef) unless $self->ordernumber;
87     $self = $self->SUPER::store( $self );
88
89     unless ( $self->parent_ordernumber ) {
90         $self->set( { parent_ordernumber => $self->ordernumber } );
91         $self = $self->SUPER::store( $self );
92     }
93
94     return $self;
95 }
96
97 =head3 add_item
98
99   $order->add_item( $itemnumber );
100
101 Link an item to this order.
102
103 =cut
104
105 sub add_item {
106     my ( $self, $itemnumber )  = @_;
107
108     my $schema = Koha::Database->new->schema;
109     my $rs = $schema->resultset('AqordersItem');
110     $rs->create({ ordernumber => $self->ordernumber, itemnumber => $itemnumber });
111 }
112
113 =head3 basket
114
115     my $basket = Koha::Acquisition::Orders->find( $id )->basket;
116
117 Returns the basket associated to the order.
118
119 =cut
120
121 sub basket {
122     my ( $self )  = @_;
123     my $basket_rs = $self->_result->basketno;
124     return Koha::Acquisition::Basket->_new_from_dbic( $basket_rs );
125 }
126
127 =head3 fund
128
129     my $fund = $order->fund
130
131 Returns the fund (aqbudgets) associated to the order.
132
133 =cut
134
135 sub fund {
136     my ( $self )  = @_;
137     my $fund_rs = $self->_result->budget;
138     return Koha::Acquisition::Fund->_new_from_dbic( $fund_rs );
139 }
140
141 =head3 invoice
142
143     my $invoice = $order->invoice
144
145 Returns the invoice associated to the order.
146
147 =cut
148
149 sub invoice {
150     my ( $self )  = @_;
151     my $invoice_rs = $self->_result->invoiceid;
152     return unless $invoice_rs;
153     return Koha::Acquisition::Invoice->_new_from_dbic( $invoice_rs );
154 }
155
156 =head3 subscription
157
158     my $subscription = $order->subscription
159
160 Returns the subscription associated to the order.
161
162 =cut
163
164 sub subscription {
165     my ( $self )  = @_;
166     my $subscription_rs = $self->_result->subscriptionid;
167     return unless $subscription_rs;
168     return Koha::Subscription->_new_from_dbic( $subscription_rs );
169 }
170
171 sub items {
172     my ( $self )  = @_;
173     # aqorders_items is not a join table
174     # There is no FK on items (may have been deleted)
175     my $items_rs = $self->_result->aqorders_items;
176     my @itemnumbers = $items_rs->get_column( 'itemnumber' )->all;
177     return Koha::Items->search({ itemnumber => \@itemnumbers });
178 }
179
180 sub duplicate_to {
181     my ( $self, $basket, $default_values ) = @_;
182     my $new_order;
183     $default_values //= {};
184     Koha::Database->schema->txn_do(
185         sub {
186             my $order_info = $self->unblessed;
187             undef $order_info->{ordernumber};
188             for my $field (
189                 qw(
190                 ordernumber
191                 received_on
192                 datereceived
193                 datecancellationprinted
194                 cancellationreason
195                 purchaseordernumber
196                 claims_count
197                 claimed_date
198                 parent_ordernumber
199                 )
200               )
201             {
202                 undef $order_info->{$field};
203             }
204             $order_info->{placed_on}        = dt_from_string;
205             $order_info->{entrydate}        = dt_from_string;
206             $order_info->{orderstatus}      = 'new';
207             $order_info->{quantityreceived} = 0;
208             while ( my ( $field, $value ) = each %$default_values ) {
209                 $order_info->{$field} = $value;
210             }
211
212             # FIXME $order_info->{created_by} = logged_in_user?
213             $order_info->{basketno} = $basket->basketno;
214
215             $new_order = Koha::Acquisition::Order->new($order_info)->store;
216             my $items = $self->items;
217             while ( my ($item) = $items->next ) {
218                 my $item_info = $item->unblessed;
219                 undef $item_info->{itemnumber};
220                 undef $item_info->{barcode};
221                 my $new_item = Koha::Item->new($item_info)->store;
222                 $new_order->add_item( $new_item->itemnumber );
223             }
224         }
225     );
226     return $new_order;
227 }
228
229
230 =head2 Internal methods
231
232 =head3 _type
233
234 =cut
235
236 sub _type {
237     return 'Aqorder';
238 }
239
240 1;