evergreen/common/trigger/reactor/
circ.rs1use crate as eg;
3use eg::common::auth;
4use eg::common::{trigger, trigger::Event, trigger::Processor};
5use eg::EgEvent;
6use eg::EgResult;
7use eg::EgValue;
8
9impl Processor<'_> {
10 pub fn autorenew(&mut self, events: &mut [&mut Event]) -> EgResult<()> {
11 let usr = &events[0].target()["usr"];
12 let patron_id = usr.as_int().unwrap_or(usr.id()?);
14
15 let home_ou = if usr.is_object() {
16 usr["home_ou"].as_int().unwrap_or(usr["home_ou"].id()?)
17 } else {
18 let patron = self
20 .editor
21 .retrieve("au", patron_id)?
22 .ok_or_else(|| self.editor.die_event())?;
23
24 patron["home_ou"].int()?
25 };
26
27 let mut auth_args = auth::InternalLoginArgs::new(patron_id, auth::LoginType::Opac);
28 auth_args.set_org_unit(home_ou);
29
30 let auth_ses = auth::Session::internal_session_api(self.editor.client_mut(), &auth_args)?
32 .ok_or_else(|| "Cannot create internal auth session".to_string())?;
33
34 for event in events {
35 self.renew_one_circ(auth_ses.token(), patron_id, event)?;
36 }
37
38 Ok(())
39 }
40
41 fn renew_one_circ(&mut self, authtoken: &str, patron_id: i64, event: &Event) -> EgResult<()> {
42 let tc = &event.target()["target_copy"];
43 let copy_id = tc.as_int().unwrap_or(tc.id()?);
44
45 log::info!(
46 "Auto-Renewing Circ id={} copy={copy_id}",
47 event.target()["id"]
48 );
49
50 let params = vec![
51 EgValue::from(authtoken),
52 eg::hash! {
53 "patron_id": patron_id,
54 "copy_id": copy_id,
55 "auto_renewal": true
56 },
57 ];
58
59 log::info!("{self} renewing with params: {params:?}");
60
61 let mut response = self
62 .editor
63 .client_mut()
64 .send_recv_one("open-ils.circ", "open-ils.circ.renew", params)?
65 .ok_or_else(|| "Renewal returned no response".to_string())?;
66
67 let evt = if response.is_array() {
70 response.array_remove(0)
71 } else {
72 response
73 };
74
75 let eg_evt = EgEvent::parse(&evt)
76 .ok_or_else(|| format!("Renew returned unexpected data: {}", evt.dump()))?;
77
78 log::info!("{self} autorenewal returned {eg_evt}");
79
80 let source_circ = event.target();
81 let new_circ = &eg_evt.payload()["circ"];
82
83 let mut new_due_date = "";
84 let mut old_due_date = "";
85 let mut fail_reason = "";
86 let mut total_remaining;
87 let mut auto_remaining;
88
89 let success = eg_evt.is_success();
90 if success && new_circ.is_object() {
91 new_due_date = new_circ["due_date"].as_str().unwrap(); total_remaining = new_circ["renewal_remaining"].int()?;
93
94 auto_remaining = new_circ["auto_renewal_remaining"]
96 .as_int()
97 .unwrap_or_default();
98 } else {
99 old_due_date = source_circ["due_date"].as_str().unwrap(); total_remaining = source_circ["renewal_remaining"].int()?;
101 fail_reason = eg_evt.desc().unwrap_or("");
102
103 auto_remaining = source_circ["auto_renewal_remaining"]
105 .as_int()
106 .unwrap_or_default();
107 }
108
109 if total_remaining < 0 {
110 total_remaining = 0;
111 }
112 if auto_remaining < 0 {
113 auto_remaining = 0;
114 }
115 if auto_remaining < total_remaining {
116 auto_remaining = total_remaining;
117 }
118
119 let user_data = eg::hash! {
120 "copy": copy_id,
121 "is_renewed": success,
122 "reason": fail_reason,
123 "new_due_date": new_due_date,
124 "old_due_date": old_due_date,
125 "textcode": eg_evt.textcode(),
126 "total_renewal_remaining": total_remaining,
127 "auto_renewal_remaining": auto_remaining,
128 };
129
130 let target = &event.target()["circ_lib"];
131 let circ_lib = target.as_int().unwrap_or(target.id()?);
132
133 trigger::create_events_for_object(
137 self.editor,
138 "autorenewal",
139 event.target(),
140 circ_lib,
141 None,
142 Some(&user_data),
143 false,
144 )
145 }
146}