Bug 32030: ERM - Add vendor to license
[koha.git] / Koha / ERM / Agreement.pm
1 package Koha::ERM::Agreement;
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 use MIME::Base64 qw( decode_base64 );
21 use MIME::Types;
22
23 use Koha::Database;
24 use Koha::DateUtils qw( dt_from_string );
25 use Koha::Exceptions;
26 use Koha::Acquisition::Bookseller;
27
28 use base qw(Koha::Object);
29
30 use Koha::ERM::Agreement::Periods;
31 use Koha::ERM::Agreement::UserRoles;
32 use Koha::ERM::Agreement::Licenses;
33 use Koha::ERM::Agreement::Relationships;
34 use Koha::ERM::Agreement::Documents;
35 use Koha::ERM::EHoldings::Package::Agreements;
36
37 =head1 NAME
38
39 Koha::ERM::Agreement - Koha ErmAgreement Object class
40
41 =head1 API
42
43 =head2 Class Methods
44
45 =cut
46
47 =head3 periods
48
49 Returns the periods for this agreement
50
51 =cut
52
53 sub periods {
54     my ( $self, $periods ) = @_;
55
56     if ( $periods ) {
57         my $schema = $self->_result->result_source->schema;
58         $schema->txn_do(
59             sub {
60                 $self->periods->delete;
61
62                 for my $period (@$periods) {
63                     $self->_result->add_to_erm_agreement_periods($period);
64                 }
65             }
66         );
67     }
68
69     my $periods_rs = $self->_result->erm_agreement_periods;
70     return Koha::ERM::Agreement::Periods->_new_from_dbic($periods_rs);
71 }
72
73 =head3 user_roles
74
75 Returns the user roles for this agreement
76
77 =cut
78
79 sub user_roles {
80     my ( $self, $user_roles ) = @_;
81
82     if ( $user_roles ) {
83         my $schema = $self->_result->result_source->schema;
84         $schema->txn_do(
85             sub {
86                 $self->user_roles->delete;
87
88                 for my $user_role (@$user_roles) {
89                     $self->_result->add_to_erm_agreement_user_roles($user_role);
90                 }
91             }
92         );
93     }
94     my $user_roles_rs = $self->_result->erm_agreement_user_roles;
95     return Koha::ERM::Agreement::UserRoles->_new_from_dbic($user_roles_rs);
96 }
97
98 =head3 agreement_licenses
99
100 Returns the agreement_licenses for this agreement
101
102 =cut
103
104 sub agreement_licenses {
105     my ( $self, $agreement_licenses ) = @_;
106
107     if ( $agreement_licenses ) {
108         my $controlling = grep { $_->{status} eq 'controlling' } @$agreement_licenses;
109         if ( $controlling > 1 ) {
110             Koha::Exceptions::DuplicateObject->throw(
111                 "Only one controlling license can exist for a given agreement");
112         }
113
114         my $schema = $self->_result->result_source->schema;
115         $schema->txn_do(
116             sub {
117                 $self->agreement_licenses->delete;
118
119                 for my $agreement_license (@$agreement_licenses) {
120                     $self->_result->add_to_erm_agreement_licenses($agreement_license);
121                 }
122             }
123         );
124     }
125     my $agreement_licenses_rs = $self->_result->erm_agreement_licenses;
126     return Koha::ERM::Agreement::Licenses->_new_from_dbic($agreement_licenses_rs);
127 }
128
129 =head3 agreement_relationships
130
131 Returns the agreement relationships of this agreement
132
133 =cut
134
135 sub agreement_relationships {
136     my ( $self, $relationships ) = @_;
137
138     if ( $relationships ) {
139         my $schema = $self->_result->result_source->schema;
140         # FIXME naming - is "back link" ok?
141         my $back_links = {
142             'supersedes'       => 'is-superseded-by',
143             'is-superseded-by' => 'supersedes',
144             'provides_post-cancellation_access_for' => 'has-post-cancellation-access-in',
145             'has-post-cancellation-access-in'       => 'provides_post-cancellation_access_for',
146             'tracks_demand-driven_acquisitions_for' => 'has-demand-driven-acquisitions-in',
147             'has-demand-driven-acquisitions-in'     => 'tracks_demand-driven_acquisitions_for',
148             'has_backfile_in'  => 'has_frontfile_in',
149             'has_frontfile_in' => 'has_backfile_in',
150             'related_to'       => 'related_to',
151         };
152         $schema->txn_do(
153             sub {
154                 $self->agreement_relationships->delete;
155                 $self->agreement_back_relationships->delete;
156
157                 for my $relationship (@$relationships) {
158                     $self->_result->add_to_erm_agreement_relationships_agreements($relationship);
159                     my $back_link = {
160                         agreement_id => $relationship->{related_agreement_id},
161                         related_agreement_id => $self->agreement_id,
162                         relationship => $back_links->{$relationship->{relationship}},
163                         notes        => $relationship->{notes}, # FIXME Is it correct, do we keep the note here?
164                     };
165                     $self->_result->add_to_erm_agreement_relationships_related_agreements($back_link);
166                 }
167             }
168         );
169     }
170     my $related_agreements_rs = $self->_result->erm_agreement_relationships_agreements;
171     return Koha::ERM::Agreement::Relationships->_new_from_dbic($related_agreements_rs);
172 }
173
174 =head3 agreement_back_relationships
175
176 # FIXME Naming - how is it called?
177 Returns the reverse relationship
178
179 =cut
180
181 sub agreement_back_relationships {
182     my ( $self ) = @_;
183     my $rs = $self->_result->erm_agreement_relationships_related_agreements;
184     return Koha::ERM::Agreement::Relationships->_new_from_dbic($rs);
185 }
186
187 =head3 documents
188
189 Returns the documents for this agreement
190
191 =cut
192
193 sub documents {
194     my ( $self, $documents ) = @_;
195
196     if ($documents) {
197         my $schema = $self->_result->result_source->schema;
198         $schema->txn_do(
199             sub {
200                 my $existing_documents = $self->documents;
201
202                 # FIXME Here we are not deleting all the documents before recreating them, like we do for other related resources.
203                 # As we do not want the content of the documents to transit over the network we need to use the document_id (and allow it in the API spec)
204                 # to distinguish from each other
205                 # Delete all the documents that are not part of the PUT request
206                 my $modified_document_ids = [ map { $_->{document_id} || () } @$documents ];
207                 $self->documents->search(
208                     {
209                         @$modified_document_ids
210                         ? (
211                             document_id => {
212                                 '-not_in' => $modified_document_ids
213                             }
214                           )
215                         : ()
216                     }
217                 )->delete;
218
219                 for my $document (@$documents) {
220                     if ( $document->{document_id} ) {
221                         # The document already exists in DB
222                         $existing_documents->find( $document->{document_id} )
223                           ->set(
224                             {
225                                 file_description  => $document->{file_description},
226                                 physical_location => $document->{physical_location},
227                                 uri               => $document->{uri},
228                                 notes             => $document->{notes},
229                             }
230                         )->store;
231                     }
232                     else {
233                         # Creating a whole new document
234                         my $file_content = decode_base64( $document->{file_content} );
235                         my $mt = MIME::Types->new();
236                         $document->{file_type} = $mt->mimeTypeOf( $document->{file_name} );
237                         $document->{uploaded_on} //= dt_from_string;
238                         $document->{file_content} = $file_content;
239                         $self->_result->add_to_erm_agreement_documents( $document);
240                     }
241                 }
242             }
243         );
244     }
245     my $documents_rs = $self->_result->erm_agreement_documents;
246     return Koha::ERM::Agreement::Documents->_new_from_dbic($documents_rs);
247 }
248
249 =head3 agreement_packages
250
251 Return the local packages for this agreement (and the other ones that have an entry locally)
252
253 =cut
254
255 sub agreement_packages {
256     my ( $self ) = @_;
257     my $packages_agreements_rs = $self->_result->erm_eholdings_packages_agreements;
258     return Koha::ERM::EHoldings::Package::Agreements->_new_from_dbic($packages_agreements_rs);
259 }
260
261 =head3 vendor
262
263 Return the vendor for this agreement
264
265 =cut
266
267 sub vendor {
268     my ( $self ) = @_;
269     my $vendor_rs = $self->_result->vendor;
270     return unless $vendor_rs;
271     return Koha::Acquisition::Bookseller->_new_from_dbic($vendor_rs);
272 }
273
274 =head2 Internal methods
275
276 =head3 _type
277
278 =cut
279
280 sub _type {
281     return 'ErmAgreement';
282 }
283
284 1;