1 package OpenILS::Application::Acq::Lineitem;
2 use base qw/OpenILS::Application/;
3 use strict; use warnings;
6 use OpenSRF::Utils::Logger qw(:logger);
7 use OpenILS::Utils::Fieldmapper;
8 use OpenILS::Utils::CStoreEditor q/:funcs/;
9 use OpenILS::Const qw/:const/;
10 use OpenSRF::Utils::SettingsClient;
11 use OpenILS::Application::AppUtils;
12 use OpenILS::Application::Acq::Financials;
13 use OpenILS::Application::Cat::BibCommon;
14 use OpenILS::Application::Cat::AssetCommon;
15 my $U = 'OpenILS::Application::AppUtils';
18 __PACKAGE__->register_method(
19 method => 'create_lineitem',
20 api_name => 'open-ils.acq.lineitem.create',
22 desc => 'Creates a lineitem',
24 {desc => 'Authentication token', type => 'string'},
25 {desc => 'The lineitem object to create', type => 'object'},
27 return => {desc => 'ID of newly created lineitem on success, Event on error'}
32 my($self, $conn, $auth, $li) = @_;
33 my $e = new_editor(xact=>1, authtoken=>$auth);
34 return $e->die_event unless $e->checkauth;
38 my $picklist = $e->retrieve_acq_picklist($li->picklist)
39 or return $e->die_event;
41 if($picklist->owner != $e->requestor->id) {
42 return $e->die_event unless
43 $e->allowed('CREATE_PICKLIST', $picklist->org_unit, $picklist);
46 # indicate the picklist was updated
47 $picklist->edit_time('now');
48 $picklist->editor($e->requestor->id);
49 $e->update_acq_picklist($picklist) or return $e->die_event;
52 if($li->purchase_order) {
53 my $po = $e->retrieve_acq_purchase_order($li->purchase_order)
54 or return $e->die_event;
55 return $e->die_event unless
56 $e->allowed('MANAGE_PROVIDER', $po->ordering_agency, $po);
58 $li->provider($po->provider) unless defined $li->provider;
61 $li->selector($e->requestor->id);
62 $e->create_acq_lineitem($li) or return $e->die_event;
69 __PACKAGE__->register_method(
70 method => 'retrieve_lineitem',
71 api_name => 'open-ils.acq.lineitem.retrieve',
74 desc => 'Retrieves a lineitem',
76 {desc => 'Authentication token', type => 'string'},
77 {desc => 'lineitem ID to retrieve', type => 'number'},
78 {options => q/Hash of options, including:
79 flesh_attrs : for attributes,
80 flesh_notes : for notes,
81 flesh_cancel_reason : for cancel reason,
82 flesh_li_details : for order details objects,
83 clear_marc : to clear marcxml from lineitem/, type => 'hash'},
85 return => {desc => 'lineitem object on success, Event on error'}
90 sub retrieve_lineitem {
91 my($self, $conn, $auth, $li_id, $options) = @_;
92 my $e = new_editor(authtoken=>$auth);
93 return $e->die_event unless $e->checkauth;
94 return retrieve_lineitem_impl($e, $li_id, $options);
97 sub retrieve_lineitem_impl {
98 my ($e, $li_id, $options, $no_auth) = @_; # no_auth needed for EDI scripts
104 jub => ['purchase_order', 'picklist'], # needed for permission check
110 my $fields = $flesh->{flesh_fields};
112 push(@{$fields->{jub} }, 'attributes') if $$options{flesh_attrs};
113 push(@{$fields->{jub} },'lineitem_notes') if $$options{flesh_notes};
114 push(@{$fields->{acqlin}}, 'alert_text') if $$options{flesh_notes};
115 push(@{$fields->{jub} }, 'order_summary') if $$options{flesh_order_summary};
116 push(@{$fields->{acqlin}}, 'cancel_reason') if $$options{flesh_cancel_reason};
118 if($$options{flesh_li_details}) {
119 push(@{$fields->{jub} }, 'lineitem_details');
120 push(@{$fields->{acqlid}}, 'fund' ) if $$options{flesh_fund};
121 push(@{$fields->{acqlid}}, 'fund_debit' ) if $$options{flesh_fund_debit};
122 push(@{$fields->{acqlid}}, 'cancel_reason') if $$options{flesh_cancel_reason};
125 if($$options{clear_marc}) { # avoid fetching marc blob
126 my @fields = grep { $_ ne 'marc' } Fieldmapper::acq::lineitem->new->real_fields;
127 $flesh->{select} = {jub => [@fields]};
130 my $li = $e->retrieve_acq_lineitem([$li_id, $flesh]) or return $e->event;
132 # collect the # of lids
133 if($$options{flesh_li_details}) {
134 $li->item_count(scalar(@{$li->lineitem_details}));
136 my $details = $e->search_acq_lineitem_detail({lineitem => $li_id}, {idlist=>1});
137 $li->item_count(scalar(@$details));
140 # attach claims to LIDs
141 if($$options{flesh_li_details}) {
142 foreach (@{$li->lineitem_details}) {
144 $e->search_acq_claim([
145 {"lineitem_detail", $_->id}, {
146 "flesh" => 1, "flesh_fields" => {"acqcl" => ["type"]}
153 return $e->event unless ((
154 $li->purchase_order and
155 ($no_auth or $e->allowed(['VIEW_PURCHASE_ORDER', 'CREATE_PURCHASE_ORDER'],
156 $li->purchase_order->ordering_agency, $li->purchase_order))
158 $li->picklist and !$li->purchase_order and # user doesn't have view_po perms
159 ($no_auth or $e->allowed(['VIEW_PICKLIST', 'CREATE_PICKLIST'],
160 $li->picklist->org_unit, $li->picklist))
163 unless ($$options{flesh_po}) {
165 $li->purchase_order ? $li->purchase_order->id : undef
168 unless ($$options{flesh_pl}) {
169 $li->picklist($li->picklist ? $li->picklist->id : undef);
176 __PACKAGE__->register_method(
177 method => 'delete_lineitem',
178 api_name => 'open-ils.acq.lineitem.delete',
180 desc => 'Deletes a lineitem',
182 {desc => 'Authentication token', type => 'string'},
183 {desc => 'lineitem ID to delete', type => 'number'},
185 return => {desc => '1 on success, Event on error'}
189 __PACKAGE__->register_method(
190 method => 'delete_lineitem',
191 api_name => 'open-ils.acq.purchase_order.lineitem.delete',
193 desc => 'Deletes a lineitem from a purchase order',
195 {desc => 'Authentication token', type => 'string'},
196 {desc => 'lineitem ID to delete', type => 'number'},
198 return => {desc => '1 on success, Event on error'}
202 __PACKAGE__->register_method(
203 method => 'delete_lineitem',
204 api_name => 'open-ils.acq.picklist.lineitem.delete',
206 desc => 'Deletes a lineitem from a picklist',
208 {desc => 'Authentication token', type => 'string'},
209 {desc => 'lineitem ID to delete', type => 'number'},
211 return => {desc => '1 on success, Event on error'}
215 sub delete_lineitem {
216 my($self, $conn, $auth, $li_id) = @_;
217 my $e = new_editor(xact=>1, authtoken=>$auth);
218 return $e->die_event unless $e->checkauth;
220 my $li = $e->retrieve_acq_lineitem($li_id)
221 or return $e->die_event;
226 my $picklist = $e->retrieve_acq_picklist($li->picklist)
227 or return $e->die_event;
228 return OpenILS::Event->new('BAD_PARAMS')
229 if $picklist->owner != $e->requestor->id;
234 # once a LI is attached to a PO, deleting it
235 # from a picklist means *detaching* it from the picklist
236 if ($self->api_name =~ /picklist/ && $li->purchase_order) {
238 my $evt = update_lineitem_impl($e, $li);
244 # delete the attached lineitem_details
245 my $lid_ids = $e->search_acq_lineitem_detail(
246 {lineitem => $li_id}, {idlist=>1});
248 for my $lid_id (@$lid_ids) {
249 $e->delete_acq_lineitem_detail(
250 $e->retrieve_acq_lineitem_detail($lid_id))
251 or return $e->die_event;
254 $e->delete_acq_lineitem($li) or return $e->die_event;
260 __PACKAGE__->register_method(
261 method => 'update_lineitem',
262 api_name => 'open-ils.acq.lineitem.update',
264 desc => 'Update one or many lineitems',
266 {desc => 'Authentication token', type => 'string'},
267 {desc => 'lineitem object update', type => 'object'}
269 return => {desc => '1 on success, Event on error'}
273 sub update_lineitem {
274 my($self, $conn, $auth, $li) = @_;
275 my $e = new_editor(xact=>1, authtoken=>$auth);
276 return $e->die_event unless $e->checkauth;
278 $li = [$li] unless ref $li eq "ARRAY";
280 my $evt = update_lineitem_impl($e, $_);
288 sub update_lineitem_impl {
291 my $orig_li = $e->retrieve_acq_lineitem([
293 { flesh => 1, # grab the lineitem with picklist attached
294 flesh_fields => {jub => ['picklist', 'purchase_order']}
296 ]) or return $e->die_event;
298 # the marc may have been cleared on retrieval...
299 $li->marc($orig_li->marc) unless $li->marc;
301 $li->editor($e->requestor->id);
302 $li->edit_time('now');
303 $e->update_acq_lineitem($li) or return $e->die_event;
307 __PACKAGE__->register_method(
308 method => 'lineitem_search',
309 api_name => 'open-ils.acq.lineitem.search',
312 desc => 'Searches lineitems',
314 {desc => 'Authentication token', type => 'string'},
315 {desc => 'Search definition', type => 'object'},
316 {desc => 'Options hash. idlist=true', type => 'object'},
317 {desc => 'List of lineitems', type => 'object/number'},
322 sub lineitem_search {
323 my($self, $conn, $auth, $search, $options) = @_;
324 my $e = new_editor(authtoken=>$auth);
325 return $e->event unless $e->checkauth;
326 return $e->event unless $e->allowed('CREATE_PICKLIST');
327 # XXX needs permissions consideration
328 my $lis = $e->search_acq_lineitem($search, {idlist=>1});
329 for my $li_id (@$lis) {
330 if($$options{idlist}) {
331 $conn->respond($li_id);
333 my $res = retrieve_lineitem($self, $conn, $auth, $li_id, $options);
334 $conn->respond($res) unless $U->event_code($res);
340 __PACKAGE__->register_method (
341 method => 'lineitems_related_by_bib',
342 api_name => 'open-ils.acq.lineitems_for_bib.by_bib_id',
345 Retrieves lineitems attached to same bib record, subject to the PO ordering agency. This variant takes the bib id.
346 @param authtoken Login session key
347 @param bib_id Id for the pertinent bib record.
348 @param options Object for tweaking the selection criteria and fleshing options.
352 __PACKAGE__->register_method (
353 method => 'lineitems_related_by_bib',
354 api_name => 'open-ils.acq.lineitems_for_bib.by_lineitem_id',
357 Retrieves lineitems attached to same bib record, subject to the PO ordering agency. This variant takes the id for any of the pertinent lineitems.
358 @param authtoken Login session key
359 @param bib_id Id for a pertinent lineitem.
360 @param options Object for tweaking the selection criteria and fleshing options.
364 __PACKAGE__->register_method (
365 method => 'lineitems_related_by_bib',
366 api_name => 'open-ils.acq.lineitems_for_bib.by_lineitem_id.count',
368 signature => q/See open-ils.acq.lineitems_for_bib.by_lineitem_id. This version returns numbers of lineitems only (XXX may count lineitems we don't actually have permission to retrieve)/
371 sub lineitems_related_by_bib {
372 my($self, $conn, $auth, $test_value, $options) = @_;
373 my $e = new_editor(authtoken => $auth);
374 return $e->event unless $e->checkauth;
376 my $perm_orgs = $U->user_has_work_perm_at($e, 'VIEW_PURCHASE_ORDER', {descendants =>1}, $e->requestor->id);
379 "select"=>{"jub"=>["id"]},
380 "from"=>{"jub" => {"acqpo" => {type => 'left'}, "acqpl" => {type => 'left'}}},
383 { "+acqpo"=>{ "ordering_agency" => $perm_orgs } },
384 { '+acqpl' => { org_unit => $perm_orgs } }
387 "order_by"=>[{"class"=>"jub", "field"=>"create_time", "direction"=>"desc"}]
390 # Be sure we just return the original LI if no related bibs
391 if ($self->api_name =~ /by_lineitem_id/) {
392 my $orig = retrieve_lineitem($self, $conn, $auth, $test_value) or
393 return $e->die_event;
394 if ($test_value = $orig->eg_bib_id) {
395 $query->{"where"}->{"eg_bib_id"} = $test_value;
397 $query->{"where"}->{"id"} = $orig->id;
399 } elsif ($test_value) {
400 $query->{"where"}->{"eg_bib_id"} = $test_value;
403 return new OpenILS::Event("BAD_PARAMS", "Null bib id");
406 if ($options && defined $options->{lineitem_state}) {
407 $query->{'where'}{'jub'}{'state'} = $options->{lineitem_state};
410 if ($options && defined $options->{po_state}) {
411 $query->{'where'}{'+acqpo'}{'state'} = $options->{po_state};
414 if ($options && defined $options->{order_by}) {
415 $query->{'order_by'} = $options->{order_by};
418 my $results = $e->json_query($query);
419 if ($self->api_name =~ /count$/) {
420 return scalar(@$results);
422 for my $result (@$results) {
423 # retrieve_lineitem takes care of POs and PLs and also handles
424 # options like flesh_notes and permissions checking.
426 retrieve_lineitem($self, $conn, $auth, $result->{"id"}, $options)
435 __PACKAGE__->register_method(
436 method => "lineitem_search_by_attributes",
437 api_name => "open-ils.acq.lineitem.search.by_attributes",
440 desc => "Performs a search against lineitem_attrs",
442 {desc => "Authentication token", type => "string"},
445 attr_value_pairs : list of pairs of (attr definition ID, attr value) where value can be scalar (fuzzy match) or array (exact match)
446 li_states : list of lineitem states
447 po_agencies : list of purchase order ordering agencies (org) ids
449 At least one of these search terms is required.
454 idlist : if set, only return lineitem IDs
455 clear_marc : if set, strip the MARC xml from the lineitem before delivery
456 flesh_attrs : flesh lineitem attributes;
463 __PACKAGE__->register_method(
464 method => "lineitem_search_by_attributes",
465 api_name => "open-ils.acq.lineitem.search.by_attributes.ident",
468 desc => "Performs a search against lineitem_attrs where ident is true. ".
469 "See open-ils.acq.lineitem.search.by_attributes for params."
473 sub lineitem_search_by_attributes {
474 my ($self, $conn, $auth, $search, $options) = @_;
476 my $e = new_editor(authtoken => $auth, xact => 1);
477 return $e->die_event unless $e->checkauth;
478 # XXX needs permissions consideration
480 return [] unless $search;
481 my $attr_value_pairs = $search->{attr_value_pairs};
482 my $li_states = $search->{li_states};
483 my $po_agencies = $search->{po_agencies}; # XXX if none, base it on perms
486 "select" => {"acqlia" =>
487 [{"column" => "lineitem", "transform" => "distinct"}]
491 "acqliad" => {"field" => "id", "fkey" => "definition"},
494 "fkey" => "lineitem",
499 "fkey" => "purchase_order"
508 $where->{"+acqliad"} = {"ident" => "t"}
509 if $self->api_name =~ /\.ident/;
511 my $searched_for_something = 0;
513 if (ref $attr_value_pairs eq "ARRAY") {
514 $where->{"-or"} = [];
515 foreach (@$attr_value_pairs) {
517 my ($def, $value) = @$_;
518 push @{$where->{"-or"}}, {
520 "attr_value" => (ref $value) ?
521 $value : {"ilike" => "%" . $value . "%"},
526 $searched_for_something = 1;
529 if ($li_states and @$li_states) {
530 $where->{"+jub"} = {"state" => $li_states};
531 $searched_for_something = 1;
534 if ($po_agencies and @$po_agencies) {
535 $where->{"+acqpo"} = {"ordering_agency" => $po_agencies};
536 $searched_for_something = 1;
539 if (not $searched_for_something) {
541 return new OpenILS::Event(
542 "BAD_PARAMS", note => "You have provided no search terms."
546 $query->{"where"} = $where;
547 my $lis = $e->json_query($query);
549 for my $li_id_obj (@$lis) {
550 my $li_id = $li_id_obj->{"lineitem"};
551 if($options->{"idlist"}) {
552 $conn->respond($li_id);
555 retrieve_lineitem($self, $conn, $auth, $li_id, $options)
563 __PACKAGE__->register_method(
564 method => 'lineitem_search_ident',
565 api_name => 'open-ils.acq.lineitem.search.ident',
568 desc => 'Performs a search against lineitem_attrs where ident is true',
570 {desc => 'Authentication token', type => 'string'},
571 { desc => q/Search definition. Options are:
572 attr_values : list of attribute values (required)
573 li_states : list of lineitem states
574 po_agencies : list of purchase order ordering agencies (org) ids
579 Options hash. Options are:
580 idlist : if set, only return lineitem IDs
581 clear_marc : if set, strip the MARC xml from the lineitem before delivery
582 flesh_attrs : flesh lineitem attributes;
590 my $LI_ATTR_SEARCH = {
591 select => { acqlia => ['lineitem'] },
604 fkey => 'purchase_order'
612 sub lineitem_search_ident {
613 my($self, $conn, $auth, $search, $options) = @_;
614 my $e = new_editor(authtoken=>$auth, xact=>1);
615 return $e->event unless $e->checkauth;
616 # XXX needs permissions consideration
618 return [] unless $search;
619 my $attr_values = $search->{attr_values};
620 my $li_states = $search->{li_states};
621 my $po_agencies = $search->{po_agencies}; # XXX if none, base it on perms
626 '+acqliad' => {ident => 't'},
630 push(@{$where_clause->{'-or'}}, {attr_value => {ilike => "%$_%"}}) for @$attr_values;
632 $where_clause->{'+jub'} = {state => {in => $li_states}}
633 if $li_states and @$li_states;
635 $where_clause->{'+acqpo'} = {ordering_agency => $po_agencies}
636 if $po_agencies and @$po_agencies;
638 $LI_ATTR_SEARCH->{where} = $where_clause;
640 my $lis = $e->json_query($LI_ATTR_SEARCH);
642 for my $li_id_obj (@$lis) {
643 my $li_id = $li_id_obj->{lineitem};
644 if($$options{idlist}) {
645 $conn->respond($li_id);
648 if($$options{flesh_attrs}) {
649 $li = $e->retrieve_acq_lineitem([
650 $li_id, {flesh => 1, flesh_fields => {jub => ['attributes']}}])
652 $li = $e->retrieve_acq_lineitem($li_id);
654 $li->clear_marc if $$options{clear_marc};
662 __PACKAGE__->register_method(
663 method => 'retrieve_lineitem_detail',
664 api_name => 'open-ils.acq.lineitem_detail.retrieve',
667 desc => q/Updates a lineitem detail/,
669 { desc => 'Authentication token', type => 'string' },
670 { desc => 'id of lineitem_detail to retrieve', type => 'number' },
672 return => { desc => 'object on success, Event on failure' }
675 sub retrieve_lineitem_detail {
676 my($self, $conn, $auth, $li_detail_id) = @_;
677 my $e = new_editor(authtoken=>$auth);
678 return $e->event unless $e->checkauth;
680 my $li_detail = $e->retrieve_acq_lineitem_detail($li_detail_id)
683 if($li_detail->fund) {
684 my $fund = $e->retrieve_acq_fund($li_detail->fund) or return $e->event;
685 return $e->event unless
686 $e->allowed('MANAGE_FUND', $fund->org, $fund);
689 # XXX check lineitem perms
694 __PACKAGE__->register_method(
695 method => 'approve_lineitem',
696 api_name => 'open-ils.acq.lineitem.approve',
698 desc => 'Mark a lineitem as approved',
700 { desc => 'Authentication token', type => 'string' },
701 { desc => 'lineitem ID', type => 'number' }
703 return => { desc => '1 on success, Event on error' }
706 sub approve_lineitem {
707 my($self, $conn, $auth, $li_id) = @_;
708 my $e = new_editor(xact=>1, authtoken=>$auth);
709 return $e->die_event unless $e->checkauth;
711 # XXX perm checks for each lineitem detail
713 my $li = $e->retrieve_acq_lineitem($li_id)
714 or return $e->die_event;
716 return OpenILS::Event->new('ACQ_LINEITEM_APPROVED', payload => $li_id)
717 if $li->state eq 'approved';
719 my $details = $e->search_acq_lineitem_detail({lineitem => $li_id});
720 return OpenILS::Event->new('ACQ_LINEITEM_NO_COPIES', payload => $li_id)
721 unless scalar(@$details) > 0;
723 for my $detail (@$details) {
724 return OpenILS::Event->new('ACQ_LINEITEM_DETAIL_NO_FUND', payload => $detail->id)
725 unless $detail->fund;
727 return OpenILS::Event->new('ACQ_LINEITEM_DETAIL_NO_ORG', payload => $detail->id)
728 unless $detail->owning_lib;
731 $li->state('approved');
732 $li->edit_time('now');
733 $e->update_acq_lineitem($li) or return $e->die_event;
741 __PACKAGE__->register_method(
742 method => 'set_lineitem_attr',
743 api_name => 'open-ils.acq.lineitem_usr_attr.set',
745 desc => 'Sets a lineitem_usr_attr value',
747 { desc => 'Authentication token', type => 'string' },
748 { desc => 'Lineitem ID', type => 'number' },
749 { desc => 'Attr name', type => 'string' },
750 { desc => 'Attr value', type => 'string' }
752 return => { desc => '1 on success, Event on error' }
756 __PACKAGE__->register_method(
757 method => 'set_lineitem_attr',
758 api_name => 'open-ils.acq.lineitem_local_attr.set',
760 desc => 'Sets a lineitem_local_attr value',
762 { desc => 'Authentication token', type => 'string' },
763 { desc => 'Lineitem ID', type => 'number' },
764 { desc => 'Attr name', type => 'string' },
765 { desc => 'Attr value', type => 'string' }
767 return => { desc => 'ID of the attr object on success, Event on error' }
772 sub set_lineitem_attr {
773 my($self, $conn, $auth, $li_id, $attr_name, $attr_value) = @_;
774 my $e = new_editor(xact=>1, authtoken=>$auth);
775 return $e->die_event unless $e->checkauth;
779 my $attr_type = $self->api_name =~ /local_attr/ ?
780 'lineitem_local_attr_definition' : 'lineitem_usr_attr_definition';
782 my $attr = $e->search_acq_lineitem_attr({
784 attr_type => $attr_type,
785 attr_name => $attr_name})->[0];
787 my $find = "search_acq_$attr_type";
790 $attr->attr_value($attr_value);
791 $e->update_acq_lineitem_attr($attr) or return $e->die_event;
793 $attr = Fieldmapper::acq::lineitem_attr->new;
794 $attr->lineitem($li_id);
795 $attr->attr_type($attr_type);
796 $attr->attr_name($attr_name);
797 $attr->attr_value($attr_value);
799 my $attr_def_id = $e->$find({code => $attr_name}, {idlist=>1})->[0]
800 or return $e->die_event;
801 $attr->definition($attr_def_id);
802 $e->create_acq_lineitem_attr($attr) or return $e->die_event;
809 __PACKAGE__->register_method(
810 method => 'get_lineitem_attr_defs',
811 api_name => 'open-ils.acq.lineitem_attr_definition.retrieve.all',
814 desc => 'Retrieve lineitem attr definitions',
815 params => [ { desc => 'Authentication token', type => 'string' }, ],
816 return => { desc => 'List of attr definitions' }
820 sub get_lineitem_attr_defs {
821 my($self, $conn, $auth) = @_;
822 my $e = new_editor(authtoken=>$auth);
823 return $e->event unless $e->checkauth;
825 for my $type (qw/generated marc local usr provider/) {
826 my $call = "retrieve_all_acq_lineitem_${type}_attr_definition";
827 $results{$type} = $e->$call;
833 __PACKAGE__->register_method(
834 method => 'lineitem_note_CUD_batch',
835 api_name => 'open-ils.acq.lineitem_note.cud.batch',
838 desc => q/Manage lineitem notes/,
840 { desc => 'Authentication token', type => 'string' },
841 { desc => 'List of lineitem_notes to manage', type => 'array' },
844 { desc => 'Streaming response of current position in the array' }
848 sub lineitem_note_CUD_batch {
849 my($self, $conn, $auth, $li_notes) = @_;
851 my $e = new_editor(xact=>1, authtoken=>$auth);
852 return $e->die_event unless $e->checkauth;
855 my $total = @$li_notes;
858 for my $note (@$li_notes) {
860 $note->editor($e->requestor->id);
861 $note->edit_time('now');
864 $note->creator($e->requestor->id);
865 $note = $e->create_acq_lineitem_note($note) or return $e->die_event;
867 } elsif($note->isdeleted) {
868 $e->delete_acq_lineitem_note($note) or return $e->die_event;
870 } elsif($note->ischanged) {
871 $e->update_acq_lineitem_note($note) or return $e->die_event;
874 if(!$note->isdeleted) {
875 $note = $e->retrieve_acq_lineitem_note([
877 "flesh" => 1, "flesh_fields" => {"acqlin" => ["alert_text"]}
882 $conn->respond({maximum => $total, progress => ++$count, note => $note});
886 return {complete => 1};
889 __PACKAGE__->register_method(
890 method => 'ranged_line_item_alert_text',
891 api_name => 'open-ils.acq.line_item_alert_text.ranged.retrieve.all'); # TODO: signature
893 sub ranged_line_item_alert_text {
894 my($self, $conn, $auth, $org_id, $depth) = @_;
895 my $e = new_editor(authtoken => $auth);
896 return $e->event unless $e->checkauth;
897 return $e->event unless $e->allowed('ADMIN_ACQ_LINEITEM_ALERT_TEXT', $org_id);
898 return $e->search_acq_lineitem_alert_text(
899 {owning_lib => $U->get_org_full_path($org_id, $depth)});
903 __PACKAGE__->register_method(
904 method => "retrieve_lineitem_by_copy_id",
905 api_name => "open-ils.acq.lineitem.retrieve.by_copy_id",
908 desc => q/Manage lineitem notes/,
910 {desc => "Authentication token", type => "string"},
911 {desc => "Evergreen internal copy ID", type => "number"},
912 {desc => "Hash of options (see open-ils.acq.lineitem.retrieve",
916 desc => "Lineitem associated with given copy",
917 type => "object", class => "jub"
922 sub retrieve_lineitem_by_copy_id {
923 my ($self, $conn, $auth, $object_id, $options) = @_;
925 my $e = new_editor("authtoken" => $auth);
926 return $e->die_event unless $e->checkauth;
928 my $result = $e->json_query({
929 "select" => {"acqlid" => ["lineitem"]},
931 "where" => {"eg_copy_id" => $object_id}
934 return new OpenILS::Event("ACQ_LINEITEM_NOT_FOUND");
937 my $li = retrieve_lineitem_impl($e, $result->{"lineitem"}, $options) or
938 return $e->die_event;