1 package OpenILS::Application::Acq::BatchManager;
2 use strict; use warnings;
5 my($class, %args) = @_;
6 my $self = bless(\%args, $class);
12 purchase_order => undef,
20 my($self, $other_args) = @_;
21 $self->conn->respond({ %{$self->{args}}, %$other_args });
23 sub respond_complete {
24 my($self, $other_args) = @_;
26 $self->conn->respond_complete({ %{$self->{args}}, %$other_args });
30 $self->{total} = $val if $val;
31 return $self->{total};
35 $self->{purchase_order} = $val if $val;
40 $self->{picklist} = $val if $val;
45 $self->{args}->{lid} += 1;
46 $self->{args}->{progress} += 1;
51 $self->{args}->{li} += 1;
52 $self->{args}->{progress} += 1;
56 my($self, $amount) = @_;
57 $self->{args}->{debits_accrued} += $amount;
58 $self->{args}->{progress} += 1;
62 my($self, $editor) = @_;
63 $self->{editor} = $editor if defined $editor;
64 return $self->{editor};
68 $self->{args}->{complete} = 1;
73 package OpenILS::Application::Acq::Order;
74 use base qw/OpenILS::Application/;
75 use strict; use warnings;
76 # ----------------------------------------------------------------------------
77 # Break up each component of the order process and pieces into managable
78 # actions that can be shared across different workflows
79 # ----------------------------------------------------------------------------
81 use OpenSRF::Utils::Logger qw(:logger);
82 use OpenILS::Utils::Fieldmapper;
83 use OpenILS::Utils::CStoreEditor q/:funcs/;
84 use OpenILS::Const qw/:const/;
85 use OpenILS::Application::AppUtils;
86 use OpenILS::Application::Cat::BibCommon;
87 use OpenILS::Application::Cat::AssetCommon;
88 my $U = 'OpenILS::Application::AppUtils';
91 # ----------------------------------------------------------------------------
93 # ----------------------------------------------------------------------------
96 my $li = Fieldmapper::acq::lineitem->new;
97 $li->creator($mgr->editor->requestor->id);
98 $li->selector($li->creator);
99 $li->editor($li->creator);
100 $li->create_time('now');
101 $li->edit_time('now');
103 $li->$_($$args{$_}) for keys %$args || ();
105 return 0 unless update_picklist($mgr, $li->picklist);
108 return $mgr->editor->create_acq_lineitem($li);
111 sub update_lineitem {
113 $li->edit_time('now');
114 $li->editor($mgr->editor->requestor->id);
115 return $mgr->editor->update_acq_lineitem($li);
118 sub delete_lineitem {
120 $li = $mgr->editor->retrieve_acq_lineitem($li) unless ref $li;
123 return 0 unless update_picklist($mgr, $li->picklist);
126 if($li->purchase_order) {
127 return 0 unless update_purchase_order($mgr, $li->purchase_order);
130 # delete the attached lineitem_details
131 my $lid_ids = $mgr->editor->search_acq_lineitem_detail({lineitem => $li->id}, {idlist=>1});
132 for my $lid_id (@$lid_ids) {
133 return 0 unless delete_lineitem_detail($mgr, undef, $lid_id);
136 return $mgr->editor->delete_acq_lineitem($li);
139 # ----------------------------------------------------------------------------
141 # ----------------------------------------------------------------------------
142 sub create_lineitem_detail {
143 my($mgr, $args) = @_;
144 my $lid = Fieldmapper::acq::lineitem_detail->new;
145 $lid->$_($$args{$_}) for keys %$args || ();
147 # create some default values
148 unless($lid->barcode) {
149 my $pfx = $U->ou_ancestor_setting_value($lid->owning_lib, 'acq.tmp_barcode_prefix') || 'ACQ';
150 $lid->barcode($pfx.$lid->id);
153 unless($lid->cn_label) {
154 my $pfx = $U->ou_ancestor_setting_value($lid->owning_lib, 'acq.tmp_callnumber_prefix') || 'ACQ';
155 $lid->cn_label($pfx.$lid->id);
158 if(!$lid->location and my $loc = $U->ou_ancestor_setting_value($lid->owning_lib, 'acq.default_copy_location')) {
159 $lid->location($loc);
162 my $li = $mgr->editor->retrieve_acq_lineitem($lid->lineitem) or return 0;
163 return 0 unless update_lineitem($mgr, $li);
164 return $mgr->editor->create_acq_lineitem_detail($lid);
167 sub delete_lineitem_detail {
169 $lid = $mgr->editor->retrieve_acq_lineitem_detail($lid) unless ref $lid;
170 return $mgr->editor->delete_acq_lineitem_detail($lid);
173 # ----------------------------------------------------------------------------
175 # ----------------------------------------------------------------------------
176 sub create_picklist {
177 my($mgr, $args) = @_;
178 my $picklist = Fieldmapper::acq::picklist->new;
179 $picklist->creator($mgr->editor->requestor->id);
180 $picklist->owner($picklist->creator);
181 $picklist->editor($picklist->creator);
182 $picklist->create_time('now');
183 $picklist->edit_time('now');
184 $picklist->org_unit($mgr->editor->requestor->ws_ou);
185 $picklist->owner($mgr->editor->requestor->id);
186 $picklist->$_($$args{$_}) for keys %$args || ();
187 $mgr->picklist($picklist);
188 return $mgr->editor->create_acq_picklist($picklist);
191 sub update_picklist {
192 my($mgr, $picklist) = @_;
193 $picklist = $mgr->editor->retrieve_acq_picklist($picklist) unless ref $picklist;
194 $picklist->edit_time('now');
195 $picklist->editor($mgr->editor->requestor->id);
196 return $mgr->editor->update_acq_picklist($picklist);
199 sub delete_picklist {
200 my($mgr, $picklist) = @_;
201 $picklist = $mgr->editor->retrieve_acq_picklist($picklist) unless ref $picklist;
203 # delete all 'new' lineitems
204 my $lis = $mgr->editor->search_acq_lineitem({picklist => $picklist->id, state => 'new'});
206 return 0 unless delete_lineitem($mgr, $li);
209 # detach all non-'new' lineitems
210 $lis = $mgr->editor->search_acq_lineitem({picklist => $picklist->id, state => {'!=' => 'new'}});
213 return 0 unless update_lineitem($li);
216 # remove any picklist-specific object perms
217 my $ops = $mgr->editor->search_permission_usr_object_perm_map({object_type => 'acqpl', object_id => "".$picklist->id});
219 return 0 unless $mgr->editor->delete_usr_object_perm_map($op);
222 return $mgr->editor->delete_acq_picklist($picklist);
225 # ----------------------------------------------------------------------------
227 # ----------------------------------------------------------------------------
228 sub update_purchase_order {
230 $po = $mgr->editor->retrieve_acq_purchase_order($po) unless ref $po;
231 $po->editor($mgr->editor->requestor->id);
232 $po->edit_date('now');
233 return $mgr->editor->update_acq_purchase_order($po);
236 sub create_purchase_order {
237 my($mgr, $args) = @_;
238 my $po = Fieldmapper::acq::purchase_order->new;
239 $po->creator($mgr->editor->requestor->id);
240 $po->editor($mgr->editor->requestor->id);
241 $po->owner($mgr->editor->requestor->id);
242 $po->edit_time('now');
243 $po->create_time('now');
244 $po->ordering_agency($mgr->editor->requestor->ws_ou);
245 $po->$_($$args{$_}) for keys %$args || ();
246 return $mgr->editor->create_acq_purchase_order($po);
252 # ----------------------------------------------------------------------------
253 # Workflow: Build a selection list from a Z39.50 search
254 # ----------------------------------------------------------------------------
256 __PACKAGE__->register_method(
258 api_name => 'open-ils.acq.picklist.search.z3950',
261 desc => 'Performs a z3950 federated search and creates a picklist and associated lineitems',
263 {desc => 'Authentication token', type => 'string'},
264 {desc => 'Search definition', type => 'object'},
265 {desc => 'Picklist name, optional', type => 'string'},
271 my($self, $conn, $auth, $search, $name, $options) = @_;
272 my $e = new_editor(authtoken=>$auth);
273 return $e->event unless $e->checkauth;
274 return $e->event unless $e->allowed('CREATE_PICKLIST');
276 $search->{limit} ||= 10;
279 my $ses = OpenSRF::AppSession->create('open-ils.search');
280 my $req = $ses->request('open-ils.search.z3950.search_class', $auth, $search);
285 while(my $resp = $req->recv(timeout=>60)) {
288 my $e = new_editor(requestor=>$e->requestor, xact=>1);
289 $mgr = OpenILS::Application::Acq::BatchManager->new({editor => $e, conn => $conn});
290 $picklist = zsearch_build_pl($mgr, $name);
294 my $result = $resp->content;
295 my $count = $result->{count};
296 $mgr->total( (($count < $search->{limit}) ? $count : $search->{limit})+1 );
298 for my $rec (@{$result->{records}}) {
300 my $li = create_lineitem($mgr, {
301 picklist => $picklist->{id},
302 source_label => $result->{service},
303 marc => $rec->{marcxml},
304 eg_bib_id => $rec->{bibid}
307 if($$options{respond_li}) {
308 $li->attributes($mgr->editor->search_acq_lineitem_attr({lineitem => $li->id}))
309 if $$options{flesh_attrs};
310 $li->clear_marc if $$options{clear_marc};
311 $mgr->respond({lineitem => $li});
318 $mgr->editor->commit;
319 $mgr->respond_complete;
323 sub zsearch_build_pl {
324 my($mgr, $name) = @_;
327 my $picklist = $mgr->editor->search_acq_picklist({owner=>$mgr->editor->requestor->id, name=>$name})->[0];
328 if($name eq '' and $picklist) {
329 return 0 unless delete_picklist($mgr, $picklist);
334 update_picklist($mgr, $picklist) or return 0;
338 return create_picklist($mgr, {name => $name});